diff --git a/src/webViews/favoriteQueries.webiew.ts b/src/webViews/favoriteQueries.webiew.ts
index 3a0c85b3..6e97a20e 100644
--- a/src/webViews/favoriteQueries.webiew.ts
+++ b/src/webViews/favoriteQueries.webiew.ts
@@ -2,7 +2,7 @@ import { getFavoriteQueries } from "../util/favoriteQuery";
export const showFavoriteQueries = (): string => {
let favQueries = getFavoriteQueries();
- return `
+ return /*HTML*/`
@@ -22,6 +22,7 @@ export const showFavoriteQueries = (): string => {
}
.favorite-queries-table {
+ min-height: 200px;
display: flex;
justify-content: space-between;
width: 100%;
diff --git a/src/webViews/namedParameters.webview.ts b/src/webViews/namedParameters.webview.ts
new file mode 100644
index 00000000..893ab690
--- /dev/null
+++ b/src/webViews/namedParameters.webview.ts
@@ -0,0 +1,265 @@
+import {
+ getUsersNamedParameters,
+ getProjectsNamedParameters,
+} from "../util/namedParameters";
+
+export const showNamedParameters = (): string => {
+ let namedParams = getUsersNamedParameters();
+ let projectNamedParams = getProjectsNamedParameters();
+ return /*HTML*/ `
+
+
+
+
+
+
Named Parameters
+
+
+
+
+
+
+
User's Named Parameters
+
Project's Named Parameters
+
+
+
+
+
+
+
+ ${
+ namedParams !== undefined &&
+ namedParams
+ .map((kv, index) => {
+ return `
${kv.key}
`;
+ })
+ .join("")
+ }
+
+
+
+
+
+
+ Note: User's parameters are present in
VSCode User Settings. You can edit from the settings file.
+
+
+
+
+
+
+
+
+
+
+ ${
+ projectNamedParams !== undefined &&
+ projectNamedParams
+ .map((kv, index) => {
+ return `
${kv.key}
`;
+ })
+ .join("")
+ }
+
+
+
+
+
+
+ Note: Project's parameters are loaded directly from the .cbNamedParams.properties file in the project root directory. You can edit from that file.
+
+
+
+
+
+
+
+ `;
+};
diff --git a/src/workbench/queryWorkbench.ts b/src/workbench/queryWorkbench.ts
index a8cdcedc..e11f18a4 100644
--- a/src/workbench/queryWorkbench.ts
+++ b/src/workbench/queryWorkbench.ts
@@ -24,6 +24,7 @@ import { saveQuery } from '../util/queryHistory';
import { getUUID } from '../util/util';
import { QueryHistoryTreeProvider } from '../tree/QueryHistoryTreeProvider';
import { IQueryContext } from '../types/IQueryContext';
+import { getAllNamedParameters } from '../util/namedParameters';
export class QueryWorkbench {
private _untitledSqlppDocumentService: UntitledSqlppDocumentService;
@@ -53,10 +54,13 @@ export class QueryWorkbench {
const query = activeTextEditor.selection.isEmpty ? activeTextEditor.document.getText() : activeTextEditor.document.getText(activeTextEditor.selection);
const queryContext = this.editorToContext.get(activeTextEditor.document.uri.toString());
const queryContextString = queryContext && (`${queryContext?.bucketName}.${queryContext?.scopeName}`); // Query context string is of format bucketName.ScopeName
+ const queryParameters = getAllNamedParameters();
+
const queryOptions: QueryOptions = {
profile: QueryProfileMode.Timings,
metrics: true,
- queryContext: queryContextString
+ queryContext: queryContextString,
+ parameters: queryParameters
};
try {
// Reveal the webview when the extension is activated
From ecc2487dfb186418157228e7f65d66579bdc102c Mon Sep 17 00:00:00 2001
From: Lokesh Goel <113521973+lokesh-couchbase@users.noreply.github.com>
Date: Wed, 5 Jun 2024 20:08:39 +0530
Subject: [PATCH 05/24] DA-459 add n1ql file support (#394)
## Describe the problem this PR is solving
## Short description of the changes
-
---
package.json | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/package.json b/package.json
index ae7bae56..d5970f03 100644
--- a/package.json
+++ b/package.json
@@ -694,7 +694,7 @@
"command": "vscode-couchbase.runQuery",
"key": "ctrl+shift+e",
"mac": "cmd+shift+e",
- "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/) && !isKVCluster"
+ "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/ || editorLangId == n1ql || resourceFilename =~ /.n1ql$/) && !isKVCluster"
}
],
"menus": {
@@ -702,7 +702,7 @@
{
"command": "vscode-couchbase.runQuery",
"category": "Couchbase",
- "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/) && !isKVCluster",
+ "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/ || editorLangId == n1ql || resourceFilename =~ /.n1ql$/) && !isKVCluster",
"group": "navigation@1"
},
{
@@ -710,28 +710,28 @@
"command": "vscode-couchbase.queryContext",
"category": "Couchbase",
"group": "navigation@2",
- "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/) && !isKVCluster"
+ "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/ || editorLangId == n1ql || resourceFilename =~ /.n1ql$/) && !isKVCluster"
},
{
"title": "Show Favorite Queries",
"command": "vscode-couchbase.showFavoriteQueries",
"category": "Couchbase",
"group": "navigation@3",
- "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/) && !isKVCluster"
+ "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/ || editorLangId == n1ql || resourceFilename =~ /.n1ql$/) && !isKVCluster"
},
{
"title": "Mark Favorite Query",
"command": "vscode-couchbase.markFavoriteQuery",
"category": "Couchbase",
"group": "navigation@4",
- "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/) && !isKVCluster"
+ "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/ || editorLangId == n1ql || resourceFilename =~ /.n1ql$/) && !isKVCluster"
},
{
"title": "Show Named Parameters",
"command": "vscode-couchbase.showNamedParameters",
"category": "Couchbase",
"group": "navigation@3",
- "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/) && !isKVCluster"
+ "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/ || editorLangId == n1ql || resourceFilename =~ /.n1ql$/) && !isKVCluster"
},
{
"title": "Refresh Cluster Overview",
@@ -758,7 +758,7 @@
"editor/context": [
{
"command": "vscode-couchbase.runQuery",
- "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/) && !isKVCluster",
+ "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/ || editorLangId == n1ql || resourceFilename =~ /.n1ql$/) && !isKVCluster",
"group": "navigation@1"
}
],
From e60f755a4fd370379a0a05d2bbf8fc5553d9ddc6 Mon Sep 17 00:00:00 2001
From: Lokesh Goel <113521973+lokesh-couchbase@users.noreply.github.com>
Date: Wed, 12 Jun 2024 12:05:21 +0530
Subject: [PATCH 06/24] Merge Branch Main into development (#396)
---
package.json | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/package.json b/package.json
index d5970f03..94639054 100644
--- a/package.json
+++ b/package.json
@@ -733,6 +733,13 @@
"group": "navigation@3",
"when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/ || editorLangId == n1ql || resourceFilename =~ /.n1ql$/) && !isKVCluster"
},
+ {
+ "title": "Show Named Parameters",
+ "command": "vscode-couchbase.showNamedParameters",
+ "category": "Couchbase",
+ "group": "navigation@3",
+ "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/) && !isKVCluster"
+ },
{
"title": "Refresh Cluster Overview",
"command": "vscode-couchbase.refreshClusterOverview",
From 818cb5b1a393edbaf3f4b092a3a7d155ebfcb635 Mon Sep 17 00:00:00 2001
From: Lokesh Goel
Date: Wed, 12 Jun 2024 12:10:28 +0530
Subject: [PATCH 07/24] bump version and remove unwanted line in code
---
package.json | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/package.json b/package.json
index 94639054..4cababfb 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "vscode-couchbase",
"displayName": "Couchbase",
"description": "",
- "version": "2.0.3",
+ "version": "2.0.4",
"engines": {
"vscode": "^1.63.1"
},
@@ -733,13 +733,6 @@
"group": "navigation@3",
"when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/ || editorLangId == n1ql || resourceFilename =~ /.n1ql$/) && !isKVCluster"
},
- {
- "title": "Show Named Parameters",
- "command": "vscode-couchbase.showNamedParameters",
- "category": "Couchbase",
- "group": "navigation@3",
- "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/) && !isKVCluster"
- },
{
"title": "Refresh Cluster Overview",
"command": "vscode-couchbase.refreshClusterOverview",
From 04d3397ad31ded8b351062e450fd18c1592e3fc2 Mon Sep 17 00:00:00 2001
From: Lokesh Goel
Date: Wed, 12 Jun 2024 12:15:33 +0530
Subject: [PATCH 08/24] resolve merge conflicts
---
package.json | 7 -------
1 file changed, 7 deletions(-)
diff --git a/package.json b/package.json
index 6631fd72..4cababfb 100644
--- a/package.json
+++ b/package.json
@@ -733,13 +733,6 @@
"group": "navigation@3",
"when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/ || editorLangId == n1ql || resourceFilename =~ /.n1ql$/) && !isKVCluster"
},
- {
- "title": "Show Named Parameters",
- "command": "vscode-couchbase.showNamedParameters",
- "category": "Couchbase",
- "group": "navigation@3",
- "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/) && !isKVCluster"
- },
{
"title": "Refresh Cluster Overview",
"command": "vscode-couchbase.refreshClusterOverview",
From 36975d8c0c65786b31727a004d7961c9db8da992 Mon Sep 17 00:00:00 2001
From: Lokesh Goel <113521973+lokesh-couchbase@users.noreply.github.com>
Date: Wed, 12 Jun 2024 15:13:29 +0530
Subject: [PATCH 09/24] Add feature to support N1QL Files (#397)
---
package.json | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/package.json b/package.json
index ae7bae56..4cababfb 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "vscode-couchbase",
"displayName": "Couchbase",
"description": "",
- "version": "2.0.3",
+ "version": "2.0.4",
"engines": {
"vscode": "^1.63.1"
},
@@ -694,7 +694,7 @@
"command": "vscode-couchbase.runQuery",
"key": "ctrl+shift+e",
"mac": "cmd+shift+e",
- "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/) && !isKVCluster"
+ "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/ || editorLangId == n1ql || resourceFilename =~ /.n1ql$/) && !isKVCluster"
}
],
"menus": {
@@ -702,7 +702,7 @@
{
"command": "vscode-couchbase.runQuery",
"category": "Couchbase",
- "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/) && !isKVCluster",
+ "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/ || editorLangId == n1ql || resourceFilename =~ /.n1ql$/) && !isKVCluster",
"group": "navigation@1"
},
{
@@ -710,28 +710,28 @@
"command": "vscode-couchbase.queryContext",
"category": "Couchbase",
"group": "navigation@2",
- "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/) && !isKVCluster"
+ "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/ || editorLangId == n1ql || resourceFilename =~ /.n1ql$/) && !isKVCluster"
},
{
"title": "Show Favorite Queries",
"command": "vscode-couchbase.showFavoriteQueries",
"category": "Couchbase",
"group": "navigation@3",
- "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/) && !isKVCluster"
+ "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/ || editorLangId == n1ql || resourceFilename =~ /.n1ql$/) && !isKVCluster"
},
{
"title": "Mark Favorite Query",
"command": "vscode-couchbase.markFavoriteQuery",
"category": "Couchbase",
"group": "navigation@4",
- "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/) && !isKVCluster"
+ "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/ || editorLangId == n1ql || resourceFilename =~ /.n1ql$/) && !isKVCluster"
},
{
"title": "Show Named Parameters",
"command": "vscode-couchbase.showNamedParameters",
"category": "Couchbase",
"group": "navigation@3",
- "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/) && !isKVCluster"
+ "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/ || editorLangId == n1ql || resourceFilename =~ /.n1ql$/) && !isKVCluster"
},
{
"title": "Refresh Cluster Overview",
@@ -758,7 +758,7 @@
"editor/context": [
{
"command": "vscode-couchbase.runQuery",
- "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/) && !isKVCluster",
+ "when": "(editorLangId == sqlpp || resourceFilename =~ /.sqlpp$/ || editorLangId == n1ql || resourceFilename =~ /.n1ql$/) && !isKVCluster",
"group": "navigation@1"
}
],
From 5ca51b7605cc795cbc061efb4a1d4ee743ab549d Mon Sep 17 00:00:00 2001
From: Prajwal Pai <108796209+prajwal-pai77@users.noreply.github.com>
Date: Mon, 1 Jul 2024 18:07:07 +0530
Subject: [PATCH 10/24] Add UI Support for DynamoDB to Couchbase (#403)
---
.github/workflows/ci.yml | 2 +-
package-lock.json | 1319 ++++++++++++++++-
package.json | 27 +-
src/commands/extensionCommands/commands.ts | 1 +
src/extension.ts | 10 +
src/handlers/handleCLIDownloader.ts | 12 +-
src/handlers/versionConfig.ts | 2 +-
.../Tools/DynamoDbMigrate/dynamoDbMigrate.ts | 334 +++++
src/tools/DynamoDBMigrate.ts | 97 ++
src/util/constants.ts | 1 +
src/webViews/tools/dynamoDbMigrate.webview.ts | 618 ++++++++
11 files changed, 2405 insertions(+), 18 deletions(-)
create mode 100644 src/pages/Tools/DynamoDbMigrate/dynamoDbMigrate.ts
create mode 100644 src/tools/DynamoDBMigrate.ts
create mode 100644 src/webViews/tools/dynamoDbMigrate.webview.ts
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 9c0c3b2a..d767623f 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -54,7 +54,7 @@ jobs:
- name: windows-specific
shell: pwsh
if: matrix.platform == 'win32'
- run: choco install openssl.light --version=1.1.1 && choco install cmake --global && npm install --global cmake-js node-gyp && echo CMAKE_JS_LIB - $CMAKE_JS_LIB
+ run: choco install openssl.light --version=1.1.1 && choco install cmake --global && npm install --global cmake-js node-gyp && echo CMAKE_JS_LIB - $CMAKE_JS_LIB
- name: mac-specific
shell: bash
if: matrix.platform == 'darwin'
diff --git a/package-lock.json b/package-lock.json
index 9942ad52..c262158e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,14 +1,16 @@
{
"name": "vscode-couchbase",
- "version": "2.0.3",
+ "version": "2.0.5",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "vscode-couchbase",
- "version": "2.0.3",
+ "version": "2.0.5",
"license": "SEE LICENSE IN LICENSE",
"dependencies": {
+ "@aws-sdk/client-dynamodb": "^3.602.0",
+ "@aws-sdk/credential-providers": "^3.600.0",
"@chatscope/chat-ui-kit-styles": "^1.4.0",
"@fortawesome/fontawesome-svg-core": "^6.5.1",
"@fortawesome/free-solid-svg-icons": "^6.5.1",
@@ -114,6 +116,748 @@
"node": ">=6.0.0"
}
},
+ "node_modules/@aws-crypto/sha256-browser": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz",
+ "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==",
+ "dependencies": {
+ "@aws-crypto/sha256-js": "^5.2.0",
+ "@aws-crypto/supports-web-crypto": "^5.2.0",
+ "@aws-crypto/util": "^5.2.0",
+ "@aws-sdk/types": "^3.222.0",
+ "@aws-sdk/util-locate-window": "^3.0.0",
+ "@smithy/util-utf8": "^2.0.0",
+ "tslib": "^2.6.2"
+ }
+ },
+ "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz",
+ "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz",
+ "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==",
+ "dependencies": {
+ "@smithy/is-array-buffer": "^2.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz",
+ "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==",
+ "dependencies": {
+ "@smithy/util-buffer-from": "^2.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@aws-crypto/sha256-js": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz",
+ "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==",
+ "dependencies": {
+ "@aws-crypto/util": "^5.2.0",
+ "@aws-sdk/types": "^3.222.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/@aws-crypto/supports-web-crypto": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz",
+ "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ }
+ },
+ "node_modules/@aws-crypto/util": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz",
+ "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==",
+ "dependencies": {
+ "@aws-sdk/types": "^3.222.0",
+ "@smithy/util-utf8": "^2.0.0",
+ "tslib": "^2.6.2"
+ }
+ },
+ "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz",
+ "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz",
+ "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==",
+ "dependencies": {
+ "@smithy/is-array-buffer": "^2.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz",
+ "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==",
+ "dependencies": {
+ "@smithy/util-buffer-from": "^2.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "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==",
+ "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",
+ "@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-utf8": "^3.0.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/client-dynamodb": {
+ "version": "3.602.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb/-/client-dynamodb-3.602.0.tgz",
+ "integrity": "sha512-q7lH7YD9KvHLF3tyAG1UqaPv4a6KiHLunqKYh8vt3d1WJK7t4wzE97Vf19MfNpza1MuZ0OF/SK8Kl69vEMrtOA==",
+ "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-endpoint-discovery": "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",
+ "@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-utf8": "^3.0.0",
+ "@smithy/util-waiter": "^3.0.1",
+ "tslib": "^2.6.2",
+ "uuid": "^9.0.1"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "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",
+ "@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-utf8": "^3.0.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "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",
+ "@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-utf8": "^3.0.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "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",
+ "@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-utf8": "^3.0.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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",
+ "fast-xml-parser": "4.2.5",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@aws-sdk/types": "3.598.0",
+ "@smithy/property-provider": "^3.1.1",
+ "@smithy/types": "^3.1.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ },
+ "peerDependencies": {
+ "@aws-sdk/client-sts": "^3.598.0"
+ }
+ },
+ "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",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@aws-sdk/types": "3.598.0",
+ "@smithy/property-provider": "^3.1.1",
+ "@smithy/types": "^3.1.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ },
+ "peerDependencies": {
+ "@aws-sdk/client-sts": "^3.598.0"
+ }
+ },
+ "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",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/endpoint-cache": {
+ "version": "3.572.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/endpoint-cache/-/endpoint-cache-3.572.0.tgz",
+ "integrity": "sha512-CzuRWMj/xtN9p9eP915nlPmlyniTzke732Ow/M60++gGgB3W+RtZyFftw3TEx+NzNhd1tH54dEcGiWdiNaBz3Q==",
+ "dependencies": {
+ "mnemonist": "0.38.3",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/middleware-endpoint-discovery": {
+ "version": "3.598.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint-discovery/-/middleware-endpoint-discovery-3.598.0.tgz",
+ "integrity": "sha512-TaFo3rfapVP0FiddH2zDyA5R5XNk2M+zMeUZaBRveYamSQ11F+fMGcedBgbOsv7yNESvaZvjlcw2K+cx3jOchA==",
+ "dependencies": {
+ "@aws-sdk/endpoint-cache": "3.572.0",
+ "@aws-sdk/types": "3.598.0",
+ "@smithy/node-config-provider": "^3.1.1",
+ "@smithy/protocol-http": "^4.0.1",
+ "@smithy/types": "^3.1.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@aws-sdk/types": "3.598.0",
+ "@smithy/protocol-http": "^4.0.1",
+ "@smithy/types": "^3.1.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@aws-sdk/types": "3.598.0",
+ "@smithy/types": "^3.1.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@aws-sdk/types": "3.598.0",
+ "@smithy/protocol-http": "^4.0.1",
+ "@smithy/types": "^3.1.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@aws-sdk/types": "3.598.0",
+ "@smithy/node-config-provider": "^3.1.1",
+ "@smithy/types": "^3.1.0",
+ "@smithy/util-config-provider": "^3.0.0",
+ "@smithy/util-middleware": "^3.0.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ },
+ "peerDependencies": {
+ "@aws-sdk/client-sso-oidc": "^3.598.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@smithy/types": "^3.1.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@aws-sdk/types": "3.598.0",
+ "@smithy/types": "^3.1.0",
+ "@smithy/util-endpoints": "^2.0.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/util-locate-window": {
+ "version": "3.568.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.568.0.tgz",
+ "integrity": "sha512-3nh4TINkXYr+H41QaPelCceEB2FXP3fxp93YZXB/kqJvX0U9j0N0Uk45gvsjmEPzG8XxkPEeLIfT2I1M7A6Lig==",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@aws-sdk/types": "3.598.0",
+ "@smithy/types": "^3.1.0",
+ "bowser": "^2.11.0",
+ "tslib": "^2.6.2"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@aws-sdk/types": "3.598.0",
+ "@smithy/node-config-provider": "^3.1.1",
+ "@smithy/types": "^3.1.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ },
+ "peerDependencies": {
+ "aws-crt": ">=1.0.0"
+ },
+ "peerDependenciesMeta": {
+ "aws-crt": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@babel/code-frame": {
"version": "7.24.2",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz",
@@ -3041,6 +3785,530 @@
"@sinonjs/commons": "^3.0.0"
}
},
+ "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==",
+ "dependencies": {
+ "@smithy/types": "^3.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@smithy/node-config-provider": "^3.1.2",
+ "@smithy/types": "^3.2.0",
+ "@smithy/util-config-provider": "^3.0.0",
+ "@smithy/util-middleware": "^3.0.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "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",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@smithy/protocol-http": "^4.0.2",
+ "@smithy/querystring-builder": "^3.0.2",
+ "@smithy/types": "^3.2.0",
+ "@smithy/util-base64": "^3.0.0",
+ "tslib": "^2.6.2"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@smithy/types": "^3.2.0",
+ "@smithy/util-buffer-from": "^3.0.0",
+ "@smithy/util-utf8": "^3.0.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@smithy/types": "^3.2.0",
+ "tslib": "^2.6.2"
+ }
+ },
+ "node_modules/@smithy/is-array-buffer": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz",
+ "integrity": "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@smithy/protocol-http": "^4.0.2",
+ "@smithy/types": "^3.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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",
+ "tslib": "^2.6.2",
+ "uuid": "^9.0.1"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@smithy/types": "^3.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@smithy/types": "^3.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@smithy/property-provider": "^3.1.2",
+ "@smithy/shared-ini-file-loader": "^3.1.2",
+ "@smithy/types": "^3.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@smithy/abort-controller": "^3.1.0",
+ "@smithy/protocol-http": "^4.0.2",
+ "@smithy/querystring-builder": "^3.0.2",
+ "@smithy/types": "^3.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@smithy/types": "^3.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@smithy/types": "^3.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@smithy/types": "^3.2.0",
+ "@smithy/util-uri-escape": "^3.0.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@smithy/types": "^3.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@smithy/types": "^3.2.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==",
+ "dependencies": {
+ "@smithy/types": "^3.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@smithy/is-array-buffer": "^3.0.0",
+ "@smithy/types": "^3.2.0",
+ "@smithy/util-hex-encoding": "^3.0.0",
+ "@smithy/util-middleware": "^3.0.2",
+ "@smithy/util-uri-escape": "^3.0.0",
+ "@smithy/util-utf8": "^3.0.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@smithy/querystring-parser": "^3.0.2",
+ "@smithy/types": "^3.2.0",
+ "tslib": "^2.6.2"
+ }
+ },
+ "node_modules/@smithy/util-base64": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz",
+ "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==",
+ "dependencies": {
+ "@smithy/util-buffer-from": "^3.0.0",
+ "@smithy/util-utf8": "^3.0.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/@smithy/util-body-length-browser": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-3.0.0.tgz",
+ "integrity": "sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ }
+ },
+ "node_modules/@smithy/util-body-length-node": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-3.0.0.tgz",
+ "integrity": "sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/@smithy/util-buffer-from": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-3.0.0.tgz",
+ "integrity": "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==",
+ "dependencies": {
+ "@smithy/is-array-buffer": "^3.0.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/@smithy/util-config-provider": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-3.0.0.tgz",
+ "integrity": "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@smithy/property-provider": "^3.1.2",
+ "@smithy/smithy-client": "^3.1.4",
+ "@smithy/types": "^3.2.0",
+ "bowser": "^2.11.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "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",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@smithy/node-config-provider": "^3.1.2",
+ "@smithy/types": "^3.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/@smithy/util-hex-encoding": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz",
+ "integrity": "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@smithy/types": "^3.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@smithy/service-error-classification": "^3.0.2",
+ "@smithy/types": "^3.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@smithy/fetch-http-handler": "^3.1.0",
+ "@smithy/node-http-handler": "^3.1.0",
+ "@smithy/types": "^3.2.0",
+ "@smithy/util-base64": "^3.0.0",
+ "@smithy/util-buffer-from": "^3.0.0",
+ "@smithy/util-hex-encoding": "^3.0.0",
+ "@smithy/util-utf8": "^3.0.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/@smithy/util-uri-escape": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz",
+ "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/@smithy/util-utf8": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-3.0.0.tgz",
+ "integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==",
+ "dependencies": {
+ "@smithy/util-buffer-from": "^3.0.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/@smithy/util-waiter": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-3.1.0.tgz",
+ "integrity": "sha512-5OVcC5ZcmmutY208ADY/l2eB4H4DVXs+hPUo/M1spF4/YEmF9DdLkfwBvohej2dIeVJayKY7hMlD0X8j3F3/Uw==",
+ "dependencies": {
+ "@smithy/abort-controller": "^3.1.0",
+ "@smithy/types": "^3.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
"node_modules/@tootallnate/once": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
@@ -4517,6 +5785,11 @@
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
"dev": true
},
+ "node_modules/bowser": {
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz",
+ "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA=="
+ },
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -6764,6 +8037,27 @@
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
"dev": true
},
+ "node_modules/fast-xml-parser": {
+ "version": "4.2.5",
+ "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz",
+ "integrity": "sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==",
+ "funding": [
+ {
+ "type": "paypal",
+ "url": "https://paypal.me/naturalintelligence"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "dependencies": {
+ "strnum": "^1.0.5"
+ },
+ "bin": {
+ "fxparser": "src/cli/cli.js"
+ }
+ },
"node_modules/fastest-levenshtein": {
"version": "1.0.16",
"resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
@@ -11366,6 +12660,14 @@
"node": ">=10"
}
},
+ "node_modules/mnemonist": {
+ "version": "0.38.3",
+ "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.3.tgz",
+ "integrity": "sha512-2K9QYubXx/NAjv4VLq1d1Ly8pWNC5L3BrixtdkyTegXWJIqY+zLNDhhX/A+ZwWt70tB1S8H4BE8FLYEFyNoOBw==",
+ "dependencies": {
+ "obliterator": "^1.6.1"
+ }
+ },
"node_modules/mocha": {
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz",
@@ -11946,6 +13248,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/obliterator": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-1.6.1.tgz",
+ "integrity": "sha512-9WXswnqINnnhOG/5SLimUlzuU1hFJUc8zkwyD59Sd+dPOMf05PmnYG/d6Q7HZ+KmgkZJa1PxRso6QdM3sTNHig=="
+ },
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -13891,6 +15198,11 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/strnum": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
+ "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA=="
+ },
"node_modules/style-loader": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz",
@@ -14469,8 +15781,7 @@
"node_modules/tslib": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
- "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
- "dev": true
+ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
},
"node_modules/type-check": {
"version": "0.4.0",
diff --git a/package.json b/package.json
index 4cababfb..ca4b2490 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "vscode-couchbase",
"displayName": "Couchbase",
"description": "",
- "version": "2.0.4",
+ "version": "2.0.5",
"engines": {
"vscode": "^1.63.1"
},
@@ -91,6 +91,8 @@
"webpack-cli": "^5.1.4"
},
"dependencies": {
+ "@aws-sdk/client-dynamodb": "^3.602.0",
+ "@aws-sdk/credential-providers": "^3.600.0",
"@chatscope/chat-ui-kit-styles": "^1.4.0",
"@fortawesome/fontawesome-svg-core": "^6.5.1",
"@fortawesome/free-solid-svg-icons": "^6.5.1",
@@ -569,6 +571,11 @@
"title": "MongoDB Migrate",
"category": "Couchbase"
},
+ {
+ "command": "vscode-couchbase.tools.dynamodbMigrate",
+ "title": "DynamoDB Migrate",
+ "category": "Couchbase"
+ },
{
"command": "vscode-couchbase.tools.dataImport",
"title": "Data Import",
@@ -898,6 +905,10 @@
"command": "vscode-couchbase.tools.mdbMigrate",
"when": "false"
},
+ {
+ "command": "vscode-couchbase.tools.dynamodbMigrate",
+ "when": "false"
+ },
{
"command": "vscode-couchbase.tools.dataImport",
"when": "false"
@@ -1078,19 +1089,23 @@
"vscode-couchbase.toolsMenu": [
{
"command": "vscode-couchbase.tools.dataExport",
- "group": "navigation"
+ "group": "secondary"
},
{
"command": "vscode-couchbase.tools.mdbMigrate",
- "group": "navigation"
+ "group": "tertiary"
+ },
+ {
+ "command": "vscode-couchbase.tools.dynamodbMigrate",
+ "group": "tertiary"
},
{
"command": "vscode-couchbase.tools.dataImport",
- "group": "navigation"
+ "group": "secondary"
},
{
"command": "vscode-couchbase.tools.DDLExport",
- "group": "navigation"
+ "group": "secondary"
}
],
"vscode-couchbase.filterDocumentsMenu": [
@@ -1185,4 +1200,4 @@
}
]
}
-}
\ No newline at end of file
+}
diff --git a/src/commands/extensionCommands/commands.ts b/src/commands/extensionCommands/commands.ts
index eb74b5f1..9076f55c 100644
--- a/src/commands/extensionCommands/commands.ts
+++ b/src/commands/extensionCommands/commands.ts
@@ -61,6 +61,7 @@ export namespace Commands {
export const checkAndCreatePrimaryIndex: string = "vscode-couchbase.checkAndCreatePrimaryIndex";
export const dataExport: string = "vscode-couchbase.tools.dataExport";
export const mdbMigrate: string = "vscode-couchbase.tools.mdbMigrate";
+ export const dynamodbMigrate: string = "vscode-couchbase.tools.dynamodbMigrate";
export const dataImport: string = "vscode-couchbase.tools.dataImport";
export const ddlExport: string = "vscode-couchbase.tools.DDLExport";
export const couchbaseIqViewsCommand: string = "couchbase-iq";
diff --git a/src/extension.ts b/src/extension.ts
index 8e1fc5d7..7779d78b 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -77,6 +77,7 @@ import { SecretService } from "./util/secretService";
import { kvTypeFilterDocuments } from "./commands/documents/documentFilters/kvTypeFilterDocuments";
import { fetchNamedParameters } from "./pages/namedParameters/namedParameters";
import { sqlppComlpletions, sqlppNamedParametersCompletions, sqlppSchemaComlpletions } from "./commands/sqlpp/sqlppCompletions";
+import { dynamodbMigrate } from "./pages/Tools/DynamoDbMigrate/dynamoDbMigrate";
export function activate(context: vscode.ExtensionContext) {
Global.setState(context.globalState);
@@ -586,6 +587,15 @@ export function activate(context: vscode.ExtensionContext) {
)
);
+ subscriptions.push(
+ vscode.commands.registerCommand(
+ Commands.dynamodbMigrate,
+ async () => {
+ await dynamodbMigrate(context);
+ }
+ )
+ );
+
subscriptions.push(
vscode.commands.registerCommand(
Commands.dataImport,
diff --git a/src/handlers/handleCLIDownloader.ts b/src/handlers/handleCLIDownloader.ts
index 2c6b8498..d4a4db15 100644
--- a/src/handlers/handleCLIDownloader.ts
+++ b/src/handlers/handleCLIDownloader.ts
@@ -108,7 +108,7 @@ class DependenciesDownloader {
map.set(
this.TOOL_MDB_MIGRATE,
this.getToolSpec(
- "https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/cbmigrate/cbmigrate_0.0.1-beta_darwin_amd64.zip",
+ "https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/cbmigrate/cbmigrate_0.1.0_darwin_amd64.zip",
this.TOOL_MDB_MIGRATE,
OSUtil.MACOS_64
)
@@ -141,7 +141,7 @@ class DependenciesDownloader {
map.set(
this.TOOL_MDB_MIGRATE,
this.getToolSpec(
- "https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/cbmigrate/cbmigrate_0.0.1-beta_darwin_arm64.zip",
+ "https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/cbmigrate/cbmigrate_0.1.0_darwin_arm64.zip",
this.TOOL_MDB_MIGRATE,
OSUtil.MACOS_ARM
)
@@ -174,7 +174,7 @@ class DependenciesDownloader {
map.set(
this.TOOL_MDB_MIGRATE,
this.getToolSpec(
- "https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/cbmigrate/cbmigrate_0.0.1-beta_windows_amd64.zip",
+ "https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/cbmigrate/cbmigrate_0.1.0_windows_amd64.zip",
this.TOOL_MDB_MIGRATE,
OSUtil.WINDOWS_64
)
@@ -207,7 +207,7 @@ class DependenciesDownloader {
map.set(
this.TOOL_MDB_MIGRATE,
this.getToolSpec(
- "https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/cbmigrate/cbmigrate_0.0.1-beta_windows_amd64.zip",
+ "https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/cbmigrate/cbmigrate_0.1.0_windows_amd64.zip",
this.TOOL_MDB_MIGRATE,
OSUtil.WINDOWS_ARM
)
@@ -240,7 +240,7 @@ class DependenciesDownloader {
map.set(
this.TOOL_MDB_MIGRATE,
this.getToolSpec(
- "https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/cbmigrate/cbmigrate_0.0.1-beta_linux_amd64.zip",
+ "https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/cbmigrate/cbmigrate_0.1.0_linux_amd64.zip",
this.TOOL_MDB_MIGRATE,
OSUtil.LINUX_64
)
@@ -265,7 +265,7 @@ class DependenciesDownloader {
map.set(
this.TOOL_MDB_MIGRATE,
this.getToolSpec(
- "https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/cbmigrate/cbmigrate_0.0.1-beta_linux_arm64.zip",
+ "https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/cbmigrate/cbmigrate_0.1.0_linux_arm64.zip",
this.TOOL_MDB_MIGRATE,
OSUtil.LINUX_ARM
)
diff --git a/src/handlers/versionConfig.ts b/src/handlers/versionConfig.ts
index 1ae97dc1..300aee7a 100644
--- a/src/handlers/versionConfig.ts
+++ b/src/handlers/versionConfig.ts
@@ -5,7 +5,7 @@ export const config = {
SHELL_KEY: "shell",
CBIMPORT_EXPORT_KEY: "cbimport_export",
TOOLS_VERSION: "7.2",
- CBMIGRATE_VERSION: "1",
+ CBMIGRATE_VERSION: "2",
SHELL_VERSION: "1",
CBIMPORT_EXPORT_VERSION: "7.6",
};
\ No newline at end of file
diff --git a/src/pages/Tools/DynamoDbMigrate/dynamoDbMigrate.ts b/src/pages/Tools/DynamoDbMigrate/dynamoDbMigrate.ts
new file mode 100644
index 00000000..f84fd540
--- /dev/null
+++ b/src/pages/Tools/DynamoDbMigrate/dynamoDbMigrate.ts
@@ -0,0 +1,334 @@
+import {
+ DynamoDBClient,
+ ListTablesCommand,
+ ListTablesCommandOutput
+} from "@aws-sdk/client-dynamodb";
+import { fromIni } from "@aws-sdk/credential-providers";
+import { readFile } from "fs/promises";
+import { join } from "path";
+import { DynamoDBToCb } from "../../../tools/DynamoDBMigrate";
+import {
+ CBTools,
+ Type as CBToolsType,
+} from "../../../util/DependencyDownloaderUtils/CBTool";
+import * as vscode from "vscode";
+import { getActiveConnection } from "../../../util/connections";
+import { Memory } from "../../../util/util";
+import { Constants } from "../../../util/constants";
+import { logger } from "../../../logger/logger";
+import * as path from "path";
+import { getLoader } from "../../../webViews/loader.webview";
+import { dynamoDBMigrateWebView } from "../../../webViews/tools/dynamoDbMigrate.webview";
+import { IConnection } from "../../../types/IConnection";
+
+export const getScopes = async (bucketId: string, connection: IConnection) => {
+ const scopes = await connection.cluster
+ ?.bucket(bucketId)
+ .collections()
+ .getAllScopes();
+ return scopes;
+};
+
+const validateFormData = (formData: any): string => {
+ const errors = [];
+ if (!formData.awsRegion.trim()) {
+ errors.push("Please specify a Aws Region");
+ }
+
+ if (!formData.tables || formData.tables.length === 0) {
+ errors.push("Please specify the DynamoDB tables field");
+ }
+
+ if (!formData.cbBucket) {
+ errors.push("Please select a Couchbase bucket");
+ }
+
+ if (!formData.cbScope || formData.cbScope.length === 0) {
+ errors.push("Please select a Couchbase scope field");
+ }
+
+ if (errors.length > 0) {
+ return errors.join("
");
+ }
+
+ return "";
+};
+
+
+export interface IDataMigrateWebviewState {
+ webviewPanel: vscode.WebviewPanel;
+}
+
+export const dynamodbMigrate = async (context: vscode.ExtensionContext) => {
+ const connection = getActiveConnection();
+ if (!connection) {
+ return;
+ }
+ if (!CBTools.getTool(CBToolsType.CB_MIGRATE).isAvailable()) {
+ vscode.window.showErrorMessage(
+ "CB Migrate is still loading, Please try again later"
+ );
+ return;
+ }
+
+ const dataMigratetWebviewDetails =
+ Memory.state.get(
+ Constants.DATA_MIGRATE_DYNAMODB_WEBVIEW
+ );
+ if (dataMigratetWebviewDetails) {
+ // data migrate webview already exists, Closing existing and creating new
+ try {
+ dataMigratetWebviewDetails.webviewPanel.dispose();
+ } catch (e) {
+ logger.error("Error while disposing data migrate webview: " + e);
+ }
+ Memory.state.update(Constants.DATA_MIGRATE_DYNAMODB_WEBVIEW, null);
+ }
+
+ const currentPanel = vscode.window.createWebviewPanel(
+ "dataMigrate",
+ "Data Migration from DynamoDB to Couchbase",
+ vscode.ViewColumn.One,
+ {
+ enableScripts: true,
+ enableForms: true,
+ retainContextWhenHidden: true
+ }
+ );
+ Memory.state.update(Constants.DATA_MIGRATE_DYNAMODB_WEBVIEW, {
+ webviewPanel: currentPanel,
+ });
+ currentPanel.iconPath = {
+ dark: vscode.Uri.file(
+ path.join(
+ __filename,
+ "..",
+ "..",
+ "images",
+ "dark",
+ "export_dark.svg"
+ )
+ ),
+ light: vscode.Uri.file(
+ path.join(
+ __filename,
+ "..",
+ "..",
+ "images",
+ "light",
+ "export_light.svg"
+ )
+ ),
+ };
+ currentPanel.webview.html = getLoader("Data Migrate");
+
+ // Get all buckets
+ const buckets = await connection.cluster?.buckets().getAllBuckets();
+ if (buckets === undefined) {
+ vscode.window.showErrorMessage("Buckets not found");
+ return;
+ }
+
+ const awsRegions = new Map([
+ ["US East (N. Virginia)", "us-east-1"],
+ ["US East (Ohio)", "us-east-2"],
+ ["US West (N. California)", "us-west-1"],
+ ["US West (Oregon)", "us-west-2"],
+ ["Africa (Cape Town)", "af-south-1"],
+ ["Asia Pacific (Hong Kong)", "ap-east-1"],
+ ["Asia Pacific (Mumbai)", "ap-south-1"],
+ ["Asia Pacific (Osaka)", "ap-northeast-3"],
+ ["Asia Pacific (Seoul)", "ap-northeast-2"],
+ ["Asia Pacific (Singapore)", "ap-southeast-1"],
+ ["Asia Pacific (Sydney)", "ap-southeast-2"],
+ ["Asia Pacific (Tokyo)", "ap-northeast-1"],
+ ["Canada (Central)", "ca-central-1"],
+ ["China (Beijing)", "cn-north-1"],
+ ["China (Ningxia)", "cn-northwest-1"],
+ ["Europe (Frankfurt)", "eu-central-1"],
+ ["Europe (Ireland)", "eu-west-1"],
+ ["Europe (London)", "eu-west-2"],
+ ["Europe (Milan)", "eu-south-1"],
+ ["Europe (Paris)", "eu-west-3"],
+ ["Europe (Stockholm)", "eu-north-1"],
+ ["Middle East (Bahrain)", "me-south-1"],
+ ["South America (São Paulo)", "sa-east-1"]
+ ]);
+
+ const bucketNameArr: string[] = buckets.map((b) => b.name);
+ const awsProfiles = await listProfiles()
+
+
+ try {
+ currentPanel.webview.html = await dynamoDBMigrateWebView(bucketNameArr, awsProfiles, awsRegions);
+ currentPanel.webview.onDidReceiveMessage(async (message) => {
+ switch (message.command) {
+ case "vscode-couchbase.tools.dynamodbMigrate.Migrate":
+ const formData = message.data;
+ const validationError = validateFormData(formData);
+ if (validationError === "") {
+ DynamoDBToCb.export(
+ formData.useAwsProfile,
+ formData.awsProfile,
+ formData.awsRegion,
+ formData.tables,
+ formData.awsAccessKey,
+ formData.awsSecretKey,
+ formData.cbBucket,
+ formData.cbScope,
+ formData.indexes,
+ formData.debug,
+ formData.sslNoVerify,
+ );
+ } else {
+ currentPanel.webview.postMessage({
+ command:
+ "vscode-couchbase.tools.dynamodbMigrate.formValidationError",
+ error: validationError,
+ });
+ }
+ break;
+
+ case "vscode-couchbase.tools.dynamodbMigrate.getCbScopes":
+ const scopes = await getScopes(
+ message.bucketId,
+ connection
+ );
+ if (scopes === undefined) {
+ vscode.window.showErrorMessage("Scopes are undefined");
+ break;
+ }
+ currentPanel.webview.postMessage({
+ command: "vscode-couchbase.tools.dynamodbMigrate.scopesInfo",
+ scopes: scopes,
+ });
+ break;
+
+ case "vscode-couchbase.tools.dynamodbMigrate.getTables":
+ let result: any
+ if (message.awsRegion === "") {
+ currentPanel.webview.postMessage({
+ command:
+ "vscode-couchbase.tools.dynamodbMigrate.connectValidationError",
+ error: "Please specify a AWS region",
+ });
+ break;
+ }
+ if (message.useAwsProfile) {
+ if (message.awsProfile === "") {
+ currentPanel.webview.postMessage({
+ command:
+ "vscode-couchbase.tools.dynamodbMigrate.connectValidationError",
+ error: "Please specify a AWS profile",
+ });
+ break;
+ }
+ result = await listTablesByProfile(
+ message.awsRegion,
+ message.awsProfile
+ );
+ } else {
+ if (message.awsAccessKeyId === "" || message.awsSecretAccessKey === "") {
+ currentPanel.webview.postMessage({
+ command:
+ "vscode-couchbase.tools.dynamodbMigrate.connectValidationError",
+ error: "Please specify the AWS Access and Secret Key",
+ });
+ break;
+ }
+ result = await listTables(
+ message.awsRegion,
+ message.awsAccessKeyId,
+ message.awsSecretAccessKey,
+ );
+ }
+ if (result.error) {
+ currentPanel.webview.postMessage({
+ command:
+ "vscode-couchbase.tools.dynamodbMigrate.connectValidationError",
+ error: result.error,
+ });
+ } else {
+ currentPanel.webview.postMessage({
+ command:
+ "vscode-couchbase.tools.dynamodbMigrate.tableInfo",
+ tables: result.tables,
+ });
+ }
+ break;
+ }
+ });
+ } catch (err) {
+ logger.error(`Failed to open data migrate webview`);
+ logger.debug(err);
+ vscode.window.showErrorMessage(
+ "Failed to open data migrate webview: " + err
+ );
+ }
+
+ currentPanel.onDidDispose(() => {
+ Memory.state.update(Constants.DATA_MIGRATE_DYNAMODB_WEBVIEW, null);
+ });
+};
+
+
+async function listTables(region: string, awsAccessKeyId: string, awsSecretAccessKey: string): Promise<{ tables: string[], error: string | null }> {
+ const ddb = new DynamoDBClient({
+ region,
+ credentials: {
+ accessKeyId: awsAccessKeyId,
+ secretAccessKey: awsSecretAccessKey
+ }
+ });
+ try {
+ return await listTablesFromClient(ddb);
+ } finally {
+ ddb.destroy();
+ }
+}
+
+async function listTablesByProfile(region: string, profile: string): Promise<{ tables: string[], error: string | null }> {
+ const ddb = new DynamoDBClient({
+ region,
+ credentials: fromIni({ profile })
+ });
+ try {
+ return await listTablesFromClient(ddb);
+ } finally {
+ ddb.destroy();
+ }
+}
+
+async function listProfiles(): Promise> {
+ const credentialsPath = join(process.env.HOME || "", ".aws", "credentials");
+ try {
+ const content = await readFile(credentialsPath, { encoding: "utf-8" });
+ const profiles = new Set();
+ const regex = /^\[([\w-]+)\]/gm;
+ let match;
+ while (match = regex.exec(content)) {
+ profiles.add(match[1]);
+ }
+ return profiles;
+ } catch (error) {
+ console.error("Error reading profiles:", error);
+ return new Set();
+ }
+}
+
+async function listTablesFromClient(ddb: DynamoDBClient): Promise<{ tables: string[], error: string | null }> {
+ try {
+ const command = new ListTablesCommand({});
+ const response: ListTablesCommandOutput = await ddb.send(command);
+ if (response.TableNames && response.TableNames.length > 0) {
+ return { tables: response.TableNames, error: null };
+ } else {
+ return { tables: [], error: "No DynamoDB tables found for the selected region and credentials." };
+ }
+ } catch (err) {
+ logger.error("Error occured while connecting to DynamoDB instance " + err)
+ return { tables: [], error: "An error occured while trying to connect to the DynamoDB instance. Check logs for error." };;
+ }
+
+}
+
diff --git a/src/tools/DynamoDBMigrate.ts b/src/tools/DynamoDBMigrate.ts
new file mode 100644
index 00000000..10922698
--- /dev/null
+++ b/src/tools/DynamoDBMigrate.ts
@@ -0,0 +1,97 @@
+import { CBTools, Type } from "../util/DependencyDownloaderUtils/CBTool";
+import { getActiveConnection, getConnectionId } from "../util/connections";
+import { Constants } from "../util/constants";
+import * as vscode from "vscode";
+import { SecretService } from "../util/secretService";
+
+export class DynamoDBToCb {
+ static async export(
+ useAwsProfile: boolean,
+ awsProfile: string,
+ awsRegion: string,
+ tables: string[],
+ awsAccessKey: string,
+ awsSecretKey: string,
+ cbBucket: string,
+ cbScope: string,
+ indexes: string,
+ debug: boolean,
+ noSslVerify: boolean
+ ): Promise {
+ const connection = getActiveConnection();
+ if (!connection) {
+ return;
+ }
+
+ const secretService = SecretService.getInstance();
+ const password = await secretService.get(`${Constants.extensionID}-${getConnectionId(connection)}`);
+ if (!password) {
+ return undefined;
+ }
+ try {
+ // Build Command
+ for (const table of tables) {
+ const cmd: string[] = [];
+ cmd.push(CBTools.getTool(Type.CB_MIGRATE).path);
+ cmd.push("dynamodb ");
+ if (useAwsProfile) {
+ cmd.push("--aws-profile");
+ cmd.push(awsProfile);
+ } else {
+ cmd.push("--aws-access-key-id");
+ cmd.push(awsAccessKey);
+ cmd.push("--aws-secret-access-key");
+ cmd.push(awsSecretKey)
+ }
+ cmd.push("--dynamodb-table-name");
+ cmd.push(table);
+ cmd.push("--cb-bucket");
+ cmd.push(cbBucket);
+ cmd.push("--cb-scope");
+ cmd.push(cbScope);
+ cmd.push("--aws-region");
+ cmd.push(awsRegion);
+
+ cmd.push("--cb-collection")
+ cmd.push(table)
+
+ cmd.push("--cb-cluster")
+ cmd.push(connection.url)
+ cmd.push("--cb-username");
+ cmd.push(connection.username);
+
+ if (indexes) {
+ cmd.push("--copy-indexes")
+ }
+
+ cmd.push("--cb-password");
+ cmd.push("'" + password + "'");
+
+
+ if (debug) {
+ cmd.push("--debug")
+ }
+
+ if (noSslVerify) {
+ cmd.push("--cb-no-ssl-verify true")
+ }
+
+
+ cmd.push("; \n");
+
+ // Run Command
+ const terminal: vscode.Terminal =
+ vscode.window.createTerminal("DynamoDBToCb");
+ const text = cmd.join(" ");
+ terminal.sendText(text);
+ terminal.show();
+ }
+ } catch (error) {
+ console.error(
+ "An error occurred while trying to migrate the tables from DynamoDb to couchbase"
+ );
+ console.error(error);
+ }
+ }
+}
+
diff --git a/src/util/constants.ts b/src/util/constants.ts
index 506d353b..dec24d30 100644
--- a/src/util/constants.ts
+++ b/src/util/constants.ts
@@ -106,5 +106,6 @@ export class Constants {
public static QUERY_RESULT = "Couchbase Query Result";
public static DATA_EXPORT_WEBVIEW = "dataExportWebview";
public static DATA_MIGRATE_MDB_WEBVIEW = "dataMdbMigrateWebview";
+ public static DATA_MIGRATE_DYNAMODB_WEBVIEW = "dataDynamodbWebview"
public static DATA_IMPORT_WEBVIEW = "dataImportWebview";
}
diff --git a/src/webViews/tools/dynamoDbMigrate.webview.ts b/src/webViews/tools/dynamoDbMigrate.webview.ts
new file mode 100644
index 00000000..50385b4f
--- /dev/null
+++ b/src/webViews/tools/dynamoDbMigrate.webview.ts
@@ -0,0 +1,618 @@
+export const dynamoDBMigrateWebView = async (buckets: string[], awsProfiles: Set, awsRegions: Map): Promise => {
+ return /*html*/`
+
+
+
+
+
+ Data Migrate
+
+
+
+
+
+ DynamoDB to Couchbase Data Migration
+
+
+
+
+
+
+ `;
+};
From a6273b9d98c37103013950b97faf876c218467fb Mon Sep 17 00:00:00 2001
From: Prajwal Pai
Date: Tue, 16 Jul 2024 12:16:24 +0530
Subject: [PATCH 11/24] Add support for Fts auto Complete and docs + tests
---
__mocks__/vscode.js | 55 +
docs/search/analyzer.md | 7 +
docs/search/bool.md | 7 +
docs/search/boost.md | 5 +
docs/search/bottom_right.md | 11 +
docs/search/cidr.md | 5 +
docs/search/collections.md | 3 +
docs/search/conjuncts.md | 9 +
docs/search/consistency.md | 5 +
docs/search/coordinates.md | 72 +
docs/search/ctl.md | 5 +
docs/search/disjuncts.md | 9 +
docs/search/distance.md | 16 +
docs/search/end.md | 7 +
docs/search/explain.md | 5 +
docs/search/facets.md | 9 +
docs/search/field.md | 3 +
docs/search/fields.md | 5 +
docs/search/fuzziness.md | 9 +
docs/search/geometries.md | 12 +
docs/search/geometry.md | 3 +
docs/search/highlight.md | 10 +
docs/search/includeLocations.md | 5 +
docs/search/inclusive_end.md | 7 +
docs/search/inclusive_max.md | 7 +
docs/search/inclusive_min.md | 7 +
docs/search/inclusive_start.md | 7 +
docs/search/k.md | 7 +
docs/search/knn.md | 6 +
docs/search/lat.md | 1 +
docs/search/level.md | 7 +
docs/search/limit.md | 5 +
docs/search/location.md | 11 +
docs/search/lon.md | 1 +
docs/search/match.md | 9 +
docs/search/match_all.md | 3 +
docs/search/match_none.md | 5 +
docs/search/match_phrase.md | 9 +
docs/search/max.md | 7 +
docs/search/min.md | 7 +
docs/search/must.md | 7 +
docs/search/must_not.md | 7 +
docs/search/offset.md | 7 +
docs/search/operator.md | 11 +
docs/search/polygon_points.md | 9 +
docs/search/prefix.md | 9 +
docs/search/prefix_lang.md | 5 +
docs/search/query.md | 5 +
docs/search/query_string.md | 11 +
docs/search/radius.md | 16 +
docs/search/regexp.md | 7 +
docs/search/relation.md | 9 +
docs/search/results.md | 5 +
docs/search/score.md | 5 +
docs/search/search_after.md | 13 +
docs/search/search_before.md | 13 +
docs/search/shape.md | 3 +
docs/search/should.md | 7 +
docs/search/sort.md | 11 +
docs/search/start.md | 7 +
docs/search/style.md | 7 +
docs/search/term.md | 9 +
docs/search/terms.md | 11 +
docs/search/timeout.md | 3 +
docs/search/top_left.md | 11 +
docs/search/type_facet.md | 7 +
docs/search/type_shape.md | 21 +
docs/search/vector.md | 7 +
docs/search/vectors.md | 3 +
docs/search/wildcard.md | 15 +
package-lock.json | 1928 +++++++++++++++--
package.json | 41 +-
.../contributor/autoComplete.ts | 11 +
.../contributor/autoCompleteVisitor.ts | 292 +++
.../contributor/booleanCbsContributor.ts | 23 +
.../contributor/cbsTemplateDef.ts | 11 +
.../contributor/cbsTemplates.ts | 279 +++
.../contributor/consistencyCbsContributor.ts | 27 +
.../contributor/ctlCbsContributor.ts | 21 +
.../contributor/fieldsContributor.ts | 88 +
.../contributor/geometryCbsContributor.ts | 24 +
.../contributor/highlightCbsContributor.ts | 24 +
.../contributor/knnCbsContributor.ts | 26 +
.../contributor/locationCbsContributor.ts | 21 +
.../contributor/queryCbsContributor.ts | 253 +++
.../contributor/shapeCbsContributor.ts | 76 +
.../documentation/documentationProvider.ts | 279 +++
.../indexParser/indexParser.ts | 62 +
.../fts/SearchWorkbench/openSearchIndex.ts | 1 +
.../fts/SearchWorkbench/searchWorkbench.ts | 14 +-
.../test/queryTypeObject.test.ts | 2 +-
.../validators/geometryObjectValidator.ts | 18 +-
.../validators/queryTypeObjectValidator.ts | 108 +-
.../validators/shapeObjectValidator.ts | 94 +-
.../validators/validationUtil.ts | 3 +-
src/extension.ts | 55 +-
.../handleSearchQueryContextStatusBar.ts | 2 +-
src/model/ScopeNode.ts | 3 +
src/pages/queryContext/queryContext.ts | 2 +-
src/reactViews/app/bootstrap.tsx | 11 +-
.../contributor/cbsCtlCodeCompletion.test.ts | 149 ++
.../cbsGeometryCodeCompletion.test.ts | 70 +
.../cbsHighlightCodeCompletion.test.ts | 77 +
.../contributor/cbsKnnCodeCompletion.test.ts | 62 +
.../cbsQueryCodeCompletion.test.ts | 446 ++++
.../contributor/cbsRootCodeCompletion.test.ts | 77 +
.../cbsShapeCodeCompletion.test.ts | 118 +
src/test/runTest.ts | 35 +-
src/test/suite/index.ts | 28 +-
src/util/cacheService/cacheService.ts | 24 +-
src/util/common.ts | 7 +
src/util/connections.ts | 3 +-
src/workbench/queryWorkbench.ts | 6 +-
src/workbench/workbenchWebviewProvider.ts | 20 +-
114 files changed, 5287 insertions(+), 278 deletions(-)
create mode 100644 __mocks__/vscode.js
create mode 100644 docs/search/analyzer.md
create mode 100644 docs/search/bool.md
create mode 100644 docs/search/boost.md
create mode 100644 docs/search/bottom_right.md
create mode 100644 docs/search/cidr.md
create mode 100644 docs/search/collections.md
create mode 100644 docs/search/conjuncts.md
create mode 100644 docs/search/consistency.md
create mode 100644 docs/search/coordinates.md
create mode 100644 docs/search/ctl.md
create mode 100644 docs/search/disjuncts.md
create mode 100644 docs/search/distance.md
create mode 100644 docs/search/end.md
create mode 100644 docs/search/explain.md
create mode 100644 docs/search/facets.md
create mode 100644 docs/search/field.md
create mode 100644 docs/search/fields.md
create mode 100644 docs/search/fuzziness.md
create mode 100644 docs/search/geometries.md
create mode 100644 docs/search/geometry.md
create mode 100644 docs/search/highlight.md
create mode 100644 docs/search/includeLocations.md
create mode 100644 docs/search/inclusive_end.md
create mode 100644 docs/search/inclusive_max.md
create mode 100644 docs/search/inclusive_min.md
create mode 100644 docs/search/inclusive_start.md
create mode 100644 docs/search/k.md
create mode 100644 docs/search/knn.md
create mode 100644 docs/search/lat.md
create mode 100644 docs/search/level.md
create mode 100644 docs/search/limit.md
create mode 100644 docs/search/location.md
create mode 100644 docs/search/lon.md
create mode 100644 docs/search/match.md
create mode 100644 docs/search/match_all.md
create mode 100644 docs/search/match_none.md
create mode 100644 docs/search/match_phrase.md
create mode 100644 docs/search/max.md
create mode 100644 docs/search/min.md
create mode 100644 docs/search/must.md
create mode 100644 docs/search/must_not.md
create mode 100644 docs/search/offset.md
create mode 100644 docs/search/operator.md
create mode 100644 docs/search/polygon_points.md
create mode 100644 docs/search/prefix.md
create mode 100644 docs/search/prefix_lang.md
create mode 100644 docs/search/query.md
create mode 100644 docs/search/query_string.md
create mode 100644 docs/search/radius.md
create mode 100644 docs/search/regexp.md
create mode 100644 docs/search/relation.md
create mode 100644 docs/search/results.md
create mode 100644 docs/search/score.md
create mode 100644 docs/search/search_after.md
create mode 100644 docs/search/search_before.md
create mode 100644 docs/search/shape.md
create mode 100644 docs/search/should.md
create mode 100644 docs/search/sort.md
create mode 100644 docs/search/start.md
create mode 100644 docs/search/style.md
create mode 100644 docs/search/term.md
create mode 100644 docs/search/terms.md
create mode 100644 docs/search/timeout.md
create mode 100644 docs/search/top_left.md
create mode 100644 docs/search/type_facet.md
create mode 100644 docs/search/type_shape.md
create mode 100644 docs/search/vector.md
create mode 100644 docs/search/vectors.md
create mode 100644 docs/search/wildcard.md
create mode 100644 src/commands/fts/SearchWorkbench/contributor/autoComplete.ts
create mode 100644 src/commands/fts/SearchWorkbench/contributor/autoCompleteVisitor.ts
create mode 100644 src/commands/fts/SearchWorkbench/contributor/booleanCbsContributor.ts
create mode 100644 src/commands/fts/SearchWorkbench/contributor/cbsTemplateDef.ts
create mode 100644 src/commands/fts/SearchWorkbench/contributor/cbsTemplates.ts
create mode 100644 src/commands/fts/SearchWorkbench/contributor/consistencyCbsContributor.ts
create mode 100644 src/commands/fts/SearchWorkbench/contributor/ctlCbsContributor.ts
create mode 100644 src/commands/fts/SearchWorkbench/contributor/fieldsContributor.ts
create mode 100644 src/commands/fts/SearchWorkbench/contributor/geometryCbsContributor.ts
create mode 100644 src/commands/fts/SearchWorkbench/contributor/highlightCbsContributor.ts
create mode 100644 src/commands/fts/SearchWorkbench/contributor/knnCbsContributor.ts
create mode 100644 src/commands/fts/SearchWorkbench/contributor/locationCbsContributor.ts
create mode 100644 src/commands/fts/SearchWorkbench/contributor/queryCbsContributor.ts
create mode 100644 src/commands/fts/SearchWorkbench/contributor/shapeCbsContributor.ts
create mode 100644 src/commands/fts/SearchWorkbench/documentation/documentationProvider.ts
create mode 100644 src/commands/fts/SearchWorkbench/indexParser/indexParser.ts
create mode 100644 src/test/contributor/cbsCtlCodeCompletion.test.ts
create mode 100644 src/test/contributor/cbsGeometryCodeCompletion.test.ts
create mode 100644 src/test/contributor/cbsHighlightCodeCompletion.test.ts
create mode 100644 src/test/contributor/cbsKnnCodeCompletion.test.ts
create mode 100644 src/test/contributor/cbsQueryCodeCompletion.test.ts
create mode 100644 src/test/contributor/cbsRootCodeCompletion.test.ts
create mode 100644 src/test/contributor/cbsShapeCodeCompletion.test.ts
diff --git a/__mocks__/vscode.js b/__mocks__/vscode.js
new file mode 100644
index 00000000..5e23aea0
--- /dev/null
+++ b/__mocks__/vscode.js
@@ -0,0 +1,55 @@
+// __mocks__/vscode.js
+
+const vscode = {
+ languages: {
+ createDiagnosticCollection: jest.fn().mockImplementation(() => {
+ const diagnosticsMap = new Map();
+ return {
+ clear: jest.fn(() => diagnosticsMap.clear()),
+ dispose: jest.fn(),
+ get: jest.fn(uri => diagnosticsMap.get(uri.toString())),
+ set: jest.fn((uri, diagnostics) => diagnosticsMap.set(uri.toString(), diagnostics)),
+ delete: jest.fn(uri => diagnosticsMap.delete(uri.toString())),
+ forEach: jest.fn(callback => diagnosticsMap.forEach(callback)),
+ };
+ }),
+ },
+ Uri: {
+ parse: jest.fn().mockImplementation((str) => ({
+ toString: () => str,
+ })),
+ },
+ workspace: {
+ openTextDocument: jest.fn().mockImplementation((uri) => ({
+ getText: jest.fn(() => ''),
+ uri: uri,
+ positionAt: jest.fn().mockImplementation((index) => {
+ return new vscode.Position(Math.floor(index / 100), index % 100);
+ }),
+ })),
+ fs: {
+ writeFile: jest.fn(),
+ }
+ },
+ Range: jest.fn().mockImplementation((start, end) => ({
+ start: start,
+ end: end
+ })),
+ Position: jest.fn().mockImplementation((line, character) => ({
+ line: line,
+ character: character
+ })),
+ Diagnostic: jest.fn().mockImplementation((range, message, severity) => ({
+ range: range,
+ message: message,
+ severity: severity
+ })),
+ DiagnosticSeverity: {
+ Error: 0,
+ Warning: 1,
+ Information: 2,
+ Hint: 3
+ }
+};
+
+module.exports = vscode;
\ No newline at end of file
diff --git a/docs/search/analyzer.md b/docs/search/analyzer.md
new file mode 100644
index 00000000..a9dee9b7
--- /dev/null
+++ b/docs/search/analyzer.md
@@ -0,0 +1,7 @@
+Use the **analyzer** property to modify the behavior of a match query or a match phrase query.
+
+Set the **analyzer** property to the name of the analyzer you want to use on the contents of the match property or match_phrase property.
+
+The specified analyzer only applies to the content of your Search request. It does not apply to the contents of documents in the Search index. However, the analyzer set on your Search request and in your Search index should match.
+
+→ [Additional Query Object Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#additional-query-properties)
\ No newline at end of file
diff --git a/docs/search/bool.md b/docs/search/bool.md
new file mode 100644
index 00000000..fb735fad
--- /dev/null
+++ b/docs/search/bool.md
@@ -0,0 +1,7 @@
+Use the **bool** property to query a field that contains a boolean value.
+
+Use the field property and set the **bool** property to true or false to run a search.
+
+The Search Service does not use any analyzers on the contents of your query.
+
+→ [Non-Analytics Query Documentation]("https://docs.couchbase.com/server/current/search/search-request-params.html#non-analytic-queries")
\ No newline at end of file
diff --git a/docs/search/boost.md b/docs/search/boost.md
new file mode 100644
index 00000000..440f2cdf
--- /dev/null
+++ b/docs/search/boost.md
@@ -0,0 +1,5 @@
+If you use multiple clauses in a query, you can use the **boost** property to assign the relative importance to a clause.
+
+Clauses with a higher value in the **boost** property score higher and appear earlier in search results.
+
+→ [Additional Query Object Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#additional-query-properties)
\ No newline at end of file
diff --git a/docs/search/bottom_right.md b/docs/search/bottom_right.md
new file mode 100644
index 00000000..6af33a3f
--- /dev/null
+++ b/docs/search/bottom_right.md
@@ -0,0 +1,11 @@
+Set the geo location value to use as the bottom-right corner point of the rectangle search area.
+
+If you use **bottom_right** as an object, you must set two values:
+
+→ **lon**: The longitude of the geo location to use as the bottom-right corner of the rectangle.
+
+→ **lat**: The latitude of the geo location to use as the bottom-right corner of the rectangle.
+
+If you use **bottom_right** as an array, your array must contain a longitude value followed by a latitude value. For example, [-2.235143, 53.482358], where -2.235143 is the longitude.
+
+→ [Rectangle-Based Geopoint Query Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#geopoint-queries-rectangle)
\ No newline at end of file
diff --git a/docs/search/cidr.md b/docs/search/cidr.md
new file mode 100644
index 00000000..cd627d51
--- /dev/null
+++ b/docs/search/cidr.md
@@ -0,0 +1,5 @@
+Enter an IP address range or single IP address, in IPv4 or IPv6 CIDR notation.
+
+The Search Service returns documents with IP addresses that fall inside the specified range or match the specified IP address.
+
+→ [IP Address Range Query Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#ip-address-range-queries)
\ No newline at end of file
diff --git a/docs/search/collections.md b/docs/search/collections.md
new file mode 100644
index 00000000..e15d5592
--- /dev/null
+++ b/docs/search/collections.md
@@ -0,0 +1,3 @@
+Contains an array of strings that specify the collections where you want to run the query.
+
+→ [Search Request Json Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html)
\ No newline at end of file
diff --git a/docs/search/conjuncts.md b/docs/search/conjuncts.md
new file mode 100644
index 00000000..f5744643
--- /dev/null
+++ b/docs/search/conjuncts.md
@@ -0,0 +1,9 @@
+Use the **conjuncts** array to specify multiple child queries in a single query object.
+
+You can use the **conjuncts** array inside a must object or directly inside a query object.
+
+If you use the **conjuncts** array, every query object in the array must have a match in a document to include the document in search results.
+
+You can create objects in a **conjuncts** array to describe any of the available query types.
+
+→ [Compound Query Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#boolean-queries)
\ No newline at end of file
diff --git a/docs/search/consistency.md b/docs/search/consistency.md
new file mode 100644
index 00000000..2ee1f1de
--- /dev/null
+++ b/docs/search/consistency.md
@@ -0,0 +1,5 @@
+Use the **consistency** object to control the consistency behavior for a Search index
+
+It contains a **vectors** object, the **level** and **results** properties.
+
+→ [Consistency Object Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#consistency)
\ No newline at end of file
diff --git a/docs/search/coordinates.md b/docs/search/coordinates.md
new file mode 100644
index 00000000..b0ab0191
--- /dev/null
+++ b/docs/search/coordinates.md
@@ -0,0 +1,72 @@
+An array of coordinate floating point values that define the GeoJSON shape.
+
+The Search Service uses the first value in the coordinates array as the longitude value.
+
+#### Point Query
+For a **Point** query, set the **coordinates** array to a single array with a longitude and latitude value
+
+#### LineString Query
+For a **LineString** query, the **coordinates** array can contain multiple coordinate point arrays.
+
+#### Polygon Query
+
+An array that contains an outer array, and arrays of 2 coordinate floating point values that define the GeoJSON Polygon shape.
+
+The Search Service uses the first value in any nested **coordinates** array as the longitude value for the coordinate.
+
+The Search Service also follows strict GeoJSON syntax, and expects exterior coordinates in a polygon to be in counterclockwise order.
+
+#### MultiPoint Query
+An array that contains arrays of 2 coordinate floating point values that define the GeoJSON MultiPoint shape.
+
+#### MultiLineString Query
+
+An array that contains nested arrays, each with their own nested arrays of 2 coordinate floating point values.
+
+For example, the following coordinates array defines 2 LineStrings with start and end points:
+"coordinates": [
+[
+[1.954764, 50.962097], [3.029578, 49.868547]
+],
+[
+[3.029578, 49.868547], [-0.387444, 48.545836]
+]
+]
+The innermost arrays define the individual points for a LineString in the MultiLineString shape.
+
+#### MultiPolygon Query
+An array that contains arrays that describe a GeoJSON Polygon shape.
+
+Each inner array that describes a Polygon can contain multiple arrays with 2 coordinate floating point values. These innermost arrays describe the coordinates of the Polygon.
+
+The Search Service also follows strict GeoJSON syntax, and expects exterior coordinates in a polygon to be in counterclockwise order
+
+#### GeometryCollection Query
+
+An array or array of arrays that describes a GeoJSON shape.
+
+The exact structure of the arrays depends on the shape:
+
+→ Point
+→ LineString
+→ Polygon
+→ MultiPoint
+→ MultiLineString
+→ MultiPolygon
+
+For any array that contains only floating point values, the Search Service uses the first value as the longitude.
+
+The Search Service also follows strict GeoJSON syntax, and expects exterior coordinates in a polygon to be in counterclockwise order.
+
+#### Circle Query
+An array of coordinate floating point values that define the center point of the Circle.
+
+Set the **coordinates** array to a single array with a longitude and latitude value.
+
+#### Envelope Query
+
+An array of 2 different arrays that contain coordinate floating point values.
+
+The first **coordinates** nested array contains the minimum longitude and maximum latitude, or the top-left corner of the rectangle.
+
+The second nested array contains the maximum longitude and minimum latitude, or the bottom-right corner.
\ No newline at end of file
diff --git a/docs/search/ctl.md b/docs/search/ctl.md
new file mode 100644
index 00000000..0afa444f
--- /dev/null
+++ b/docs/search/ctl.md
@@ -0,0 +1,5 @@
+Use the **ctl** object to make sure that the Search Service runs your Search query against the latest version of the documents in your database.
+
+The **ctl** object and its properties cause the Search Service to run your query against the latest version of a document written to a vBucket. The Search Service uses a consistency vector to synchronize the last document write to a vBucket from the Data Service with the Search index.
+
+→ [Ctl Object Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#ctl)
\ No newline at end of file
diff --git a/docs/search/disjuncts.md b/docs/search/disjuncts.md
new file mode 100644
index 00000000..46df2697
--- /dev/null
+++ b/docs/search/disjuncts.md
@@ -0,0 +1,9 @@
+Use the **disjuncts** array to specify multiple child queries in a single query object.
+
+You can use the **disjuncts** array inside a must_not object, should object, or directly inside a query object.
+
+Use a min property to set the number of query objects from the **disjuncts** array that must have a match in a document. If a document does not match the min number of query objects, the Search Service does not include the document in search results.
+
+You can create objects in a **disjuncts** array to describe any of the available query types.
+
+→ [Compound Query Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#boolean-queries)
\ No newline at end of file
diff --git a/docs/search/distance.md b/docs/search/distance.md
new file mode 100644
index 00000000..59c0783e
--- /dev/null
+++ b/docs/search/distance.md
@@ -0,0 +1,16 @@
+The radius where the Search Service should search for matching geo location values.
+
+Enter the radius as a single string, with a numeric value and a unit value. For example, 100.5mi.
+
+You can use the following distance units:
+
+→ **mm:** Millimeters
+→ **cm:** Centimeters
+→ **in:** Inches
+→ **yd:** Yards
+→ **ft:** Feet
+→ **m:** Meters
+→ **km:** Kilometers
+→ **mi:** Miles
+
+→ [Distance/Radius-Based Geopoint Query Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#geopoint-queries-distance)
\ No newline at end of file
diff --git a/docs/search/end.md b/docs/search/end.md
new file mode 100644
index 00000000..1a454df1
--- /dev/null
+++ b/docs/search/end.md
@@ -0,0 +1,7 @@
+Set the end date of the date range that you want to search for.
+
+You can specify only an **end** value or only a **start** value on your date range.
+
+By default, **end** is exclusive to the range.
+
+→ [Date Range Query Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#date-range-queries)
\ No newline at end of file
diff --git a/docs/search/explain.md b/docs/search/explain.md
new file mode 100644
index 00000000..e7670e97
--- /dev/null
+++ b/docs/search/explain.md
@@ -0,0 +1,5 @@
+To create an explanation for a search result's score in search results, set **explain** to true.
+
+To turn off explanations for search result scoring, set **explain** to false.
+
+→ [Search Request Json Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html)
\ No newline at end of file
diff --git a/docs/search/facets.md b/docs/search/facets.md
new file mode 100644
index 00000000..df5ba2c5
--- /dev/null
+++ b/docs/search/facets.md
@@ -0,0 +1,9 @@
+Contains **{facet-name}** objects to define each facet you want to return with search results.
+
+The Search Service supports the following facet types:
+
+→ **Term Facet**: Counts the documents that have the same value for a specified field.
+
+→ **Numeric Range Facet**: Counts the documents with numeric field values that are greater than or less than a specified range or ranges.
+
+→ **Date Range Facet**: Counts the documents with date field values that are earlier or later than a specified range or ranges.
\ No newline at end of file
diff --git a/docs/search/field.md b/docs/search/field.md
new file mode 100644
index 00000000..69a27d0d
--- /dev/null
+++ b/docs/search/field.md
@@ -0,0 +1,3 @@
+Specify a specific field name, using dot notation, where the Search Service should search for a match to your search query.
+
+→ [Additional Query Object Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#additional-query-properties)
\ No newline at end of file
diff --git a/docs/search/fields.md b/docs/search/fields.md
new file mode 100644
index 00000000..46634e2b
--- /dev/null
+++ b/docs/search/fields.md
@@ -0,0 +1,5 @@
+An array of strings to specify each indexed field you want to return in search results.
+
+You must add a field and its contents to a Search index to view it in search results or add it to the **fields** array.
+
+→ [Search Request Json Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html)
\ No newline at end of file
diff --git a/docs/search/fuzziness.md b/docs/search/fuzziness.md
new file mode 100644
index 00000000..64bd11d1
--- /dev/null
+++ b/docs/search/fuzziness.md
@@ -0,0 +1,9 @@
+Use the **fuzziness** property to run a fuzzy query.
+
+The **fuzziness** property uses your specified edit distance to match terms based on their similarity, rather than exact matches.
+
+You can set **fuzziness** to a maximum value of 2.
+
+Use the **fuzziness** property with the term property for a term query or the match property for a match query.
+
+→ [Additional Query Object Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#additional-query-properties)
\ No newline at end of file
diff --git a/docs/search/geometries.md b/docs/search/geometries.md
new file mode 100644
index 00000000..f5556304
--- /dev/null
+++ b/docs/search/geometries.md
@@ -0,0 +1,12 @@
+Contains objects to define each GeoJSON shape in the GeometryCollection.
+
+Each object in the **geometries** array has a **type** property and a coordinates property.
+
+Set the type property inside the object to the specific shape type you want to define:
+
+→ Point
+→ LineString
+→ Polygon
+→ MultiPoint
+→ MultiLineString
+→ MultiPolygon
\ No newline at end of file
diff --git a/docs/search/geometry.md b/docs/search/geometry.md
new file mode 100644
index 00000000..9ede0b5d
--- /dev/null
+++ b/docs/search/geometry.md
@@ -0,0 +1,3 @@
+Contains the **shape** property and **relation** property.
+
+Defines the GeoJSON shape and how the Search Service should find a match in documents.
\ No newline at end of file
diff --git a/docs/search/highlight.md b/docs/search/highlight.md
new file mode 100644
index 00000000..09386fd2
--- /dev/null
+++ b/docs/search/highlight.md
@@ -0,0 +1,10 @@
+Use the **highlight** object to control how the Search Service highlights matches in search results.
+
+```json
+"highlight": {
+ "style": "html",
+ "fields": ["textField"]
+},
+```
+
+→ [Highlight Object Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#highlight)
\ No newline at end of file
diff --git a/docs/search/includeLocations.md b/docs/search/includeLocations.md
new file mode 100644
index 00000000..88730c08
--- /dev/null
+++ b/docs/search/includeLocations.md
@@ -0,0 +1,5 @@
+To return the position of each occurrence of a search term inside a document, set **includeLocations** to true.
+
+**Note**: You must have *Include Term Vectors* enabled or the **include_term_vectors** property set to true on a field to use **includeLocations**. For more information about how to enable term vectors, see Child Field Options or Search Index JSON Properties.
+
+→ [Search Request Json Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html)
\ No newline at end of file
diff --git a/docs/search/inclusive_end.md b/docs/search/inclusive_end.md
new file mode 100644
index 00000000..20563257
--- /dev/null
+++ b/docs/search/inclusive_end.md
@@ -0,0 +1,7 @@
+Set whether the Search Service should return documents that contain the exact **end** value.
+
+If you set **inclusive_end** to false, only dates earlier than end count as a match to your Search query.
+
+If you do not set the **inclusive_end** value, by default, **end** is exclusive to the range.
+
+→ [Date Range Query Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#date-range-queries)
\ No newline at end of file
diff --git a/docs/search/inclusive_max.md b/docs/search/inclusive_max.md
new file mode 100644
index 00000000..59e7bf4f
--- /dev/null
+++ b/docs/search/inclusive_max.md
@@ -0,0 +1,7 @@
+Set whether the Search Service should return documents that contain the exact **max** value.
+
+If you set **inclusive_max** to false, only values less than **max** count as a match to your Search query.
+
+If you do not set the **inclusive_max** value, by default, **max** is exclusive to the range.
+
+→ [Numeric Range Query Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#numeric-range-queries)
\ No newline at end of file
diff --git a/docs/search/inclusive_min.md b/docs/search/inclusive_min.md
new file mode 100644
index 00000000..51200adc
--- /dev/null
+++ b/docs/search/inclusive_min.md
@@ -0,0 +1,7 @@
+Set whether the Search Service should return documents that contain the exact **min** value.
+
+If you set **inclusive_min** to false, only values greater than min count as a match to your Search query.
+
+If you do not set the **inclusive_min** value, by default, **min** is inclusive to the range.
+
+→ [Numeric Range Query Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#numeric-range-queries)
\ No newline at end of file
diff --git a/docs/search/inclusive_start.md b/docs/search/inclusive_start.md
new file mode 100644
index 00000000..24f61036
--- /dev/null
+++ b/docs/search/inclusive_start.md
@@ -0,0 +1,7 @@
+Set whether the Search Service should return documents that contain the exact **start** value.
+
+If you set **inclusive_start** to false, only dates later than start count as a match to your Search query.
+
+If you do not set the **inclusive_start** value, by default, **start** is inclusive to the range.
+
+→ [Date Range Query Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#date-range-queries)
\ No newline at end of file
diff --git a/docs/search/k.md b/docs/search/k.md
new file mode 100644
index 00000000..0283cba6
--- /dev/null
+++ b/docs/search/k.md
@@ -0,0 +1,7 @@
+Enter the total number of results that you want to return from your Vector Search query.
+
+The Search Service returns the **k** closest vectors to the vector given in vector.
+
+**NOTE:** The **size** or **limit** property overrides any value set in **k**.
+
+→ [Knn Object Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#knn-object)
\ No newline at end of file
diff --git a/docs/search/knn.md b/docs/search/knn.md
new file mode 100644
index 00000000..2114fa4b
--- /dev/null
+++ b/docs/search/knn.md
@@ -0,0 +1,6 @@
+Each object inside the knn array in a Search query describes a Vector Search query.
+Add the knn array with at least one object to run a Vector Search query
+
+**NOTE:** To run a Vector Search query, you must still include a **query** object with your Search request. To return only results from your Vector Search query, you can set the query object to a **match_none** query. To run a hybrid query that uses regular Search Service parameters together with Vector Search to return results
+
+→ [Knn Object Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#knn-object)
\ No newline at end of file
diff --git a/docs/search/lat.md b/docs/search/lat.md
new file mode 100644
index 00000000..89594cf2
--- /dev/null
+++ b/docs/search/lat.md
@@ -0,0 +1 @@
+The latitude of the geo location
\ No newline at end of file
diff --git a/docs/search/level.md b/docs/search/level.md
new file mode 100644
index 00000000..b955268c
--- /dev/null
+++ b/docs/search/level.md
@@ -0,0 +1,7 @@
+Set the consistency to bounded or unbounded consistency:
+
+→ **at_plus**: The Search query executes but requires that the Search index matches the timestamp of the last document update. You must provide a **vectors** object
+
+→ **not_bounded**: The Search query executes without a consistency requirement. **not_bounded** is faster than **at_plus**, as it doesn't rely on a **vectors** object or wait for the Search index to match the Data Service index.
+
+→ [Consistency Object Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#consistency)
\ No newline at end of file
diff --git a/docs/search/limit.md b/docs/search/limit.md
new file mode 100644
index 00000000..818f1808
--- /dev/null
+++ b/docs/search/limit.md
@@ -0,0 +1,5 @@
+Set the total number of results to return for a single page of search results.
+
+If you provide both the **size** and **limit** properties, the Search Service uses the **size** value.
+
+→ [Search Request Json Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html)
\ No newline at end of file
diff --git a/docs/search/location.md b/docs/search/location.md
new file mode 100644
index 00000000..7bd86d4e
--- /dev/null
+++ b/docs/search/location.md
@@ -0,0 +1,11 @@
+Set the geo location value to use as the center of the search radius for your query.
+
+If you use **location** as an object, you must set two values:
+
+→ **lon**: The longitude of the geo location to use as the center of the search radius.
+
+→ **lat**: The latitude of the geo location to use as the center of the search radius.
+
+If you use **location** as an array, your array must contain a longitude value followed by a latitude value. For example, [-2.235143, 53.482358], where -2.235143 is the longitude.
+
+→ [Distance/Radius-Based Geopoint Query Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#geopoint-queries-distance)
\ No newline at end of file
diff --git a/docs/search/lon.md b/docs/search/lon.md
new file mode 100644
index 00000000..6fc0a534
--- /dev/null
+++ b/docs/search/lon.md
@@ -0,0 +1 @@
+The longitude of the geo location
\ No newline at end of file
diff --git a/docs/search/match.md b/docs/search/match.md
new file mode 100644
index 00000000..ce9d4cdc
--- /dev/null
+++ b/docs/search/match.md
@@ -0,0 +1,9 @@
+Use the **match** property to run a match query. The Search Service searches for an exact match to the specified term inside the Search index's default field.
+
+You can set a specific field to search with the field property.
+
+You can change the matching behavior by using the fuzziness property.
+
+You cannot include spaces inside the string you provide to the **match** property without specifying the operator property, which tells the Search Service how to interpret the string.
+
+→ [Analytics Query Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#analytic-queries)
\ No newline at end of file
diff --git a/docs/search/match_all.md b/docs/search/match_all.md
new file mode 100644
index 00000000..6655b017
--- /dev/null
+++ b/docs/search/match_all.md
@@ -0,0 +1,3 @@
+Use the **match_all** object as the only property in your **query** object to return all documents from the Search index in search results.
+
+→ [Special Queries Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#special-queries)
\ No newline at end of file
diff --git a/docs/search/match_none.md b/docs/search/match_none.md
new file mode 100644
index 00000000..9a465574
--- /dev/null
+++ b/docs/search/match_none.md
@@ -0,0 +1,5 @@
+Use the **match_none** object as the only property in your **query** object to return no documents from the Search index in search results.
+
+If you're using the knn object, the **match_none** object returns only matches to the Vector Search query inside the knn object.
+
+→ [Special Queries Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#special-queries)
\ No newline at end of file
diff --git a/docs/search/match_phrase.md b/docs/search/match_phrase.md
new file mode 100644
index 00000000..99df16b3
--- /dev/null
+++ b/docs/search/match_phrase.md
@@ -0,0 +1,9 @@
+Use the **match_phrase** property to run a match phrase query. The Search Service searches for exact matches to the phrase you specify.
+
+Unlike a **match** query string, a **match_phrase** query string can contain spaces without using the operator property.
+
+To use a match phrase query:
+→ You must specify a field to search with the field property or the {field-name} syntax in your search query.
+→ You must have Include Term Vectors enabled or the include_term_vectors property set to true on the field you want to search.
+
+→ [Analytics Query Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#analytic-queries)
\ No newline at end of file
diff --git a/docs/search/max.md b/docs/search/max.md
new file mode 100644
index 00000000..f65e4139
--- /dev/null
+++ b/docs/search/max.md
@@ -0,0 +1,7 @@
+Set the maximum value of the range that you want to search for.
+
+You can specify only a **min** value or only a **max** value on your range.
+
+By default, **max** is exclusive to the range.
+
+→ [Numeric Range Query Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#numeric-range-queries)
\ No newline at end of file
diff --git a/docs/search/min.md b/docs/search/min.md
new file mode 100644
index 00000000..d6afa93a
--- /dev/null
+++ b/docs/search/min.md
@@ -0,0 +1,7 @@
+Set the minimum value of the range that you want to search for.
+
+You can specify only a **min** value or only a max value on your range.
+
+By default, **min** is inclusive to the range.
+
+→ [Numeric Range Query Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#numeric-range-queries)
\ No newline at end of file
diff --git a/docs/search/must.md b/docs/search/must.md
new file mode 100644
index 00000000..414ed719
--- /dev/null
+++ b/docs/search/must.md
@@ -0,0 +1,7 @@
+Use a **must** object to create a boolean query.
+
+A **must** object must contain a conjuncts array. The array lists all the queries that must have a match in a document to include the document in search results.
+
+For example, a query could have a **must** object with 2 queries in a conjuncts array. The Search Service must find a match for both those queries in a document to include it in search results.
+
+→ [Boolean Query Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#boolean-queries)
\ No newline at end of file
diff --git a/docs/search/must_not.md b/docs/search/must_not.md
new file mode 100644
index 00000000..684edbd3
--- /dev/null
+++ b/docs/search/must_not.md
@@ -0,0 +1,7 @@
+Use a **must_not** object to create a boolean query.
+
+A **must_not** object must contain a disjuncts array. The array lists all the queries that must have a match in a document to include the document in search results.
+
+For example, a query could have a **must_not** object with 3 queries in a disjuncts array. The Search Service must not find a match for any of the 3 queries in a document to include it in search results.
+
+→ [Boolean Query Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#boolean-queries)
\ No newline at end of file
diff --git a/docs/search/offset.md b/docs/search/offset.md
new file mode 100644
index 00000000..8e354c4f
--- /dev/null
+++ b/docs/search/offset.md
@@ -0,0 +1,7 @@
+Set an offset value to change where pagination starts for search results, based on the Search query's Sort Object.
+
+For example, if you set a **size** value of 5 and a **from** value of 10, the Search query returns results 11 through 15 on a page.
+
+If you provide both the **from** and **offset** properties, the Search Service uses the **from** value.
+
+→ [Search Request Json Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html)
\ No newline at end of file
diff --git a/docs/search/operator.md b/docs/search/operator.md
new file mode 100644
index 00000000..21ddf90b
--- /dev/null
+++ b/docs/search/operator.md
@@ -0,0 +1,11 @@
+Use the **operator** property to modify the behavior of a match query:
+
+→ **"and"**: Any spaces between terms in the match property are interpreted as the AND operator. Documents must match all of the terms in the query.
+
+→ **"or"**: Any spaces between terms in the match property are interpreted as the OR operator. Documents must match at least one of the terms in the query.
+
+For example, if you set a **match** property to the value "good great" and the **operator** property to "and", the Search Service only returns matches for documents that contain good and great.
+
+If you set the **operator** property to "or", a document only needs to contain one of the terms from the **match** property: good or great.
+
+→ [Additional Query Object Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#additional-query-properties)
\ No newline at end of file
diff --git a/docs/search/polygon_points.md b/docs/search/polygon_points.md
new file mode 100644
index 00000000..3e188613
--- /dev/null
+++ b/docs/search/polygon_points.md
@@ -0,0 +1,9 @@
+Set an array of latitude and longitude string values to use as the points in your polygon search area.
+
+For example, an array of [ "37.79393211306212,-122.44234633404847", "37.77995881733997,-122.43977141339417", "37.788031092020155,-122.42925715405579"] is interpreted as 3 separate polygon points and creates a 3-sided polygon.
+
+For **polygon_points**, the first value in the string is the latitude, and the second is the longitude.
+
+You can set the last value in the array to the same value as the first latitude and longitude to explicitly close your polygon. Otherwise, the Search Service infers the polygon's closure.
+
+→ [Polygon-Based Geopoint Query Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#geopoint-queries-polygon)
\ No newline at end of file
diff --git a/docs/search/prefix.md b/docs/search/prefix.md
new file mode 100644
index 00000000..e7b86fc7
--- /dev/null
+++ b/docs/search/prefix.md
@@ -0,0 +1,9 @@
+Use the **prefix** property to run a prefix query.
+
+Set the property to a string to return matches for any term that starts with that string in search results.
+
+For example, you could set the **prefix** property to "inter" to return matches for "interview", "internal", "interesting", and so on.
+
+If you use the prefix property, the Search Service does not use any analyzers on the contents of your query text.
+
+→ [Non-Analytics Query Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#non-analytic-queries)
\ No newline at end of file
diff --git a/docs/search/prefix_lang.md b/docs/search/prefix_lang.md
new file mode 100644
index 00000000..8d6c13db
--- /dev/null
+++ b/docs/search/prefix_lang.md
@@ -0,0 +1,5 @@
+Use the **prefix_length** property to modify the behavior of a match query.
+
+The **prefix_length** changes a match query to a prefix match query. The Search Service matches terms based on the query and the result sharing a prefix of the specified length.
+
+→ [Additional Query Object Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#additional-query-properties)
\ No newline at end of file
diff --git a/docs/search/query.md b/docs/search/query.md
new file mode 100644
index 00000000..6f2442bc
--- /dev/null
+++ b/docs/search/query.md
@@ -0,0 +1,5 @@
+Use the **query** object to set the specific details of your Search query.
+
+Use the properties in the **query** object to control search result rankings, add multiple subqueries, and more.
+
+→ [Query Object Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#query-object)
\ No newline at end of file
diff --git a/docs/search/query_string.md b/docs/search/query_string.md
new file mode 100644
index 00000000..07ca8e16
--- /dev/null
+++ b/docs/search/query_string.md
@@ -0,0 +1,11 @@
+Query String queries let you express more complex queries with a special syntax. You can reduce the properties you need to specify for a Search query with Query String syntax.
+
+If you do not add any additional Query String syntax to a query, the Search Service interprets the query as a match query.
+
+- **^** : If you use multiple clauses in a query, you can use the ^ operator to assign the relative importance to a clause.
+- **>, >=, < and ≤** : You can run two types of range queries with the later than (>), later than or equal to (>=), earlier than (<), and earlier than or equal to (≤) operators:
+- **\\** : Use a backslash character (\\) to escape characters in a Query String query.
+- **{field-name}** : Set the field in a document where the Search Service should search for your query by adding a field name and a colon to the start of a search term. Use dot notation for the field name. For example, `parentField.childField`.
+- **+** and **-** : Use the + and - operators before a clause in a Query String query to run a boolean query. The + operator adds the clause to the MUST list of a boolean query. The - operator adds the clause to the MUST_NOT list of a boolean query.
+
+→ [Query String Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#query-string-query-syntax)
\ No newline at end of file
diff --git a/docs/search/radius.md b/docs/search/radius.md
new file mode 100644
index 00000000..491ed22d
--- /dev/null
+++ b/docs/search/radius.md
@@ -0,0 +1,16 @@
+Set the radius of the Circle.
+
+Enter the radius as a single string, with a numeric value and a unit value. For example, 100.5mi.
+
+You can use the following distance units:
+
+→ **mm:** Millimeters
+→ **cm:** Centimeters
+→ **in:** Inches
+→ **yd:** Yards
+→ **ft:** Feet
+→ **m:** Meters
+→ **km:** Kilometers
+→ **mi:** Miles
+
+→ [Circle GeoJSON Query Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#geojson-queries-circle)
\ No newline at end of file
diff --git a/docs/search/regexp.md b/docs/search/regexp.md
new file mode 100644
index 00000000..93fb33af
--- /dev/null
+++ b/docs/search/regexp.md
@@ -0,0 +1,7 @@
+Use the **regexp** property to run a regular expression query.
+
+Set the property to a regular expression to return matches for that regular expression in search results.
+
+If you use the **regexp** property, the Search Service does not use any analyzers on the contents of your query text.
+
+→ [Non-Analytics Query Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#non-analytic-queries)
\ No newline at end of file
diff --git a/docs/search/relation.md b/docs/search/relation.md
new file mode 100644
index 00000000..a1eac293
--- /dev/null
+++ b/docs/search/relation.md
@@ -0,0 +1,9 @@
+Set how the Search Service should return a match for a GeoJSON Point search.
+
+Your selected **relation** type determines which shapes return a match for your query.
+
+You can use the following string values in the **relation** property: **intersects**, **contains** and **within**
+
+These values have different meanings according to the shape. Please check docs for more.
+
+→ [Point GeoJSON Query Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#geojson-queries-point)
\ No newline at end of file
diff --git a/docs/search/results.md b/docs/search/results.md
new file mode 100644
index 00000000..345a179a
--- /dev/null
+++ b/docs/search/results.md
@@ -0,0 +1,5 @@
+To display an error instead of partial results if any index partitions are unavailable on a node, set **results** to **complete**.
+
+To return partial results from a query if a node is unreachable, remove the **results** property.
+
+→ [Consistency Object Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#consistency)
\ No newline at end of file
diff --git a/docs/search/score.md b/docs/search/score.md
new file mode 100644
index 00000000..d975f91b
--- /dev/null
+++ b/docs/search/score.md
@@ -0,0 +1,5 @@
+To turn off document relevancy scoring in search results, set **score** to none.
+
+To turn on document relevancy scoring in search results, remove the **score** property.
+
+→ [Search Request Json Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html)
\ No newline at end of file
diff --git a/docs/search/search_after.md b/docs/search/search_after.md
new file mode 100644
index 00000000..60540e87
--- /dev/null
+++ b/docs/search/search_after.md
@@ -0,0 +1,13 @@
+Use **search_after** with **from**/**offset** and sort to control pagination in search results.
+
+Give a value for each string or JSON object in the **sort** array to the **search_after** array. The Search Service starts search result pagination after the document with those values.
+
+You must provide the values in the same order that they appear in the **sort** array.
+
+For example, if you had a set of 10 documents to sort based on _id values of 1-10, with **from** set to 2 and **search_after** set to 8, documents 9-10 appear on the same page.
+
+---
+
+**Note**: If you use **search_after** in a search request, you can't use **search_before**. Both properties are included in the example code to show the correct syntax.
+
+→ [Search Request Json Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html)
\ No newline at end of file
diff --git a/docs/search/search_before.md b/docs/search/search_before.md
new file mode 100644
index 00000000..c3e80e84
--- /dev/null
+++ b/docs/search/search_before.md
@@ -0,0 +1,13 @@
+Use **search_before** with **from**/**offset** and sort to control pagination in search results.
+
+Give a value for each string or JSON object in the **sort** array to the **search_before** array. The Search Service starts search result pagination before the document with those values.
+
+You must provide the values in the same order that they appear in the **sort** array.
+
+For example, if you had a set of 10 documents to sort based on _id values of 1-10, with **from** set to 2 and **search_before** set to 8, documents 2-6 appear on the same page.
+
+---
+
+**Note**: If you use **search_before** in a search request, you can't use **search_after**. Both properties are included in the example code to show the correct syntax.
+
+→ [Search Request Json Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html)
\ No newline at end of file
diff --git a/docs/search/shape.md b/docs/search/shape.md
new file mode 100644
index 00000000..53762658
--- /dev/null
+++ b/docs/search/shape.md
@@ -0,0 +1,3 @@
+Contains the **type** property and **coordinates** property.
+
+Defines the specific GeoJSON shape to use in the query.
\ No newline at end of file
diff --git a/docs/search/should.md b/docs/search/should.md
new file mode 100644
index 00000000..6d00286c
--- /dev/null
+++ b/docs/search/should.md
@@ -0,0 +1,7 @@
+Use a **should** object to create a boolean query.
+
+A **should** object must contain a disjuncts array. The array lists all the queries that must have a match in a document to score the document higher in search results.
+
+A document can be included in search results if it does not match the query or queries in a **should** object. The document scores higher in search results if it does match the query.
+
+→ [Boolean Query Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#boolean-queries)
\ No newline at end of file
diff --git a/docs/search/sort.md b/docs/search/sort.md
new file mode 100644
index 00000000..0a3d9738
--- /dev/null
+++ b/docs/search/sort.md
@@ -0,0 +1,11 @@
+Contains an array of strings or JSON objects to set how to sort search results.
+
+The strings can be:
+
+→ **{field_name}**: Specify the name of a field to use to sort the search results.
+
+→ **_id**: Use the document's identifier to sort the search results.
+
+→ **_score**: Use the document's score from the Search query to sort the search results.
+
+→ [Sort Object Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#sort)
\ No newline at end of file
diff --git a/docs/search/start.md b/docs/search/start.md
new file mode 100644
index 00000000..5ba58f0c
--- /dev/null
+++ b/docs/search/start.md
@@ -0,0 +1,7 @@
+Set the start date of the date range that you want to search for.
+
+You can specify only a **start** value or only an **end** value on your date range.
+
+By default, **start** is inclusive to the range.
+
+→ [Date Range Query Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#date-range-queries)
\ No newline at end of file
diff --git a/docs/search/style.md b/docs/search/style.md
new file mode 100644
index 00000000..2b076263
--- /dev/null
+++ b/docs/search/style.md
@@ -0,0 +1,7 @@
+Sets how the Search Service highlights a match from a search query:
+
+→ **ansi**: The Search Service highlights matches with a yellow background (\u001b[43m).
+
+→ **html**: The Search Service surrounds matches with and HTML tags.
+
+→ [Highlight Object Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#highlight)
\ No newline at end of file
diff --git a/docs/search/term.md b/docs/search/term.md
new file mode 100644
index 00000000..51a52242
--- /dev/null
+++ b/docs/search/term.md
@@ -0,0 +1,9 @@
+Use the **term** property to run a term query.
+
+The Search Service searches for an exact match for the text you provide in the **term** property.
+
+You can change the matching behavior by using the fuzziness property.
+
+If you use the **term** property, the Search Service does not use any analyzers on the contents of your query text.
+
+→ [Non-Analytics Query Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#non-analytic-queries)
\ No newline at end of file
diff --git a/docs/search/terms.md b/docs/search/terms.md
new file mode 100644
index 00000000..526f3087
--- /dev/null
+++ b/docs/search/terms.md
@@ -0,0 +1,11 @@
+Use the **terms** array to run a phrase query. The Search Service searches for the strings you provide in the **terms** array in the specified order.
+
+Unlike the match_phrase property, the **terms** array does not use any analyzers on the contents of your query text.
+
+For example, set the **terms** array to ["nice", "view"]. The Search Service looks for any occurrences of nice in a document that are followed by an occurrence of view.
+
+To use a phrase query:
+→ You must set the field property in your search query.
+→ You must have Include Term Vectors enabled or the include_term_vectors property set to true on the field you want to search.
+
+→ [Non-Analytics Query Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#non-analytic-queries)
\ No newline at end of file
diff --git a/docs/search/timeout.md b/docs/search/timeout.md
new file mode 100644
index 00000000..73ad4c8e
--- /dev/null
+++ b/docs/search/timeout.md
@@ -0,0 +1,3 @@
+Set the maximum time, in milliseconds, that a Search query can execute on a Search index partition.
+
+If the query time exceeds the **timeout**, the Search Service cancels the query. The query might return partial results if any index partitions responded before the timeout.
\ No newline at end of file
diff --git a/docs/search/top_left.md b/docs/search/top_left.md
new file mode 100644
index 00000000..9827e272
--- /dev/null
+++ b/docs/search/top_left.md
@@ -0,0 +1,11 @@
+Set the geo location value to use as the top-left corner point of the rectangle search area.
+
+If you use **top_left** as an object, you must set two values:
+
+→ **lon**: The longitude of the geo location to use as the top-left corner of the rectangle.
+
+→ **lat**: The latitude of the geo location to use as the top-left corner of the rectangle.
+
+If you use **top_left** as an array, your array must contain a longitude value followed by a latitude value. For example, [-2.235143, 53.482358], where -2.235143 is the longitude.
+
+→ [Rectangle-Based Geopoint Query Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#geopoint-queries-rectangle)
\ No newline at end of file
diff --git a/docs/search/type_facet.md b/docs/search/type_facet.md
new file mode 100644
index 00000000..1c80c2ec
--- /dev/null
+++ b/docs/search/type_facet.md
@@ -0,0 +1,7 @@
+Set the data type of the field specified in field:
+
+→ **string**: The field contains a string.
+
+→ **date**: The field contains date/time data.
+
+→ **number**: The field contains a number or geographic data, like a latitude or longitude value.
\ No newline at end of file
diff --git a/docs/search/type_shape.md b/docs/search/type_shape.md
new file mode 100644
index 00000000..0fc570aa
--- /dev/null
+++ b/docs/search/type_shape.md
@@ -0,0 +1,21 @@
+**type** defines the shape of the GeoJson Query
+
+The allowed values are the following:
+
+→ **"Point"**: Use a GeoJSON Point query to search for a single latitude and longitude coordinate that intersects or is contained inside a GeoJSON shape in your documents
+
+→ **"LineString"**: Use a GeoJSON LineString query to search for a line of coordinates that intersects or is contained inside a GeoJSON shape in your documents
+
+→ **"Polygon"**: Use a GeoJSON Polygon query to search for a defined area that intersects, is contained inside, or surrounds a GeoJSON shape in your documents
+
+→ **"MultiPoint"**: Use a GeoJSON MultiPoint query to search for multiple coordinate points that intersect or are contained inside a GeoJSON shape in your documents
+
+→ **"MultiLineString"**: Use a GeoJSON MultiLineString query to search for multiple LineStrings that intersect or are contained inside a GeoJSON shape in your documents
+
+→ **"MultiPolygon"**: Use a GeoJSON MultiPolygon query to search for a group of defined Polygons that intersect, are contained inside, or surround a GeoJSON shape in your documents
+
+→ **"GeometryCollection"**: Use a GeoJSON GeometryCollection query to search for a group of defined Points, LineStrings, or Polygons that intersect, are contained inside, or surround a GeoJSON shape in your documents
+
+→ **"Circle"**: Use a GeoJSON Circle query to search in a radius around a single latitude and longitude coordinate
+
+→ **"Envelope"**: Use a GeoJSON Envelope query to search in a bounded rectangle, based on a pair of coordinates that define the minimum and maximum longitude and latitude:
\ No newline at end of file
diff --git a/docs/search/vector.md b/docs/search/vector.md
new file mode 100644
index 00000000..f56ced5e
--- /dev/null
+++ b/docs/search/vector.md
@@ -0,0 +1,7 @@
+Enter the vector that you want to compare to the vector data in **field**.
+
+The Search Service uses the similarity metric defined in the Search index definition to return the **k** closest vectors from the Search index.
+
+**NOTE:** The vector in your Search query must match the dimension of the vectors stored in your Search index. If the dimensions do not match, your Search query does not return any results. For more information about the dimension value, see the dims property or the Dimension option in the UI.
+
+→ [Knn Object Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#knn-object)
\ No newline at end of file
diff --git a/docs/search/vectors.md b/docs/search/vectors.md
new file mode 100644
index 00000000..9a7353de
--- /dev/null
+++ b/docs/search/vectors.md
@@ -0,0 +1,3 @@
+An object that contains a **{search-index-name}** object for each Search index in the query.
+
+→ [Vectors Object Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#vectors)
\ No newline at end of file
diff --git a/docs/search/wildcard.md b/docs/search/wildcard.md
new file mode 100644
index 00000000..2764e0b9
--- /dev/null
+++ b/docs/search/wildcard.md
@@ -0,0 +1,15 @@
+Use the **wildcard** property to run a wildcard query.
+
+Set the property to a regular expression that includes a wildcard character in the middle or end of a search term:
+
+→ Use **?** to allow a match to any single character.
+
+→ Use **\*** to allow a match to zero or many characters.
+
+For example, you could set the **wildcard** property to "inter*" to return matches for "interview", "interject", "internal", and so on.
+
+You cannot place the wildcard character at the start of the search term.
+
+If you use the **wildcard** property, the Search Service does not use any analyzers on the contents of your query text.
+
+→ [Non-Analytics Query Documentation](https://docs.couchbase.com/server/current/search/search-request-params.html#non-analytic-queries)
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 1612d773..7ecaad19 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -32,6 +32,7 @@
"dayjs": "^1.11.9",
"decompress": "^4.2.1",
"gitly": "^2.5.2",
+ "jsonc-parser": "^3.2.1",
"monaco-editor": "^0.43.0",
"mongodb": "^6.4.0",
"prop-types": "^15.7.2",
@@ -47,23 +48,25 @@
"react-tooltip": "^5.26.0",
"shelljs": "^0.8.5",
"stream-json": "^1.8.0",
- "uuid": "^9.0.1"
+ "uuid": "^9.0.1",
+ "vscode-json-languageservice": "^5.3.11"
},
"devDependencies": {
"@babel/parser": "^7.22.7",
"@babel/preset-env": "^7.23.5",
"@babel/preset-react": "^7.23.3",
+ "@electron/rebuild": "^3.6.0",
"@types/glob": "^7.2.0",
"@types/jest": "^29.5.12",
"@types/mocha": "^10.0.6",
- "@types/node": "^20.12.2",
+ "@types/node": "^20.14.2",
"@types/react": "^18.2.6",
"@types/react-dom": "^18.2.4",
"@types/uuid": "^9.0.6",
"@types/vscode": "^1.63.1",
"@typescript-eslint/eslint-plugin": "^7.5.0",
"@typescript-eslint/parser": "^7.5.0",
- "@vscode/test-electron": "^2.3.9",
+ "@vscode/test-electron": "^2.4.0",
"babel-loader": "^9.1.3",
"class-transformer": "^0.5.1",
"cmake-js": "^6.3.2",
@@ -84,7 +87,7 @@
"terser-webpack-plugin": "^5.3.10",
"ts-jest": "^29.1.2",
"ts-loader": "^9.5.1",
- "typescript": "^5.4.3",
+ "typescript": "^5.4.5",
"webpack": "^5.91.0",
"webpack-cli": "^5.1.4"
},
@@ -1929,6 +1932,332 @@
"node": ">=10.0.0"
}
},
+ "node_modules/@electron/rebuild": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.6.0.tgz",
+ "integrity": "sha512-zF4x3QupRU3uNGaP5X1wjpmcjfw1H87kyqZ00Tc3HvriV+4gmOGuvQjGNkrJuXdsApssdNyVwLsy+TaeTGGcVw==",
+ "dev": true,
+ "dependencies": {
+ "@malept/cross-spawn-promise": "^2.0.0",
+ "chalk": "^4.0.0",
+ "debug": "^4.1.1",
+ "detect-libc": "^2.0.1",
+ "fs-extra": "^10.0.0",
+ "got": "^11.7.0",
+ "node-abi": "^3.45.0",
+ "node-api-version": "^0.2.0",
+ "node-gyp": "^9.0.0",
+ "ora": "^5.1.0",
+ "read-binary-file-arch": "^1.0.6",
+ "semver": "^7.3.5",
+ "tar": "^6.0.5",
+ "yargs": "^17.0.1"
+ },
+ "bin": {
+ "electron-rebuild": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=12.13.0"
+ }
+ },
+ "node_modules/@electron/rebuild/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/@electron/rebuild/node_modules/bl": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
+ "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
+ "dev": true,
+ "dependencies": {
+ "buffer": "^5.5.0",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
+ }
+ },
+ "node_modules/@electron/rebuild/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/@electron/rebuild/node_modules/cli-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
+ "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
+ "dev": true,
+ "dependencies": {
+ "restore-cursor": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@electron/rebuild/node_modules/cliui": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@electron/rebuild/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/@electron/rebuild/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/@electron/rebuild/node_modules/fs-extra": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+ "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@electron/rebuild/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@electron/rebuild/node_modules/is-interactive": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
+ "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@electron/rebuild/node_modules/jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "dev": true,
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/@electron/rebuild/node_modules/minipass": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
+ "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@electron/rebuild/node_modules/ora": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz",
+ "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==",
+ "dev": true,
+ "dependencies": {
+ "bl": "^4.1.0",
+ "chalk": "^4.1.0",
+ "cli-cursor": "^3.1.0",
+ "cli-spinners": "^2.5.0",
+ "is-interactive": "^1.0.0",
+ "is-unicode-supported": "^0.1.0",
+ "log-symbols": "^4.1.0",
+ "strip-ansi": "^6.0.0",
+ "wcwidth": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@electron/rebuild/node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dev": true,
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/@electron/rebuild/node_modules/restore-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
+ "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
+ "dev": true,
+ "dependencies": {
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@electron/rebuild/node_modules/semver": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
+ "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@electron/rebuild/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@electron/rebuild/node_modules/tar": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
+ "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
+ "dev": true,
+ "dependencies": {
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.0.0",
+ "minipass": "^5.0.0",
+ "minizlib": "^2.1.1",
+ "mkdirp": "^1.0.3",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@electron/rebuild/node_modules/universalify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+ "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/@electron/rebuild/node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/@electron/rebuild/node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@electron/rebuild/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ },
+ "node_modules/@electron/rebuild/node_modules/yargs": {
+ "version": "17.7.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
+ "dev": true,
+ "dependencies": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@electron/rebuild/node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/@eslint-community/eslint-utils": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
@@ -2067,6 +2396,12 @@
"react": ">=16.3"
}
},
+ "node_modules/@gar/promisify": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
+ "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==",
+ "dev": true
+ },
"node_modules/@humanwhocodes/config-array": {
"version": "0.11.14",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
@@ -2929,8 +3264,30 @@
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
"dev": true,
"dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@malept/cross-spawn-promise": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-2.0.0.tgz",
+ "integrity": "sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/malept"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund"
+ }
+ ],
+ "dependencies": {
+ "cross-spawn": "^7.0.1"
+ },
+ "engines": {
+ "node": ">= 12.13.0"
}
},
"node_modules/@monaco-editor/loader": {
@@ -3000,6 +3357,45 @@
"node": ">= 8"
}
},
+ "node_modules/@npmcli/fs": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz",
+ "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==",
+ "dev": true,
+ "dependencies": {
+ "@gar/promisify": "^1.1.3",
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@npmcli/fs/node_modules/semver": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
+ "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@npmcli/move-file": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz",
+ "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==",
+ "deprecated": "This functionality has been moved to @npmcli/fs",
+ "dev": true,
+ "dependencies": {
+ "mkdirp": "^1.0.4",
+ "rimraf": "^3.0.2"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
"node_modules/@popperjs/core": {
"version": "2.11.8",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
@@ -3023,6 +3419,18 @@
"integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
"dev": true
},
+ "node_modules/@sindresorhus/is": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
+ "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/is?sponsor=1"
+ }
+ },
"node_modules/@sinonjs/commons": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz",
@@ -3041,13 +3449,25 @@
"@sinonjs/commons": "^3.0.0"
}
},
+ "node_modules/@szmarczak/http-timer": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz",
+ "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==",
+ "dev": true,
+ "dependencies": {
+ "defer-to-connect": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/@tootallnate/once": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
- "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
+ "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
"dev": true,
"engines": {
- "node": ">= 6"
+ "node": ">= 10"
}
},
"node_modules/@types/babel__core": {
@@ -3091,6 +3511,18 @@
"@babel/types": "^7.20.7"
}
},
+ "node_modules/@types/cacheable-request": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz",
+ "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==",
+ "dev": true,
+ "dependencies": {
+ "@types/http-cache-semantics": "*",
+ "@types/keyv": "^3.1.4",
+ "@types/node": "*",
+ "@types/responselike": "^1.0.0"
+ }
+ },
"node_modules/@types/debug": {
"version": "4.1.12",
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
@@ -3167,6 +3599,12 @@
"@types/unist": "*"
}
},
+ "node_modules/@types/http-cache-semantics": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz",
+ "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==",
+ "dev": true
+ },
"node_modules/@types/istanbul-lib-coverage": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
@@ -3207,6 +3645,15 @@
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
"dev": true
},
+ "node_modules/@types/keyv": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz",
+ "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
"node_modules/@types/mdast": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz",
@@ -3233,9 +3680,9 @@
"integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g=="
},
"node_modules/@types/node": {
- "version": "20.12.2",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.2.tgz",
- "integrity": "sha512-zQ0NYO87hyN6Xrclcqp7f8ZbXNbRfoGWNcMvHTPQp9UUrwI0mI7XBz+cu7/W6/VClYo2g63B0cjull/srU7LgQ==",
+ "version": "20.14.2",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz",
+ "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==",
"dependencies": {
"undici-types": "~5.26.4"
}
@@ -3263,6 +3710,15 @@
"@types/react": "*"
}
},
+ "node_modules/@types/responselike": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz",
+ "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
"node_modules/@types/semver": {
"version": "7.5.8",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
@@ -3661,41 +4117,32 @@
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
"integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ=="
},
+ "node_modules/@vscode/l10n": {
+ "version": "0.0.18",
+ "resolved": "https://registry.npmjs.org/@vscode/l10n/-/l10n-0.0.18.tgz",
+ "integrity": "sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ=="
+ },
"node_modules/@vscode/test-electron": {
- "version": "2.3.9",
- "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.3.9.tgz",
- "integrity": "sha512-z3eiChaCQXMqBnk2aHHSEkobmC2VRalFQN0ApOAtydL172zXGxTwGrRtviT5HnUB+Q+G3vtEYFtuQkYqBzYgMA==",
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.4.0.tgz",
+ "integrity": "sha512-yojuDFEjohx6Jb+x949JRNtSn6Wk2FAh4MldLE3ck9cfvCqzwxF32QsNy1T9Oe4oT+ZfFcg0uPUCajJzOmPlTA==",
"dev": true,
"dependencies": {
- "http-proxy-agent": "^4.0.1",
- "https-proxy-agent": "^5.0.0",
+ "http-proxy-agent": "^7.0.2",
+ "https-proxy-agent": "^7.0.4",
"jszip": "^3.10.1",
- "semver": "^7.5.2"
+ "ora": "^7.0.1",
+ "semver": "^7.6.2"
},
"engines": {
"node": ">=16"
}
},
- "node_modules/@vscode/test-electron/node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dev": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/@vscode/test-electron/node_modules/semver": {
- "version": "7.6.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
- "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
+ "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
"dev": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
"bin": {
"semver": "bin/semver.js"
},
@@ -3703,12 +4150,6 @@
"node": ">=10"
}
},
- "node_modules/@vscode/test-electron/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
- },
"node_modules/@webassemblyjs/ast": {
"version": "1.12.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz",
@@ -3911,6 +4352,12 @@
"integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
"dev": true
},
+ "node_modules/abbrev": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
+ "dev": true
+ },
"node_modules/acorn": {
"version": "8.11.3",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
@@ -3951,15 +4398,40 @@
}
},
"node_modules/agent-base": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
- "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
+ "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==",
"dev": true,
"dependencies": {
- "debug": "4"
+ "debug": "^4.3.4"
},
"engines": {
- "node": ">= 6.0.0"
+ "node": ">= 14"
+ }
+ },
+ "node_modules/agentkeepalive": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz",
+ "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==",
+ "dev": true,
+ "dependencies": {
+ "humanize-ms": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 8.0.0"
+ }
+ },
+ "node_modules/aggregate-error": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
+ "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
+ "dev": true,
+ "dependencies": {
+ "clean-stack": "^2.0.0",
+ "indent-string": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
}
},
"node_modules/ajv": {
@@ -4511,6 +4983,55 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/bl": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz",
+ "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==",
+ "dev": true,
+ "dependencies": {
+ "buffer": "^6.0.3",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
+ }
+ },
+ "node_modules/bl/node_modules/buffer": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+ "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.2.1"
+ }
+ },
+ "node_modules/bl/node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dev": true,
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/bluebird": {
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
@@ -4667,22 +5188,175 @@
"integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==",
"dev": true,
"engines": {
- "node": ">=0.10"
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/buffer-shims": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz",
+ "integrity": "sha512-Zy8ZXMyxIT6RMTeY7OP/bDndfj6bwCan7SS98CEndS6deHwWPpseeHlwarNcBim+etXnF9HBc1non5JgDaJU1g==",
+ "dev": true
+ },
+ "node_modules/buffers": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz",
+ "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.2.0"
+ }
+ },
+ "node_modules/cacache": {
+ "version": "16.1.3",
+ "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz",
+ "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==",
+ "dev": true,
+ "dependencies": {
+ "@npmcli/fs": "^2.1.0",
+ "@npmcli/move-file": "^2.0.0",
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.1.0",
+ "glob": "^8.0.1",
+ "infer-owner": "^1.0.4",
+ "lru-cache": "^7.7.1",
+ "minipass": "^3.1.6",
+ "minipass-collect": "^1.0.2",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "mkdirp": "^1.0.4",
+ "p-map": "^4.0.0",
+ "promise-inflight": "^1.0.1",
+ "rimraf": "^3.0.2",
+ "ssri": "^9.0.0",
+ "tar": "^6.1.11",
+ "unique-filename": "^2.0.0"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
+ "node_modules/cacache/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/cacache/node_modules/glob": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
+ "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^5.0.1",
+ "once": "^1.3.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/cacache/node_modules/lru-cache": {
+ "version": "7.18.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
+ "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/cacache/node_modules/minimatch": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+ "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/cacache/node_modules/tar": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
+ "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
+ "dev": true,
+ "dependencies": {
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.0.0",
+ "minipass": "^5.0.0",
+ "minizlib": "^2.1.1",
+ "mkdirp": "^1.0.3",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/cacache/node_modules/tar/node_modules/minipass": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
+ "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cacache/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ },
+ "node_modules/cacheable-lookup": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz",
+ "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.6.0"
+ }
+ },
+ "node_modules/cacheable-request": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz",
+ "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==",
+ "dev": true,
+ "dependencies": {
+ "clone-response": "^1.0.2",
+ "get-stream": "^5.1.0",
+ "http-cache-semantics": "^4.0.0",
+ "keyv": "^4.0.0",
+ "lowercase-keys": "^2.0.0",
+ "normalize-url": "^6.0.1",
+ "responselike": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
}
},
- "node_modules/buffer-shims": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz",
- "integrity": "sha512-Zy8ZXMyxIT6RMTeY7OP/bDndfj6bwCan7SS98CEndS6deHwWPpseeHlwarNcBim+etXnF9HBc1non5JgDaJU1g==",
- "dev": true
- },
- "node_modules/buffers": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz",
- "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==",
+ "node_modules/cacheable-request/node_modules/get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
"dev": true,
+ "dependencies": {
+ "pump": "^3.0.0"
+ },
"engines": {
- "node": ">=0.2.0"
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/call-bind": {
@@ -4898,6 +5572,42 @@
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
"integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow=="
},
+ "node_modules/clean-stack": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/cli-cursor": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz",
+ "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==",
+ "dev": true,
+ "dependencies": {
+ "restore-cursor": "^4.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-spinners": {
+ "version": "2.9.2",
+ "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz",
+ "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/cliui": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
@@ -4956,6 +5666,15 @@
"node": ">=0.10.0"
}
},
+ "node_modules/clone": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+ "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
"node_modules/clone-deep": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
@@ -4970,6 +5689,18 @@
"node": ">=6"
}
},
+ "node_modules/clone-response": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz",
+ "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==",
+ "dev": true,
+ "dependencies": {
+ "mimic-response": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/clsx": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz",
@@ -5875,6 +6606,33 @@
"node": ">=4"
}
},
+ "node_modules/decompress-response": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
+ "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
+ "dev": true,
+ "dependencies": {
+ "mimic-response": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/decompress-response/node_modules/mimic-response": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
+ "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/decompress-tar": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz",
@@ -5983,6 +6741,27 @@
"node": ">=0.10.0"
}
},
+ "node_modules/defaults": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
+ "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
+ "dev": true,
+ "dependencies": {
+ "clone": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/defer-to-connect": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
+ "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/define-data-property": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
@@ -6038,6 +6817,15 @@
"node": ">=6"
}
},
+ "node_modules/detect-libc": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
+ "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/detect-newline": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
@@ -6110,6 +6898,12 @@
"readable-stream": "^2.0.2"
}
},
+ "node_modules/eastasianwidth": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+ "dev": true
+ },
"node_modules/electron-to-chromium": {
"version": "1.4.722",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.722.tgz",
@@ -6142,6 +6936,16 @@
"node": ">= 4"
}
},
+ "node_modules/encoding": {
+ "version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
+ "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "iconv-lite": "^0.6.2"
+ }
+ },
"node_modules/end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
@@ -6163,6 +6967,15 @@
"node": ">=10.13.0"
}
},
+ "node_modules/env-paths": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/envinfo": {
"version": "7.11.1",
"resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.1.tgz",
@@ -6175,6 +6988,12 @@
"node": ">=4"
}
},
+ "node_modules/err-code": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
+ "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
+ "dev": true
+ },
"node_modules/error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@@ -6725,6 +7544,12 @@
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
+ "node_modules/exponential-backoff": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz",
+ "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==",
+ "dev": true
+ },
"node_modules/extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
@@ -7018,22 +7843,6 @@
"node": ">= 8"
}
},
- "node_modules/fs-minipass/node_modules/minipass": {
- "version": "3.3.6",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
- "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/fs-minipass/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
- },
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -7349,6 +8158,31 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/got": {
+ "version": "11.8.6",
+ "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz",
+ "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==",
+ "dev": true,
+ "dependencies": {
+ "@sindresorhus/is": "^4.0.0",
+ "@szmarczak/http-timer": "^4.0.5",
+ "@types/cacheable-request": "^6.0.1",
+ "@types/responselike": "^1.0.0",
+ "cacheable-lookup": "^5.0.3",
+ "cacheable-request": "^7.0.2",
+ "decompress-response": "^6.0.0",
+ "http2-wrapper": "^1.0.0-beta.5.2",
+ "lowercase-keys": "^2.0.0",
+ "p-cancelable": "^2.0.0",
+ "responselike": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.19.0"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/got?sponsor=1"
+ }
+ },
"node_modules/graceful-fs": {
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
@@ -7598,31 +8432,49 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/http-cache-semantics": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
+ "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==",
+ "dev": true
+ },
"node_modules/http-proxy-agent": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
- "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
+ "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
"dev": true,
"dependencies": {
- "@tootallnate/once": "1",
- "agent-base": "6",
- "debug": "4"
+ "agent-base": "^7.1.0",
+ "debug": "^4.3.4"
},
"engines": {
- "node": ">= 6"
+ "node": ">= 14"
+ }
+ },
+ "node_modules/http2-wrapper": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz",
+ "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==",
+ "dev": true,
+ "dependencies": {
+ "quick-lru": "^5.1.1",
+ "resolve-alpn": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=10.19.0"
}
},
"node_modules/https-proxy-agent": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
- "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz",
+ "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==",
"dev": true,
"dependencies": {
- "agent-base": "6",
+ "agent-base": "^7.0.2",
"debug": "4"
},
"engines": {
- "node": ">= 6"
+ "node": ">= 14"
}
},
"node_modules/human-signals": {
@@ -7634,6 +8486,28 @@
"node": ">=10.17.0"
}
},
+ "node_modules/humanize-ms": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
+ "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "^2.0.0"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/icss-utils": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
@@ -7794,6 +8668,21 @@
"node": ">=0.8.19"
}
},
+ "node_modules/indent-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/infer-owner": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
+ "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
+ "dev": true
+ },
"node_modules/inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@@ -7854,8 +8743,7 @@
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz",
"integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==",
- "optional": true,
- "peer": true,
+ "devOptional": true,
"dependencies": {
"jsbn": "1.1.0",
"sprintf-js": "^1.1.3"
@@ -7868,8 +8756,7 @@
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
"integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==",
- "optional": true,
- "peer": true
+ "devOptional": true
},
"node_modules/is-alphabetical": {
"version": "2.0.1",
@@ -8064,12 +8951,30 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/is-interactive": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz",
+ "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/is-iojs": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-iojs/-/is-iojs-1.1.0.tgz",
"integrity": "sha512-tLn1j3wYSL6DkvEI+V/j0pKohpa5jk+ER74v6S4SgCXnjS0WA+DoZbwZBrrhgwksMvtuwndyGeG5F8YMsoBzSA==",
"dev": true
},
+ "node_modules/is-lambda": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
+ "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==",
+ "dev": true
+ },
"node_modules/is-natural-number": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz",
@@ -10208,8 +11113,7 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
"integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==",
- "optional": true,
- "peer": true
+ "devOptional": true
},
"node_modules/jsesc": {
"version": "2.5.2",
@@ -10265,6 +11169,11 @@
"node": ">=6"
}
},
+ "node_modules/jsonc-parser": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz",
+ "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA=="
+ },
"node_modules/jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
@@ -10583,6 +11492,15 @@
"loose-envify": "cli.js"
}
},
+ "node_modules/lowercase-keys": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
+ "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/lowlight": {
"version": "1.20.0",
"resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz",
@@ -10602,34 +11520,109 @@
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
"dev": true,
"dependencies": {
- "yallist": "^3.0.2"
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/make-dir": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
+ "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
+ "dependencies": {
+ "pify": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/make-dir/node_modules/pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/make-error": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+ "dev": true
+ },
+ "node_modules/make-fetch-happen": {
+ "version": "10.2.1",
+ "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz",
+ "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==",
+ "dev": true,
+ "dependencies": {
+ "agentkeepalive": "^4.2.1",
+ "cacache": "^16.1.0",
+ "http-cache-semantics": "^4.1.0",
+ "http-proxy-agent": "^5.0.0",
+ "https-proxy-agent": "^5.0.0",
+ "is-lambda": "^1.0.1",
+ "lru-cache": "^7.7.1",
+ "minipass": "^3.1.6",
+ "minipass-collect": "^1.0.2",
+ "minipass-fetch": "^2.0.3",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "negotiator": "^0.6.3",
+ "promise-retry": "^2.0.1",
+ "socks-proxy-agent": "^7.0.0",
+ "ssri": "^9.0.0"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
+ "node_modules/make-fetch-happen/node_modules/agent-base": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+ "dev": true,
+ "dependencies": {
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6.0.0"
+ }
+ },
+ "node_modules/make-fetch-happen/node_modules/http-proxy-agent": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
+ "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
+ "dev": true,
+ "dependencies": {
+ "@tootallnate/once": "2",
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6"
}
},
- "node_modules/make-dir": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
- "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
+ "node_modules/make-fetch-happen/node_modules/https-proxy-agent": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
+ "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+ "dev": true,
"dependencies": {
- "pify": "^3.0.0"
+ "agent-base": "6",
+ "debug": "4"
},
"engines": {
- "node": ">=4"
+ "node": ">= 6"
}
},
- "node_modules/make-dir/node_modules/pify": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
- "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
+ "node_modules/make-fetch-happen/node_modules/lru-cache": {
+ "version": "7.18.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
+ "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
+ "dev": true,
"engines": {
- "node": ">=4"
+ "node": ">=12"
}
},
- "node_modules/make-error": {
- "version": "1.3.6",
- "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
- "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
- "dev": true
- },
"node_modules/makeerror": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
@@ -11308,6 +12301,15 @@
"node": ">=6"
}
},
+ "node_modules/mimic-response": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
+ "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@@ -11327,29 +12329,99 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/minizlib": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
- "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
+ "node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"dependencies": {
- "minipass": "^3.0.0",
"yallist": "^4.0.0"
},
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minipass-collect": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
+ "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
+ "dev": true,
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
"engines": {
"node": ">= 8"
}
},
- "node_modules/minizlib/node_modules/minipass": {
- "version": "3.3.6",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
- "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "node_modules/minipass-fetch": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz",
+ "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==",
+ "dev": true,
"dependencies": {
- "yallist": "^4.0.0"
+ "minipass": "^3.1.6",
+ "minipass-sized": "^1.0.3",
+ "minizlib": "^2.1.2"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ },
+ "optionalDependencies": {
+ "encoding": "^0.1.13"
+ }
+ },
+ "node_modules/minipass-flush": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
+ "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
+ "dev": true,
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/minipass-pipeline": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
+ "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
+ "dev": true,
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minipass-sized": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz",
+ "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
+ "dev": true,
+ "dependencies": {
+ "minipass": "^3.0.0"
},
"engines": {
"node": ">=8"
}
},
+ "node_modules/minipass/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ },
+ "node_modules/minizlib": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
+ "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
+ "dependencies": {
+ "minipass": "^3.0.0",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
"node_modules/minizlib/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
@@ -11712,23 +12784,225 @@
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
"dev": true
},
+ "node_modules/negotiator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/neo-async": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
"dev": true
},
- "node_modules/nice-try": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
- "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+ "node_modules/nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+ "dev": true
+ },
+ "node_modules/node-abi": {
+ "version": "3.65.0",
+ "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.65.0.tgz",
+ "integrity": "sha512-ThjYBfoDNr08AWx6hGaRbfPwxKV9kVzAzOzlLKbk2CuqXE2xnCh+cbAGnwM3t8Lq4v9rUB7VfondlkBckcJrVA==",
+ "dev": true,
+ "dependencies": {
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/node-abi/node_modules/semver": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
+ "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/node-api-headers": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/node-api-headers/-/node-api-headers-1.1.0.tgz",
+ "integrity": "sha512-ucQW+SbYCUPfprvmzBsnjT034IGRB2XK8rRc78BgjNKhTdFKgAwAmgW704bKIBmcYW48it0Gkjpkd39Azrwquw=="
+ },
+ "node_modules/node-api-version": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/node-api-version/-/node-api-version-0.2.0.tgz",
+ "integrity": "sha512-fthTTsi8CxaBXMaBAD7ST2uylwvsnYxh2PfaScwpMhos6KlSFajXQPcM4ogNE1q2s3Lbz9GCGqeIHC+C6OZnKg==",
+ "dev": true,
+ "dependencies": {
+ "semver": "^7.3.5"
+ }
+ },
+ "node_modules/node-api-version/node_modules/semver": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
+ "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/node-gyp": {
+ "version": "9.4.1",
+ "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.1.tgz",
+ "integrity": "sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ==",
+ "dev": true,
+ "dependencies": {
+ "env-paths": "^2.2.0",
+ "exponential-backoff": "^3.1.1",
+ "glob": "^7.1.4",
+ "graceful-fs": "^4.2.6",
+ "make-fetch-happen": "^10.0.3",
+ "nopt": "^6.0.0",
+ "npmlog": "^6.0.0",
+ "rimraf": "^3.0.2",
+ "semver": "^7.3.5",
+ "tar": "^6.1.2",
+ "which": "^2.0.2"
+ },
+ "bin": {
+ "node-gyp": "bin/node-gyp.js"
+ },
+ "engines": {
+ "node": "^12.13 || ^14.13 || >=16"
+ }
+ },
+ "node_modules/node-gyp/node_modules/are-we-there-yet": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz",
+ "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==",
+ "deprecated": "This package is no longer supported.",
+ "dev": true,
+ "dependencies": {
+ "delegates": "^1.0.0",
+ "readable-stream": "^3.6.0"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
+ "node_modules/node-gyp/node_modules/gauge": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz",
+ "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==",
+ "deprecated": "This package is no longer supported.",
+ "dev": true,
+ "dependencies": {
+ "aproba": "^1.0.3 || ^2.0.0",
+ "color-support": "^1.1.3",
+ "console-control-strings": "^1.1.0",
+ "has-unicode": "^2.0.1",
+ "signal-exit": "^3.0.7",
+ "string-width": "^4.2.3",
+ "strip-ansi": "^6.0.1",
+ "wide-align": "^1.1.5"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
+ "node_modules/node-gyp/node_modules/minipass": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
+ "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/node-gyp/node_modules/npmlog": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz",
+ "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==",
+ "deprecated": "This package is no longer supported.",
+ "dev": true,
+ "dependencies": {
+ "are-we-there-yet": "^3.0.0",
+ "console-control-strings": "^1.1.0",
+ "gauge": "^4.0.3",
+ "set-blocking": "^2.0.0"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
+ "node_modules/node-gyp/node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dev": true,
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/node-gyp/node_modules/semver": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
+ "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/node-gyp/node_modules/tar": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
+ "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
+ "dev": true,
+ "dependencies": {
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.0.0",
+ "minipass": "^5.0.0",
+ "minizlib": "^2.1.1",
+ "mkdirp": "^1.0.3",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/node-gyp/node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/node-gyp/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
- "node_modules/node-api-headers": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/node-api-headers/-/node-api-headers-1.1.0.tgz",
- "integrity": "sha512-ucQW+SbYCUPfprvmzBsnjT034IGRB2XK8rRc78BgjNKhTdFKgAwAmgW704bKIBmcYW48it0Gkjpkd39Azrwquw=="
- },
"node_modules/node-int64": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
@@ -11760,6 +13034,21 @@
"integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
"dev": true
},
+ "node_modules/nopt": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz",
+ "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==",
+ "dev": true,
+ "dependencies": {
+ "abbrev": "^1.0.0"
+ },
+ "bin": {
+ "nopt": "bin/nopt.js"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
"node_modules/normalize-package-data": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
@@ -11790,6 +13079,18 @@
"node": ">=0.10.0"
}
},
+ "node_modules/normalize-url": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
+ "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/npm-run-all": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz",
@@ -11986,6 +13287,119 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/ora": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/ora/-/ora-7.0.1.tgz",
+ "integrity": "sha512-0TUxTiFJWv+JnjWm4o9yvuskpEJLXTcng8MJuKd+SzAzp2o+OP3HWqNhB4OdJRt1Vsd9/mR0oyaEYlOnL7XIRw==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^5.3.0",
+ "cli-cursor": "^4.0.0",
+ "cli-spinners": "^2.9.0",
+ "is-interactive": "^2.0.0",
+ "is-unicode-supported": "^1.3.0",
+ "log-symbols": "^5.1.0",
+ "stdin-discarder": "^0.1.0",
+ "string-width": "^6.1.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ora/node_modules/ansi-regex": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
+ "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/ora/node_modules/chalk": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
+ "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
+ "dev": true,
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/ora/node_modules/emoji-regex": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz",
+ "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==",
+ "dev": true
+ },
+ "node_modules/ora/node_modules/is-unicode-supported": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz",
+ "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ora/node_modules/log-symbols": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-5.1.0.tgz",
+ "integrity": "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^5.0.0",
+ "is-unicode-supported": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ora/node_modules/string-width": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-6.1.0.tgz",
+ "integrity": "sha512-k01swCJAgQmuADB0YIc+7TuatfNvTBVOoaUWJjTB9R4VJzR5vNWzf5t42ESVZFPS8xTySF7CAdV4t/aaIm3UnQ==",
+ "dev": true,
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^10.2.1",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ora/node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
"node_modules/os-locale": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
@@ -11998,6 +13412,15 @@
"node": ">=0.10.0"
}
},
+ "node_modules/p-cancelable": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz",
+ "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/p-limit": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
@@ -12028,6 +13451,21 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/p-map": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
+ "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
+ "dev": true,
+ "dependencies": {
+ "aggregate-error": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
@@ -12501,6 +13939,25 @@
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
},
+ "node_modules/promise-inflight": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
+ "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==",
+ "dev": true
+ },
+ "node_modules/promise-retry": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
+ "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
+ "dev": true,
+ "dependencies": {
+ "err-code": "^2.0.2",
+ "retry": "^0.12.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/prompts": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
@@ -12538,6 +13995,16 @@
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
+ "node_modules/pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "dependencies": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
@@ -12582,6 +14049,18 @@
}
]
},
+ "node_modules/quick-lru": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
+ "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@@ -12781,6 +14260,18 @@
"react-dom": ">=16.14.0"
}
},
+ "node_modules/read-binary-file-arch": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/read-binary-file-arch/-/read-binary-file-arch-1.0.6.tgz",
+ "integrity": "sha512-BNg9EN3DD3GsDXX7Aa8O4p92sryjkmzYYgmgTAc6CA4uGLEDzFfxOxugu21akOxpcXHiEgsYkC6nPsQvLLLmEg==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^4.3.4"
+ },
+ "bin": {
+ "read-binary-file-arch": "cli.js"
+ }
+ },
"node_modules/read-pkg": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
@@ -13137,6 +14628,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/resolve-alpn": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz",
+ "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==",
+ "dev": true
+ },
"node_modules/resolve-cwd": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
@@ -13176,6 +14673,43 @@
"node": ">=10"
}
},
+ "node_modules/responselike": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz",
+ "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==",
+ "dev": true,
+ "dependencies": {
+ "lowercase-keys": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/restore-cursor": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz",
+ "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==",
+ "dev": true,
+ "dependencies": {
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/retry": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
+ "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
"node_modules/reusify": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
@@ -13270,6 +14804,13 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true,
+ "optional": true
+ },
"node_modules/sass": {
"version": "1.72.0",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.72.0.tgz",
@@ -13578,8 +15119,7 @@
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
"integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
- "optional": true,
- "peer": true,
+ "devOptional": true,
"engines": {
"node": ">= 6.0.0",
"npm": ">= 3.0.0"
@@ -13589,8 +15129,7 @@
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/socks/-/socks-2.8.1.tgz",
"integrity": "sha512-B6w7tkwNid7ToxjZ08rQMT8M9BJAf8DKx8Ft4NivzH0zBUfd6jldGcisJn/RLgxcX3FPNDdNQCUEMMT79b+oCQ==",
- "optional": true,
- "peer": true,
+ "devOptional": true,
"dependencies": {
"ip-address": "^9.0.5",
"smart-buffer": "^4.2.0"
@@ -13600,6 +15139,32 @@
"npm": ">= 3.0.0"
}
},
+ "node_modules/socks-proxy-agent": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz",
+ "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==",
+ "dev": true,
+ "dependencies": {
+ "agent-base": "^6.0.2",
+ "debug": "^4.3.3",
+ "socks": "^2.6.2"
+ },
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/socks-proxy-agent/node_modules/agent-base": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+ "dev": true,
+ "dependencies": {
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6.0.0"
+ }
+ },
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -13689,6 +15254,18 @@
"integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
"dev": true
},
+ "node_modules/ssri": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz",
+ "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==",
+ "dev": true,
+ "dependencies": {
+ "minipass": "^3.1.1"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
"node_modules/stack-utils": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
@@ -13715,6 +15292,21 @@
"resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz",
"integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w=="
},
+ "node_modules/stdin-discarder": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.1.0.tgz",
+ "integrity": "sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==",
+ "dev": true,
+ "dependencies": {
+ "bl": "^5.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/stream-chain": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/stream-chain/-/stream-chain-2.2.5.tgz",
@@ -14579,9 +16171,9 @@
}
},
"node_modules/typescript": {
- "version": "5.4.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz",
- "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==",
+ "version": "5.4.5",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
+ "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
@@ -14678,6 +16270,30 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/unique-filename": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz",
+ "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==",
+ "dev": true,
+ "dependencies": {
+ "unique-slug": "^3.0.0"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
+ "node_modules/unique-slug": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz",
+ "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==",
+ "dev": true,
+ "dependencies": {
+ "imurmurhash": "^0.1.4"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
"node_modules/unist-util-is": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz",
@@ -14926,6 +16542,33 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/vscode-json-languageservice": {
+ "version": "5.3.11",
+ "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-5.3.11.tgz",
+ "integrity": "sha512-WYS72Ymria3dn8ZbjtBbt5K71m05wY1Q6hpXV5JxUT0q75Ts0ljLmnZJAVpx8DjPgYbFD+Z8KHpWh2laKLUCtQ==",
+ "dependencies": {
+ "@vscode/l10n": "^0.0.18",
+ "jsonc-parser": "^3.2.1",
+ "vscode-languageserver-textdocument": "^1.0.11",
+ "vscode-languageserver-types": "^3.17.5",
+ "vscode-uri": "^3.0.8"
+ }
+ },
+ "node_modules/vscode-languageserver-textdocument": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.11.tgz",
+ "integrity": "sha512-X+8T3GoiwTVlJbicx/sIAF+yuJAqz8VvwJyoMVhwEMoEKE/fkDmrqUgDMyBECcM2A2frVZIUj5HI/ErRXCfOeA=="
+ },
+ "node_modules/vscode-languageserver-types": {
+ "version": "3.17.5",
+ "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz",
+ "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg=="
+ },
+ "node_modules/vscode-uri": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz",
+ "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw=="
+ },
"node_modules/walker": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
@@ -14956,6 +16599,15 @@
"node": ">=10.13.0"
}
},
+ "node_modules/wcwidth": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
+ "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
+ "dev": true,
+ "dependencies": {
+ "defaults": "^1.0.3"
+ }
+ },
"node_modules/webidl-conversions": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
diff --git a/package.json b/package.json
index 3039ec6a..55db319e 100644
--- a/package.json
+++ b/package.json
@@ -46,7 +46,8 @@
"compile:views": "webpack --mode development",
"watch:extension": "tsc -watch -p ./",
"watch:views": "webpack --watch --mode development",
- "test": "node ./out/test/runTest.js && jest",
+ "test": "node ./out/test/runTest.js",
+ "test:file": "node ./out/test/runTest.js",
"format": "prettier 'src/**/*.ts' --write",
"lint": "eslint src --ext ts --fix",
"pretest": "npm run compile:extension"
@@ -55,17 +56,18 @@
"@babel/parser": "^7.22.7",
"@babel/preset-env": "^7.23.5",
"@babel/preset-react": "^7.23.3",
+ "@electron/rebuild": "^3.6.0",
"@types/glob": "^7.2.0",
"@types/jest": "^29.5.12",
"@types/mocha": "^10.0.6",
- "@types/node": "^20.12.2",
+ "@types/node": "^20.14.2",
"@types/react": "^18.2.6",
"@types/react-dom": "^18.2.4",
"@types/uuid": "^9.0.6",
"@types/vscode": "^1.63.1",
"@typescript-eslint/eslint-plugin": "^7.5.0",
"@typescript-eslint/parser": "^7.5.0",
- "@vscode/test-electron": "^2.3.9",
+ "@vscode/test-electron": "^2.4.0",
"babel-loader": "^9.1.3",
"class-transformer": "^0.5.1",
"cmake-js": "^6.3.2",
@@ -86,7 +88,7 @@
"terser-webpack-plugin": "^5.3.10",
"ts-jest": "^29.1.2",
"ts-loader": "^9.5.1",
- "typescript": "^5.4.3",
+ "typescript": "^5.4.5",
"webpack": "^5.91.0",
"webpack-cli": "^5.1.4"
},
@@ -114,6 +116,7 @@
"dayjs": "^1.11.9",
"decompress": "^4.2.1",
"gitly": "^2.5.2",
+ "jsonc-parser": "^3.2.1",
"monaco-editor": "^0.43.0",
"mongodb": "^6.4.0",
"prop-types": "^15.7.2",
@@ -129,7 +132,8 @@
"react-tooltip": "^5.26.0",
"shelljs": "^0.8.5",
"stream-json": "^1.8.0",
- "uuid": "^9.0.1"
+ "uuid": "^9.0.1",
+ "vscode-json-languageservice": "^5.3.11"
},
"activationEvents": [
"onFileSystem:couchbase",
@@ -358,17 +362,24 @@
],
"configuration": "./language/language-configuration.json"
},
-
{
- "id":"searchQuery",
+ "id": "json",
"extensions": [
".cbs.json"
],
"aliases": [
"SEARCH"
],
- "configuration": "./language/language-configuration.json"
-
+ "configurationDefaults": {
+ "[json]": {
+ "editor.quickSuggestions": {
+ "strings": false,
+ "comments": false,
+ "other": false
+ },
+ "editor.suggestOnTriggerCharacters": false
+ }
+ }
}
],
"grammars": [
@@ -732,7 +743,7 @@
"command": "vscode-couchbase.runSearch",
"key": "ctrl+shift+e",
"mac": "cmd+shift+e",
- "when": "(editorLangId == cbs.json || resourceFilename =~ /.cbs.json$/) && !isKVCluster"
+ "when": "editorLangId == json && resourceFilename =~ /\\.cbs\\.json$/ && !isKVCluster && isSearchEnabled"
}
],
"menus": {
@@ -746,7 +757,7 @@
{
"command": "vscode-couchbase.runSearch",
"category": "Couchbase",
- "when": "(editorLangId == cbs.json || resourceFilename =~ /.cbs.json$/) && !isKVCluster",
+ "when": "editorLangId == json && resourceFilename =~ /\\.cbs\\.json$/ && !isKVCluster && isSearchEnabled",
"group": "navigation@1"
},
{
@@ -761,7 +772,7 @@
"command": "vscode-couchbase.searchContext",
"category": "Couchbase",
"group": "navigation@2",
- "when": "(editorLangId == cbs.json || resourceFilename =~ /.cbs.json$/) && !isKVCluster"
+ "when": "editorLangId == json && resourceFilename =~ /\\.cbs\\.json$/ && !isKVCluster"
},
{
"title": "Show Favorite Queries",
@@ -814,7 +825,7 @@
},
{
"command": "vscode-couchbase.runSearch",
- "when": "(editorLangId == .cbs.json || resourceFilename =~ /.cbs.json$/) && !isKVCluster",
+ "when": "editorLangId == json && resourceFilename =~ /\\.cbs\\.json$/ && !isKVCluster && isSearchEnabled",
"group": "navigation@1"
}
],
@@ -1023,7 +1034,7 @@
},
{
"command": "vscode-couchbase.openSearchWorkbench",
- "when": "view == couchbase && viewItem == searchIndex && !isKVCluster",
+ "when": "view == couchbase && viewItem == searchIndex && !isKVCluster && isSearchEnabled",
"group": "workbench@1"
},
{
@@ -1254,4 +1265,4 @@
}
]
}
-}
\ No newline at end of file
+}
diff --git a/src/commands/fts/SearchWorkbench/contributor/autoComplete.ts b/src/commands/fts/SearchWorkbench/contributor/autoComplete.ts
new file mode 100644
index 00000000..cb5db227
--- /dev/null
+++ b/src/commands/fts/SearchWorkbench/contributor/autoComplete.ts
@@ -0,0 +1,11 @@
+import * as jsonc from 'jsonc-parser';
+import * as vscode from 'vscode';
+
+export interface CBSContributor {
+
+ accept(key: string | null): boolean;
+
+ contributeKey(parentKey: string | null, node: jsonc.Node, suggestion: string[], result: vscode.CompletionItem[], existingKeys:string[]): any;
+
+ contributeValue(attributeKey: string | null, node: jsonc.Node, suggestion: string[], fields:string[]): any;
+}
diff --git a/src/commands/fts/SearchWorkbench/contributor/autoCompleteVisitor.ts b/src/commands/fts/SearchWorkbench/contributor/autoCompleteVisitor.ts
new file mode 100644
index 00000000..3d78b027
--- /dev/null
+++ b/src/commands/fts/SearchWorkbench/contributor/autoCompleteVisitor.ts
@@ -0,0 +1,292 @@
+import * as vscode from 'vscode';
+import * as jsonc from 'jsonc-parser';
+import { CBSContributor } from './autoComplete';
+import { booleanCbsContributor } from './booleanCbsContributor';
+import { consistencyCbsContributor } from './consistencyCbsContributor';
+import { geometryCbsContributor } from './geometryCbsContributor';
+import { highlightCbsContributor } from './highlightCbsContributor';
+import { knnCbsContributor } from './knnCbsContributor';
+import { locationCbsContributor } from './locationCbsContributor';
+import { fieldsContributor } from './fieldsContributor';
+import { queryCbsContributor } from './queryCbsContributor';
+import { cbsTemplate } from './cbsTemplates';
+import { ctlCbsContributor } from './ctlCbsContributor';
+import { shapeCbsContributor } from './shapeCbsContributor';
+import { SearchWorkbench } from '../searchWorkbench';
+import { logger } from '../../../../logger/logger';
+
+
+
+export class AutocompleteVisitor {
+ public topLevelKeywords: string[] = ["query", "knn", "ctl", "size", "limit", "from", "offset", "highlight", "fields", "facets", "explain", "sort", "includeLocations", "score", "search_after", "search_before", "collections"];
+ private contributors: CBSContributor[] = [new booleanCbsContributor(), new consistencyCbsContributor(), new geometryCbsContributor(), new highlightCbsContributor(), new knnCbsContributor(), new locationCbsContributor(), new queryCbsContributor(), new ctlCbsContributor(), new shapeCbsContributor()];
+
+ async getAutoCompleteContributor(document: vscode.TextDocument, position: vscode.Position, searchWorkBench?: SearchWorkbench): Promise {
+ const text = document.getText();
+ // const rootNode = jsonc.parseTree(text);
+ const queryContext = searchWorkBench?.editorToContext.get(document.uri.toString());
+ const tempJsonString = this.addTemporaryQuotes(text, position);
+ const rootNode = jsonc.parseTree(tempJsonString);
+
+
+ if (!rootNode) {
+ return [];
+ }
+ const node = jsonc.findNodeAtOffset(rootNode, document.offsetAt(position));
+
+ if (!node) {
+ return [];
+ }
+ if(!this.isWithinObject(node)){
+ return [];
+ }
+ const isKey = this.isKey(document, position);
+ let attributeName: string | null = null;
+ if (!isKey) {
+ attributeName = this.getAttributeName(rootNode, node);
+ }
+
+ const suggestions: string[] = [];
+ const result: vscode.CompletionItem[] = [];
+ const existingKeys: string[] = [];
+
+ await this.fetchKeys(node, existingKeys)
+ const isWithinQuotes = this.isWithinQuotes(document, position);
+ if (this.isTopLevelProperty(rootNode, node)) {
+
+ if (!isKey) {
+ if (attributeName == 'score') {
+ suggestions.push('none');
+ }
+ } else {
+ suggestions.push(...this.topLevelKeywords.filter(keyword => !existingKeys.includes(keyword)));
+
+
+ if (!existingKeys.includes('highlight')) {
+ result.push(cbsTemplate.getHighlightTemplate());
+ }
+ if (!existingKeys.includes('knn')) {
+ result.push(cbsTemplate.getKNNTemplate())
+ }
+ }
+
+ } else {
+ let type = this.getNodeType(node, rootNode);
+ for (const contributor of this.contributors) {
+ if (contributor.accept(type)) {
+ if (isKey) {
+ const existingKeys2 = existingKeys.filter(item => item !== '');
+ contributor.contributeKey(type, node, suggestions, result, existingKeys2);
+ }
+ else {
+ let fields: string[] = []
+ if (attributeName == "field" && queryContext?.bucketName && queryContext?.indexName) {
+ fields = await fieldsContributor.getFieldNames(queryContext?.bucketName, queryContext?.indexName)
+ }
+ contributor.contributeValue(attributeName, node, suggestions, fields)
+ }
+ }
+ };
+
+
+
+ }
+ for (const suggestion of suggestions) {
+ if (!existingKeys.includes(suggestion)) {
+ let itemLabel = suggestion;
+ if (!isWithinQuotes) {
+ itemLabel = `"${suggestion}"`;
+ }
+
+ const completionItem = new vscode.CompletionItem(itemLabel, vscode.CompletionItemKind.Text);
+ result.push(completionItem);
+ }
+ };
+ return result;
+ }
+
+ addTemporaryQuotes(jsonString: string, position: vscode.Position): string {
+ const lines = jsonString.split('\n');
+ const line = lines[position.line];
+
+ const regex = /("(\w+)")\s*:\s*,/;
+
+ if (regex.test(line)) {
+ return lines.map((l, i) =>
+ i === position.line ? l.replace(regex, '$1: "",') : l
+ ).join('\n');
+ }
+
+ return jsonString;
+ }
+
+ isTopLevelProperty(rootNode: jsonc.Node, currentNode: jsonc.Node) {
+ if (currentNode === rootNode) {
+ return true
+ }
+ if (currentNode.type === 'string') {
+ if (currentNode.parent && currentNode.parent.parent) {
+ const propertyNode = currentNode.parent.parent
+ return propertyNode === rootNode
+ }
+ }
+ if (currentNode.type === 'property' && currentNode.parent) {
+ return currentNode.parent === rootNode;
+ }
+
+ return false;
+ }
+
+ async fetchKeys(node: jsonc.Node, existingKeys: string[]): Promise {
+ if (node.type === 'object') {
+ for (const prop of node.children || []) {
+ if (prop.type === 'property') {
+ const keyNode = prop.children?.[0];
+ if (keyNode && keyNode.type === 'string') {
+ existingKeys.push(keyNode.value as string);
+ }
+ }
+ }
+ } else if (node.type === 'string') {
+ if (node.parent?.type === 'property' && node.parent.parent?.type === 'object') {
+ const objectNode = node.parent.parent;
+ for (const prop of objectNode.children || []) {
+ if (prop.type === 'property') {
+ const keyNode = prop.children?.[0];
+ if (keyNode && keyNode.type === 'string' && keyNode.value !== '') {
+ existingKeys.push(keyNode.value as string);
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+
+ getNodeType(node: jsonc.Node | undefined, rootNode: jsonc.Node): string | null {
+ let currentNode = node ;
+ if (!currentNode) {
+ logger.debug("Error fetching Node type, Node is undefined")
+ return null;
+ }
+
+
+ let lastPropertyName = undefined;
+ let count = 0;
+
+ while (currentNode) {
+ if (currentNode.type === 'property') {
+ if (currentNode.parent) {
+ count = count + 1;
+ lastPropertyName = jsonc.findNodeAtOffset(rootNode, currentNode.offset)?.value;
+ if (count == 2) {
+ break;
+ }
+ }
+ } else if (currentNode.type === 'array' && currentNode.parent && currentNode.parent.type === 'property') {
+ lastPropertyName = jsonc.findNodeAtOffset(rootNode, currentNode.parent.offset)?.value;
+ break;
+ } else if ( currentNode.type === 'object' && currentNode.parent && currentNode.parent.type === 'property'){
+ lastPropertyName = jsonc.findNodeAtOffset(rootNode,currentNode.parent.offset)?.value
+ break;
+ }
+ currentNode = currentNode.parent;
+ }
+
+ if (lastPropertyName) {
+ return lastPropertyName;
+ } else {
+ return null;
+ }
+ }
+
+ isKey(document: vscode.TextDocument, position: vscode.Position): boolean {
+ const lineText = document.lineAt(position.line).text.substring(0, position.character);
+
+ if (/^\s*[\{,]\s*$/.test(lineText)) {
+ return true;
+ }
+
+ let depth = 0;
+ for (let i = position.character - 1; i >= 0; i--) {
+ const char = lineText[i];
+ switch (char) {
+ case ':':
+ if (depth === 0) return false;
+ break;
+ case '{':
+ case '[':
+ depth++;
+ break;
+ case '}':
+ case ']':
+ depth--;
+ break;
+ }
+ }
+
+ return true;
+ }
+
+
+
+
+ getAttributeName(rootNode: jsonc.Node, currentNode: jsonc.Node) {
+ if (!rootNode) {
+ return null
+ }
+ if (currentNode && currentNode.parent?.type === "object") {
+ return jsonc.findNodeAtOffset(rootNode, currentNode.offset)?.value;
+ }
+ if (currentNode && currentNode.parent && currentNode.parent?.type === "property") {
+ const propertyNode = currentNode.parent;
+ return jsonc.findNodeAtOffset(rootNode, propertyNode.offset)?.value;
+ }
+
+ return null;
+ }
+
+ isWithinQuotes(document: vscode.TextDocument, position: vscode.Position): boolean {
+ const lineText = document.lineAt(position.line).text;
+ const charPos = position.character;
+
+ let quoteOpen = false;
+ let quoteClose = false;
+
+ for (let i = charPos - 1; i >= 0; i--) {
+ if (lineText[i] === '"' && (i === 0 || lineText[i - 1] !== '\\')) {
+ quoteOpen = true;
+ break;
+ }
+ }
+
+ for (let i = charPos; i < lineText.length; i++) {
+ if (lineText[i] === '"' && (i === 0 || lineText[i - 1] !== '\\')) {
+ quoteClose = true;
+ break;
+ }
+ }
+
+ return quoteOpen && quoteClose;
+ }
+
+ isWithinObject(currentNode: jsonc.Node): boolean{
+ while (currentNode) {
+ if (currentNode.type === 'array') {
+ let objectWithinArray: jsonc.Node | undefined = currentNode;
+ while (objectWithinArray && objectWithinArray.type !== 'object') {
+ objectWithinArray = objectWithinArray.parent;
+ }
+ return objectWithinArray !== undefined && objectWithinArray.parent === currentNode;
+ } else if (currentNode.type === 'object') {
+ return true;
+ }
+ if(currentNode.parent){
+ currentNode = currentNode.parent;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/src/commands/fts/SearchWorkbench/contributor/booleanCbsContributor.ts b/src/commands/fts/SearchWorkbench/contributor/booleanCbsContributor.ts
new file mode 100644
index 00000000..0d4038b0
--- /dev/null
+++ b/src/commands/fts/SearchWorkbench/contributor/booleanCbsContributor.ts
@@ -0,0 +1,23 @@
+import { Node } from 'jsonc-parser'
+import { CBSContributor } from './autoComplete'
+
+export class booleanCbsContributor implements CBSContributor {
+
+ accept(key: string | null): boolean {
+ return key === "must" || key === "must_not" || key === "should";
+ }
+
+ contributeKey(parentKey: string, node: Node, suggestion: string[]) {
+ if (parentKey === "must") {
+ suggestion.push("conjuncts")
+ } else if (parentKey == "must_not" || parentKey == "should") {
+ suggestion.push("disjuncts")
+ }
+
+ }
+
+ contributeValue(attributeKey: string, node: Node, suggestion: string[]) {
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/commands/fts/SearchWorkbench/contributor/cbsTemplateDef.ts b/src/commands/fts/SearchWorkbench/contributor/cbsTemplateDef.ts
new file mode 100644
index 00000000..143e49d2
--- /dev/null
+++ b/src/commands/fts/SearchWorkbench/contributor/cbsTemplateDef.ts
@@ -0,0 +1,11 @@
+export class cbsTemplateDef {
+ key: string;
+ desc: string;
+ attrs: string[];
+
+ constructor(key: string, desc: string, attrs: string[]) {
+ this.key = key;
+ this.desc = desc;
+ this.attrs = attrs;
+ }
+}
diff --git a/src/commands/fts/SearchWorkbench/contributor/cbsTemplates.ts b/src/commands/fts/SearchWorkbench/contributor/cbsTemplates.ts
new file mode 100644
index 00000000..4bf7d765
--- /dev/null
+++ b/src/commands/fts/SearchWorkbench/contributor/cbsTemplates.ts
@@ -0,0 +1,279 @@
+import * as vscode from 'vscode';
+
+export class cbsTemplate {
+
+ static getQueryTemplate(existingKeys: string[]): vscode.CompletionItem {
+ const QUERY = 'query';
+ const snippetCompletion = new vscode.CompletionItem(QUERY, vscode.CompletionItemKind.Module);
+ snippetCompletion.detail = "Query string query syntax";
+
+ let snippetText = '';
+
+ if (!existingKeys.includes("query")) {
+ snippetText += '\t"query": "$1"\n';
+ }
+
+ snippetText = snippetText.replace(/,\n\}/g, '\n}');
+
+ snippetCompletion.insertText = new vscode.SnippetString(snippetText);
+
+ return snippetCompletion;
+ }
+
+
+ static getHighlightTemplate(): vscode.CompletionItem {
+
+ const snippetCompletion = new vscode.CompletionItem("Highlight Options", vscode.CompletionItemKind.Module);
+ snippetCompletion.detail = "Highlight Options";
+
+ let snippetText = `"highlight": {\n\t"style": "$1",\n\t"fields": [$2]\n}`;
+
+
+ snippetCompletion.insertText = new vscode.SnippetString(snippetText);
+
+ return snippetCompletion;
+ }
+
+ static getEmptyTemplate(name: string, desc: string): vscode.CompletionItem {
+ const emptyTemplate = new vscode.CompletionItem(name, vscode.CompletionItemKind.Module);
+ emptyTemplate.detail = desc;
+ emptyTemplate.documentation = new vscode.MarkdownString(`Inserts an empty JSON object for \`${name}\``);
+
+ let snippetText = `"${name}": {}`;
+
+ emptyTemplate.insertText = new vscode.SnippetString(snippetText);
+
+ // emptyTemplate.command = { title: 'Format Document', command: 'editor.action.formatDocument' };
+
+ return emptyTemplate;
+ }
+
+ static getGeoTemplate(key: string, desc: string, type: string, existingKeys: string[]): vscode.CompletionItem {
+ const geoCompletion = new vscode.CompletionItem(key, vscode.CompletionItemKind.Module);
+ geoCompletion.detail = desc;
+ let snippetText = '';
+
+ let cursorPosition = 1;
+
+ if (!existingKeys.includes("field")) {
+ snippetText += `"field": "\${${cursorPosition++}}",\n`;
+ }
+
+ if (!existingKeys.includes("geometry")) {
+ snippetText += '"geometry": {\n';
+ snippetText += '"shape": {\n';
+ snippetText += `"type": "${type}",\n`;
+
+ if (type === "GeometryCollection") {
+ snippetText += `"geometries": [\${${cursorPosition++}}]\n`;
+ } else {
+ snippetText += `"coordinates": [\${${cursorPosition++}}]\n`;
+ }
+
+ if (type === "Circle") {
+ snippetText += `, "radius": "\${${cursorPosition++}}"\n`;
+ }
+
+ snippetText += '},\n';
+ snippetText += `"relation": "\${${cursorPosition++}}"\n`;
+ snippetText += '}';
+ }
+
+ snippetText = snippetText.replace(/,\n}/g, '\n}');
+
+ geoCompletion.insertText = new vscode.SnippetString(snippetText);
+
+ return geoCompletion;
+ }
+
+
+
+ static getKNNTemplate(): vscode.CompletionItem {
+ const snippetCompletion = new vscode.CompletionItem("knn", vscode.CompletionItemKind.Module);
+ snippetCompletion.detail = "Knn filter";
+ let snippetText = '"knn": [{\n\t"k": $1,\n\t"field": "$2",\n\t"vector": [$3]\n}]';
+
+ snippetCompletion.insertText = new vscode.SnippetString(snippetText);
+
+ return snippetCompletion;
+ }
+
+ static getConjunctsTemplate(existingKeys: string[]): vscode.CompletionItem {
+ const CONJUNCTS_QUERY = 'conjuncts';
+ const snippetCompletion = new vscode.CompletionItem(CONJUNCTS_QUERY, vscode.CompletionItemKind.Module);
+ snippetCompletion.detail = "Query conjunction";
+
+ let snippetText = '';
+
+ if (!existingKeys.includes("conjuncts")) {
+ snippetText += '\t"conjuncts": [\n\t\t{\n\t\t\t$1\n\t\t}\n\t]\n';
+ }
+
+ snippetText = snippetText.replace(/,\n\}/g, '\n}');
+
+ snippetCompletion.insertText = new vscode.SnippetString(snippetText);
+
+ return snippetCompletion;
+ }
+
+ static getDisjunctsTemplate(existingKeys: string[]): vscode.CompletionItem {
+ const DISJUNCTS_QUERY = 'disjuncts';
+ const snippetCompletion = new vscode.CompletionItem(DISJUNCTS_QUERY, vscode.CompletionItemKind.Module);
+ snippetCompletion.detail = "Query disjunction";
+
+ let snippetText = '';
+
+ if (!existingKeys.includes("disjuncts")) {
+ snippetText += '\t"disjuncts": [\n\t\t{\n\t\t\t$1\n\t\t}\n\t]\n';
+ }
+
+ snippetText = snippetText.replace(/,\n\}/g, '\n}');
+
+ snippetCompletion.insertText = new vscode.SnippetString(snippetText);
+
+ return snippetCompletion;
+ }
+
+ static getMustTemplate(): vscode.CompletionItem {
+ const snippetCompletion = new vscode.CompletionItem('must');
+ snippetCompletion.detail = "Must boolean query template";
+ snippetCompletion.kind = vscode.CompletionItemKind.Module;
+
+ let snippetText = '';
+
+ snippetText += '"must": {\n\t"conjuncts": [\n\t\t{$1}\n\t]\n}';
+
+ snippetCompletion.insertText = new vscode.SnippetString(snippetText);
+
+ return snippetCompletion;
+ }
+
+ static getShouldTemplate(): vscode.CompletionItem {
+ const snippetCompletion = new vscode.CompletionItem('should');
+ snippetCompletion.detail = "Should boolean query template";
+ snippetCompletion.kind = vscode.CompletionItemKind.Module;
+
+ let snippetText = '';
+ snippetText += '"should": {\n\t"disjuncts": [\n\t\t{$1}\n\t]\n}';
+
+ snippetCompletion.insertText = new vscode.SnippetString(snippetText);
+
+ return snippetCompletion;
+ }
+
+ static getMustNotTemplate(): vscode.CompletionItem {
+ const snippetCompletion = new vscode.CompletionItem('must_not');
+ snippetCompletion.detail = "MustNot boolean query template";
+ snippetCompletion.kind = vscode.CompletionItemKind.Module;
+
+ let snippetText = '';
+
+ snippetText += '"must_not": {\n\t"disjuncts": [\n\t\t{$1}\n\t]\n}';
+
+ snippetCompletion.insertText = new vscode.SnippetString(snippetText);
+
+ return snippetCompletion;
+ }
+
+ static createGenericTemplate(key: string, description: string, attributes: string[]): vscode.CompletionItem {
+ const snippetCompletion = new vscode.CompletionItem(key);
+ snippetCompletion.detail = description;
+ snippetCompletion.kind = vscode.CompletionItemKind.Module;
+
+ let snippetText = '';
+
+ attributes.forEach((attr, index) => {
+ snippetText += `\t"${attr}": $${index + 1}`;
+ if (index < attributes.length - 1) {
+ snippetText += ",\n";
+ }
+ });
+
+
+ snippetCompletion.insertText = new vscode.SnippetString(snippetText);
+
+ return snippetCompletion;
+ }
+
+
+ static getRectangleTemplate(existingKeys: string[]): vscode.CompletionItem {
+ const RECTANGLE_QUERY = 'rectangle_query';
+ const snippetCompletion = new vscode.CompletionItem(RECTANGLE_QUERY, vscode.CompletionItemKind.Module);
+ snippetCompletion.detail = "Rectangle-Based Geopoint Query";
+
+ let snippetText = '';
+
+ if (!existingKeys.includes("field")) {
+ snippetText += '\t"field": "$1",\n';
+ }
+
+ if (!existingKeys.includes("top_left")) {
+ snippetText += `\t"top_left": {\n\t\t"lon": "$2",\n\t\t"lat": "$3"\n\t},\n`;
+ }
+
+ if (!existingKeys.includes("bottom_right")) {
+ snippetText += `\t"bottom_right": {\n\t\t"lon": "$4",\n\t\t"lat": "$5"\n\t}\n`;
+ }
+
+ snippetText = snippetText.replace(/,\n}$/g, '\n}');
+
+ snippetCompletion.insertText = new vscode.SnippetString(snippetText);
+
+ return snippetCompletion;
+ }
+
+ static getRadiusTemplate(existingKeys: string[]): vscode.CompletionItem {
+ const RADIUS_QUERY = 'radius_query';
+ const snippetCompletion = new vscode.CompletionItem(RADIUS_QUERY, vscode.CompletionItemKind.Module);
+ snippetCompletion.detail = "Distance/Radius-Based Geopoint Query";
+
+ let snippetText = '';
+
+ if (!existingKeys.includes("field")) {
+ snippetText += '\t"field": "$1",\n';
+ }
+
+ if (!existingKeys.includes("distance")) {
+ snippetText += '\t"distance": "$2",\n';
+ }
+
+ if (!existingKeys.includes("location")) {
+ snippetText += `\t"location": {\n\t\t"lon": "$3",\n\t\t"lat": "$4"\n\t}\n`;
+ }
+
+ snippetText = snippetText.replace(/,\n\}/g, '\n}');
+
+ snippetCompletion.insertText = new vscode.SnippetString(snippetText);
+
+ return snippetCompletion;
+ }
+
+ static getVectorTemplate(existingKeys: string[]): vscode.CompletionItem {
+ const snippetCompletion = new vscode.CompletionItem('vector_query');
+ snippetCompletion.detail = "Vector search filter";
+ snippetCompletion.kind = vscode.CompletionItemKind.Module;
+
+ let snippetText = '';
+
+ if (!existingKeys.includes("field")) {
+ snippetText += '"field": "$1",\n';
+ }
+ if (!existingKeys.includes("k")) {
+ snippetText += '"k": $2,\n';
+ }
+ if (!existingKeys.includes("vector")) {
+ snippetText += '"vector": [$3]\n';
+ }
+
+ snippetText = snippetText.replace(/,\n$/, '\n');
+
+ snippetCompletion.insertText = new vscode.SnippetString(snippetText);
+ // snippetCompletion.command = {
+ // title: "Format Document",
+ // command: "editor.action.formatDocument"
+ // };
+
+ return snippetCompletion;
+ }
+
+}
\ No newline at end of file
diff --git a/src/commands/fts/SearchWorkbench/contributor/consistencyCbsContributor.ts b/src/commands/fts/SearchWorkbench/contributor/consistencyCbsContributor.ts
new file mode 100644
index 00000000..e0eb901c
--- /dev/null
+++ b/src/commands/fts/SearchWorkbench/contributor/consistencyCbsContributor.ts
@@ -0,0 +1,27 @@
+import { Node } from 'jsonc-parser'
+import { CBSContributor } from './autoComplete'
+import * as vscode from 'vscode';
+
+export class consistencyCbsContributor implements CBSContributor {
+ public static keys: string[] = ["vectors", "level", "results"];
+
+ accept(key: string | null): boolean {
+ return key === "consistency";
+ }
+
+ contributeKey(parentKey: string, node: Node, suggestion: string[], result: vscode.CompletionItem[], existingKeys: string[]) {
+ suggestion.push(...consistencyCbsContributor.keys)
+
+ }
+
+ contributeValue(attributeKey: string, node: Node, suggestion: string[], fields:string[]) {
+ if (attributeKey == "level") {
+ suggestion.push("at_plus", "not_bounded")
+ }
+ else if (attributeKey == "results") {
+ suggestion.push("complete")
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/commands/fts/SearchWorkbench/contributor/ctlCbsContributor.ts b/src/commands/fts/SearchWorkbench/contributor/ctlCbsContributor.ts
new file mode 100644
index 00000000..6c5ae789
--- /dev/null
+++ b/src/commands/fts/SearchWorkbench/contributor/ctlCbsContributor.ts
@@ -0,0 +1,21 @@
+import { Node } from 'jsonc-parser'
+import { CBSContributor } from './autoComplete'
+import * as vscode from 'vscode';
+
+export class ctlCbsContributor implements CBSContributor {
+ public static keys: string[] = ["timeout", "consistency"];
+
+ accept(key: string | null): boolean {
+ return key === "ctl";
+ }
+
+ contributeKey(parentKey: string, node: Node, suggestion: string[], result: vscode.CompletionItem[], existingKeys: string[]) {
+ suggestion.push(...ctlCbsContributor.keys);
+
+ }
+
+ contributeValue(attributeKey: string, node: Node, suggestion: string[], fields:string[]) {
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/commands/fts/SearchWorkbench/contributor/fieldsContributor.ts b/src/commands/fts/SearchWorkbench/contributor/fieldsContributor.ts
new file mode 100644
index 00000000..b8b09681
--- /dev/null
+++ b/src/commands/fts/SearchWorkbench/contributor/fieldsContributor.ts
@@ -0,0 +1,88 @@
+import { CacheService, IBucketCache } from "../../../../util/cacheService/cacheService";
+import { getActiveConnection } from "../../../../util/connections";
+import { CouchbaseRestAPI } from "../../../../util/apis/CouchbaseRestAPI";
+import { SearchIndexParser } from "../indexParser/indexParser";
+import { logger } from "../../../../logger/logger";
+
+
+export class fieldsContributor {
+
+ static async getFieldNames(bucketName: string, indexName: string): Promise {
+ const cache = new CacheService()
+ const suggestions: string[] = []
+ const connection = getActiveConnection();
+ if (!connection) {
+ return [];
+ }
+ const api = new CouchbaseRestAPI(connection);
+
+ cache.loadCache(connection);
+ const bucketCache = cache.getCache(bucketName);
+ const result = await api.fetchSearchIndexDefinition(indexName);
+ if (!bucketCache) {
+ return []
+ }
+ const index = result?.indexDef
+ if (index) {
+ try {
+ const fields = SearchIndexParser.extractPropertiesMap(index);
+ fields.set(SearchIndexParser.getDefaultField(index), '');
+
+ const isDynamic = SearchIndexParser.isIndexDynamic(index);
+ if (isDynamic) {
+ const cols = SearchIndexParser.listCollections(index);
+ for (const prop of cols) {
+ if (!SearchIndexParser.isCollectionDynamicallyIndexed(index, prop)) {
+ continue;
+ }
+
+ if (prop.includes('.')) {
+ const parts = prop.split('.');
+ const additionalFields = this.extractFieldsFromCollection(bucketCache, parts[0], parts[1]);
+ if (additionalFields && typeof additionalFields[0] === 'object' && additionalFields[0] !== null) {
+ const entries = Object.entries(additionalFields[0] as { [key: string]: any });
+
+ entries.map(property => {
+ const key = property[0];
+ const value = property[1];
+
+ if (typeof value === 'object' && value !== null && 'type' in value) {
+ const type = value.type;
+ if (type !== 'array') {
+ if (type === 'object') {
+ Object.entries(value.value).forEach(([subKey, _]) => {
+ const fullKey = `${key}.${subKey}`;
+ fields.set(fullKey, '')
+ });
+
+ }
+ fields.set(key, value)
+ }
+
+ }
+ });
+ }
+ }
+ }
+ }
+ suggestions.push(...fields.keys());
+ return suggestions;
+ } catch (e) {
+ logger.debug(`An error occurred while trying to extract fields from index: ${indexName}` + e);
+ }
+ }
+ return [];
+ }
+
+
+ static extractFieldsFromCollection(bucketCache: IBucketCache, scopeName: string, collectionName: string): any {
+ const scope = bucketCache.scopes.get(scopeName);
+ if (scope) {
+ const collection = scope.collections.get(collectionName);
+ return collection?.schema?.patterns
+ }
+ return
+ }
+}
+
+
diff --git a/src/commands/fts/SearchWorkbench/contributor/geometryCbsContributor.ts b/src/commands/fts/SearchWorkbench/contributor/geometryCbsContributor.ts
new file mode 100644
index 00000000..fc77fa7b
--- /dev/null
+++ b/src/commands/fts/SearchWorkbench/contributor/geometryCbsContributor.ts
@@ -0,0 +1,24 @@
+import { Node } from 'jsonc-parser'
+import { CBSContributor } from './autoComplete'
+import * as vscode from 'vscode';
+
+export class geometryCbsContributor implements CBSContributor {
+ public static keys: string[] = ["shape", "relation"];
+
+ accept(key: string | null): boolean {
+ return key === "geometry";
+ }
+
+ contributeKey(parentKey: string, node: Node, suggestion: string[], result: vscode.CompletionItem[], existingKeys: string[]) {
+ suggestion.push(...geometryCbsContributor.keys)
+
+ }
+
+ contributeValue(attributeKey: string, node: Node, suggestion: string[], fields:string[]) {
+ if (attributeKey == "relation") {
+ suggestion.push("intersects", "contains", "within")
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/commands/fts/SearchWorkbench/contributor/highlightCbsContributor.ts b/src/commands/fts/SearchWorkbench/contributor/highlightCbsContributor.ts
new file mode 100644
index 00000000..8b10f23f
--- /dev/null
+++ b/src/commands/fts/SearchWorkbench/contributor/highlightCbsContributor.ts
@@ -0,0 +1,24 @@
+import { Node } from 'jsonc-parser'
+import { CBSContributor } from './autoComplete'
+import * as vscode from 'vscode';
+
+export class highlightCbsContributor implements CBSContributor {
+ public static keys: string[] = ["style", "fields"];
+
+ accept(key: string | null): boolean {
+ return key === "highlight";
+ }
+
+ contributeKey(parentKey: string, node: Node, suggestion: string[], result: vscode.CompletionItem[], existingKeys: string[]) {
+ suggestion.push(...highlightCbsContributor.keys)
+
+ }
+
+ contributeValue(attributeKey: string, node: Node, suggestion: string[]) {
+ if (attributeKey == "style") {
+ suggestion.push("ansi", "html")
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/commands/fts/SearchWorkbench/contributor/knnCbsContributor.ts b/src/commands/fts/SearchWorkbench/contributor/knnCbsContributor.ts
new file mode 100644
index 00000000..1de87c96
--- /dev/null
+++ b/src/commands/fts/SearchWorkbench/contributor/knnCbsContributor.ts
@@ -0,0 +1,26 @@
+import { Node } from 'jsonc-parser'
+import { CBSContributor } from './autoComplete'
+import * as vscode from 'vscode';
+import { cbsTemplate } from './cbsTemplates';
+
+export class knnCbsContributor implements CBSContributor {
+ public static keys: string[] = ["k", "field", "vector", "boost"];
+
+ accept(key: string | null): boolean {
+ return key === "knn";
+ }
+
+ contributeKey(parentKey: string, node: Node, suggestion: string[], result: vscode.CompletionItem[], existingKeys: string[] ) {
+ suggestion.push(...knnCbsContributor.keys)
+ result.push(cbsTemplate.getVectorTemplate(existingKeys))
+
+ }
+
+ contributeValue(attributeKey: string, node: Node, suggestion: string[], fields:string[]) {
+ if (attributeKey == "field") {
+ suggestion.push(...fields);
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/commands/fts/SearchWorkbench/contributor/locationCbsContributor.ts b/src/commands/fts/SearchWorkbench/contributor/locationCbsContributor.ts
new file mode 100644
index 00000000..e4f650bc
--- /dev/null
+++ b/src/commands/fts/SearchWorkbench/contributor/locationCbsContributor.ts
@@ -0,0 +1,21 @@
+import { Node } from 'jsonc-parser'
+import { CBSContributor } from './autoComplete'
+import * as vscode from 'vscode';
+
+export class locationCbsContributor implements CBSContributor {
+ public static keys: string[] = ["lat", "lon"];
+
+ accept(key: string | null): boolean {
+ return key === "location" || key === "top_left" || key === "bottom_right";
+ }
+
+ contributeKey(parentKey: string, node: Node, suggestion: string[], result: vscode.CompletionItem[], existingKeys: string[]) {
+ suggestion.push(...locationCbsContributor.keys)
+
+ }
+
+ contributeValue(attributeKey: string, node: Node, suggestion: string[], fields: string[]) {
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/commands/fts/SearchWorkbench/contributor/queryCbsContributor.ts b/src/commands/fts/SearchWorkbench/contributor/queryCbsContributor.ts
new file mode 100644
index 00000000..e70e1a2e
--- /dev/null
+++ b/src/commands/fts/SearchWorkbench/contributor/queryCbsContributor.ts
@@ -0,0 +1,253 @@
+import { Node } from "jsonc-parser";
+import { CompletionItem } from "vscode";
+import { CBSContributor } from "./autoComplete";
+import { cbsTemplate } from "./cbsTemplates";
+import { cbsTemplateDef } from "./cbsTemplateDef";
+import * as vscode from 'vscode';
+
+export class queryCbsContributor implements CBSContributor {
+
+ public static allQueryKeys: Set = new Set();
+ private boolQueries = ["must", "must_not", "should"];
+ private compound = ["disjuncts", "conjuncts"];
+ private query = ["boost", "conjuncts"];
+ private match = ["match", "analyzer", "operator", "boost", "fuzziness", "prefix_length", "field"];
+ private matchPhrase = ["match_phrase", "analyzer", "operator", "boost", "fuzziness", "prefix_length", "field"];
+ private bool = ["bool", "boost", "field"];
+ private prefix = ["prefix", "boost", "field"];
+ private regexp = ["regexp", "boost", "field"];
+ private terms = ["terms", "boost", "field"];
+ private cidr = ["cidr", "boost", "field"];
+ private wildcard = ["wildcard", "boost", "field"];
+ private term = ["term", "boost", "field", "fuzziness"];
+ private polygon = ["polygon_points", "boost", "field"];
+ private numeric = ["min", "max", "inclusive_min", "inclusive_max", "field", "boost"];
+ private date = ["start", "end", "inclusive_start", "inclusive_end", "field", "boost"];
+ private radius = ["location", "distance", "field", "boost"];
+ private rectangle = ["top_left", "bottom_right", "field", "boost"];
+ private geometry = ["geometry", "field", "boost"];
+ private special = ["match_all", "match_none"];
+
+
+ constructor() {
+ this.addAllKeys();
+ }
+
+ private addAllKeys(): void {
+
+ ["query",
+ ...this.boolQueries,
+ ...this.compound,
+ ...this.query,
+ ...this.match,
+ ...this.matchPhrase,
+ ...this.bool,
+ ...this.prefix,
+ ...this.regexp,
+ ...this.terms,
+ ...this.cidr,
+ ...this.wildcard,
+ ...this.term,
+ ...this.polygon,
+ ...this.numeric,
+ ...this.date,
+ ...this.radius,
+ ...this.rectangle,
+ ...this.geometry,
+ ...this.special].forEach(key => {
+ queryCbsContributor.allQueryKeys.add(key);
+ });
+ }
+
+ accept(key: string | null): boolean {
+ return key === "query" || key === "disjuncts" || key === "conjuncts";
+ }
+
+ contributeKey(parentKey: string | null, node: Node, suggestion: string[], result: CompletionItem[], existingKeys: string[]) {
+
+ if (existingKeys.length === 0) {
+ queryCbsContributor.allQueryKeys.forEach(key => suggestion.push(key));
+ }
+
+ if (this.boolQueries.some(query => existingKeys.includes(query))) {
+ this.boolQueries.filter(query => !existingKeys.includes(query)).forEach(query => {
+ suggestion.push(query);
+ });
+ this.addBooleanTemplates(existingKeys, result);
+ } else if (!existingKeys.includes("query") && !this.compound.some(comp => existingKeys.includes(comp))) {
+
+ if (!existingKeys.includes("field")) {
+ suggestion.push("field");
+ }
+
+ if (existingKeys.length === 0) {
+ result.push(cbsTemplate.getQueryTemplate(existingKeys));
+ suggestion.push("query");
+ this.addBooleanTemplates(existingKeys, result);
+ result.push(cbsTemplate.getConjunctsTemplate(existingKeys));
+ result.push(cbsTemplate.getDisjunctsTemplate(existingKeys));
+ result.push(cbsTemplate.getEmptyTemplate("match_all", "match_all template"))
+ result.push(cbsTemplate.getEmptyTemplate("match_none", "match_all template"))
+ }
+
+ const boolContributors = this.getBoolContributors(existingKeys, result);
+ const cidrContributors = this.getCidrContributors(existingKeys, result);
+ const prefixContributors = this.getPrefixContributors(existingKeys, result)
+ const regexexpContributors = this.getRegexpContributors(existingKeys, result)
+ const termContributors = this.getTermContributors(existingKeys, result)
+ const termsContributors = this.getTermsContributors(existingKeys, result)
+ const rectangleContributors = this.getRectangleContributors(existingKeys, result)
+ const polygonContributors = this.getPolygonContributors(existingKeys, result)
+ const radiusContributors = this.getRadiusContributors(existingKeys, result)
+ const wildCardContributors = this.getWildCardContributors(existingKeys, result)
+ const numericContributors = this.getNumericContributors(existingKeys, result)
+ const dateContributors = this.getDateContributors(existingKeys, result)
+ const matchQuery = this.getMatchContributors(existingKeys, result)
+ const matchPhraseQuery = this.getMatchPhraseContributors(existingKeys, result)
+ this.addGeometryContributors(existingKeys, result)
+ const allContributors = [...boolContributors, ...cidrContributors, ...prefixContributors, ...regexexpContributors, ...termContributors, ...termsContributors, ...rectangleContributors, ...polygonContributors, ...radiusContributors, ...wildCardContributors, ...numericContributors, ...dateContributors, ...matchQuery, ...matchPhraseQuery];
+
+ allContributors.forEach(contributor => {
+ if (!suggestion.includes(contributor)) {
+ suggestion.push(contributor);
+ }
+ });
+
+
+ }
+ }
+
+ addBooleanTemplates(existingKeys: string[], result: CompletionItem[]) {
+ if (!existingKeys.includes("must")) {
+ result.push(cbsTemplate.getMustTemplate())
+ }
+ if (!existingKeys.includes("must_not")) {
+ result.push(cbsTemplate.getMustNotTemplate())
+ }
+ if (!existingKeys.includes("should")) {
+ result.push(cbsTemplate.getShouldTemplate())
+ }
+
+ }
+
+ addGeometryContributors(existingKeys: string[], result: CompletionItem[]) {
+ if (existingKeys.every(key => this.geometry.includes(key))) {
+ result.push(cbsTemplate.getGeoTemplate("point_geo_query", "Point GeoJSON Query", "Point", existingKeys))
+ result.push(cbsTemplate.getGeoTemplate("linestring_geo_query", "LineString GeoJSON Query", "Point", existingKeys))
+ result.push(cbsTemplate.getGeoTemplate("polygon_geo_query", "Polygon GeoJSON Query", "Polygon", existingKeys))
+ result.push(cbsTemplate.getGeoTemplate("multi_point_geo_query", "MultiPoint GeoJSON Query", "MultiPoint", existingKeys))
+ result.push(cbsTemplate.getGeoTemplate("multi_linestring_geo_query", "MultiLineString GeoJSON Query", "MultiLineString", existingKeys))
+ result.push(cbsTemplate.getGeoTemplate("multi_polygon_geo_query", "MultiPolygon GeoJSON Query", "MultiPolygon", existingKeys))
+ result.push(cbsTemplate.getGeoTemplate("envelope_geo_query", "Envelope GeoJSON Query", "Envelope", existingKeys))
+ result.push(cbsTemplate.getGeoTemplate("circle_geo_query", "Circle GeoJSON Query", "Circle", existingKeys))
+ result.push(cbsTemplate.getGeoTemplate("geometry_col_geo_query", "Geometry Collection GeoJSON Query", "GeometryCollection", existingKeys))
+ }
+ }
+
+ getPolygonContributors(existingKeys: string[], result: CompletionItem[]): string[] {
+ const template = this.getSingleTemplate("polygon_points_query", "Polygon Based Geopoint queries", this.polygon);
+ return this.genericContributor(this.polygon, existingKeys, result, [template]);
+ }
+
+ getRectangleContributors(existingKeys: string[], result: CompletionItem[]): string[] {
+ if (existingKeys.every(key => this.rectangle.includes(key))) {
+ result.push(cbsTemplate.getRectangleTemplate(existingKeys))
+ }
+ return this.genericContributor(this.rectangle, existingKeys, result, [])
+ }
+
+ getRadiusContributors(existingKeys: string[], result: CompletionItem[]): string[] {
+ if (existingKeys.every(key => this.radius.includes(key))) {
+ result.push(cbsTemplate.getRadiusTemplate(existingKeys))
+ }
+ return this.genericContributor(this.radius, existingKeys, result, [])
+ }
+
+ getBoolContributors(existingKeys: string[], result: CompletionItem[]): string[] {
+ const template = this.getSingleTemplate("bool_query", "Boolean query", this.bool);
+ return this.genericContributor(this.bool, existingKeys, result, [template]);
+ }
+
+ getCidrContributors(existingKeys: string[], result: CompletionItem[]): string[] {
+ const template = this.getSingleTemplate("cidr_query", "CIDR query", this.cidr);
+ return this.genericContributor(this.cidr, existingKeys, result, [template]);
+ }
+
+
+ getPrefixContributors(existingKeys: string[], result: CompletionItem[]): string[] {
+ const template = this.getSingleTemplate("prefix_query", "Prefix query", this.prefix);
+ return this.genericContributor(this.prefix, existingKeys, result, [template]);
+ }
+
+ getRegexpContributors(existingKeys: string[], result: CompletionItem[]): string[] {
+ const template = this.getSingleTemplate("regex_query", "Regex query", this.regexp);
+ return this.genericContributor(this.regexp, existingKeys, result, [template]);
+ }
+
+ getTermContributors(existingKeys: string[], result: CompletionItem[]): string[] {
+ const template = this.getSingleTemplate("term_query", "Term query", this.term);
+ return this.genericContributor(this.term, existingKeys, result, [template]);
+ }
+
+ getTermsContributors(existingKeys: string[], result: CompletionItem[]): string[] {
+ const template = this.getSingleTemplate("terms_query", "Terms query", this.terms);
+ return this.genericContributor(this.terms, existingKeys, result, [template]);
+ }
+
+ getWildCardContributors(existingKeys: string[], result: CompletionItem[]): string[] {
+ const template = this.getSingleTemplate("wildcard_query", "Wildcard query", this.wildcard);
+ return this.genericContributor(this.wildcard, existingKeys, result, [template]);
+ }
+
+ getNumericContributors(existingKeys: string[], result: CompletionItem[]): string[] {
+ const numericRangeTemplate = this.getSingleTemplate("numeric_range", "Simple numeric range search", ["field", "min", "max"]);
+ const numericRangeAllTemplate = this.getSingleTemplate("numeric_range_all", "Data numeric search with all attributes", this.numeric)
+ return this.genericContributor(this.numeric, existingKeys, result, [numericRangeTemplate, numericRangeAllTemplate]);
+ }
+
+ getDateContributors(existingKeys: string[], result: CompletionItem[]): string[] {
+ const dateRangeTemplate = this.getSingleTemplate("date_range", "Simple data range search", ["field", "start", "end"]);
+ const dateRangeAllTemplate = this.getSingleTemplate("date_range_all", "Data range search with all attributes", this.date)
+ return this.genericContributor(this.date, existingKeys, result, [dateRangeTemplate, dateRangeAllTemplate]);
+ }
+
+ getMatchContributors(existingKeys: string[], result: CompletionItem[]): string[] {
+ const matchQueryTemplate = this.getSingleTemplate("match_query", "Simple match query search", ["field", "match"]);
+ const matchQueryAllTemplate = this.getSingleTemplate("match_query_all", "Match query search with all attributes", this.match)
+ return this.genericContributor(this.match, existingKeys, result, [matchQueryTemplate, matchQueryAllTemplate]);
+ }
+
+ getMatchPhraseContributors(existingKeys: string[], result: CompletionItem[]): string[] {
+ const matchPhraseQueryTemplate = this.getSingleTemplate("match_phrase_query", "Simple match phrase query search", ["field", "match_phrase"]);
+ const matchPhraseQueryAllTemplate = this.getSingleTemplate("match_phrase_query_all", "Match phrase query search with all attributes", this.matchPhrase)
+ return this.genericContributor(this.matchPhrase, existingKeys, result, [matchPhraseQueryTemplate, matchPhraseQueryAllTemplate]);
+ }
+
+ genericContributor(keys: string[], existingKeys: string[], result: vscode.CompletionItem[], templateDefs: cbsTemplateDef[]): string[] {
+ if (existingKeys.every(key => keys.includes(key))) {
+ templateDefs.forEach(def => {
+ def.attrs = def.attrs.filter(attr => !existingKeys.includes(attr) && attr !== 'boost');
+ result.push(cbsTemplate.createGenericTemplate(def.key, def.desc, def.attrs))
+ });
+ return keys;
+ } else {
+ return [];
+ }
+ }
+
+ private getSingleTemplate(key: string, desc: string, fields: string[]): cbsTemplateDef {
+ return new cbsTemplateDef(key, desc, fields);
+ }
+
+ contributeValue(attributeKey: string | null, node: Node, suggestion: string[], fields: string[]) {
+
+ if (attributeKey == "operator") {
+ suggestion.push("or", "and");
+ }
+ else if (attributeKey == "field") {
+ suggestion.push(...fields);
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/commands/fts/SearchWorkbench/contributor/shapeCbsContributor.ts b/src/commands/fts/SearchWorkbench/contributor/shapeCbsContributor.ts
new file mode 100644
index 00000000..52b2615d
--- /dev/null
+++ b/src/commands/fts/SearchWorkbench/contributor/shapeCbsContributor.ts
@@ -0,0 +1,76 @@
+import { Node } from "jsonc-parser";
+import { CompletionItem } from "vscode";
+import { CBSContributor } from "./autoComplete";
+
+export class shapeCbsContributor implements CBSContributor {
+
+ accept(key: string | null): boolean {
+ return key === "shape"
+ }
+
+ contributeKey(parentKey: string | null, node: Node, suggestion: string[], result: CompletionItem[], existingKeys: string[]) {
+ let type: string = "";
+ if (node.type === 'string') {
+ if (node.parent && node.parent.parent) {
+ node = node.parent.parent
+ }
+ }
+ if (!node.children) {
+ return
+ }
+ for (const propertyNode of node.children) {
+ if (propertyNode.type === 'property' && propertyNode.children) {
+ let keyNode = null;
+ let valueNode = null;
+
+ for (const childNode of propertyNode.children) {
+ if (childNode.type === 'string' && childNode.value === 'type') {
+ keyNode = childNode;
+ } else if (childNode.type === 'string') {
+ valueNode = childNode;
+ }
+
+ if (keyNode && valueNode) {
+ type = valueNode.value;
+ }
+ }
+ }
+ }
+
+ if (type === "Circle") {
+ suggestion.push("coordinates")
+ suggestion.push("type")
+ suggestion.push("radius")
+ } else if (type === "GeometryCollection") {
+ suggestion.push("type")
+ suggestion.push("geometries")
+ } else if (type === "") {
+ suggestion.push("coordinates")
+ suggestion.push("type")
+ suggestion.push("radius")
+ suggestion.push("geometries")
+ } else {
+ suggestion.push("coordinates")
+ suggestion.push("type")
+ }
+
+
+ }
+
+ contributeValue(attributeKey: string | null, node: Node, suggestion: string[], fields: string[]) {
+ if (attributeKey === "type") {
+ suggestion.push("Point");
+ suggestion.push("LineString");
+ suggestion.push("Polygon");
+ suggestion.push("MultiPoint");
+ suggestion.push("MultiLineString");
+ suggestion.push("MultiPolygon");
+ suggestion.push("GeometryCollection");
+ suggestion.push("Circle");
+ suggestion.push("Envelope");
+ }
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/commands/fts/SearchWorkbench/documentation/documentationProvider.ts b/src/commands/fts/SearchWorkbench/documentation/documentationProvider.ts
new file mode 100644
index 00000000..c1db1a33
--- /dev/null
+++ b/src/commands/fts/SearchWorkbench/documentation/documentationProvider.ts
@@ -0,0 +1,279 @@
+import * as vscode from 'vscode';
+import * as jsonc from 'jsonc-parser';
+import * as fs from 'fs';
+import * as path from 'path';
+import { logger } from '../../../../logger/logger';
+
+
+
+export class CbsJsonHoverProvider implements vscode.HoverProvider {
+ private context: vscode.ExtensionContext;
+
+ constructor(context: vscode.ExtensionContext) {
+ this.context = context;
+ }
+
+ provideHover(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): vscode.ProviderResult {
+ if (!this.isCbsJsonFile(document)) {
+ return null;
+ }
+
+ const offset = document.offsetAt(position);
+ const text = document.getText();
+ const rootNode = jsonc.parseTree(text);
+ if (!rootNode){
+ return
+ }
+ let node = jsonc.findNodeAtOffset(rootNode, offset);
+ node = node?.parent
+
+ if (node && node.type === 'property' && node.children && node.children[0].type === 'string') {
+
+ const key = node.children[0].value;
+ const parentNode = jsonc.findNodeAtOffset(rootNode, node.parent!.offset);
+ const type = this.getParentType(parentNode);
+
+ const documentation = this.getDocumentationForKey(key, type);
+ if (documentation) {
+ return new vscode.Hover(documentation);
+ }
+ }
+
+ return null;
+ }
+
+ private isCbsJsonFile(document: vscode.TextDocument): boolean {
+ return document.fileName.endsWith('.cbs.json');
+ }
+
+ private getParentType(node: jsonc.Node | undefined): string | null {
+ if (!node || !node.parent) return null;
+ if (node.parent.type === 'property') {
+ return node.parent.children![0].value;
+ }
+ return null;
+ }
+
+
+ private getDocumentationForKey(key: string, type: string | null): vscode.MarkdownString | null {
+ let filePath: string;
+
+ switch (key) {
+ case "query":
+ filePath = type === null ? "/docs/search/query.md" : "/docs/search/query_string.md";
+ break;
+ case "must":
+ filePath = "/docs/search/must.md";
+ break;
+ case "must_not":
+ filePath = "/docs/search/must_not.md";
+ break;
+ case "should":
+ filePath = "/docs/search/should.md";
+ break;
+ case "conjuncts":
+ filePath = "/docs/search/conjuncts.md";
+ break;
+ case "disjuncts":
+ filePath = "/docs/search/disjuncts.md";
+ break;
+ case "match":
+ filePath = "/docs/search/match.md";
+ break;
+ case "match_phrase":
+ filePath = "/docs/search/match_phrase.md";
+ break;
+ case "bool":
+ filePath = "/docs/search/bool.md";
+ break;
+ case "prefix":
+ filePath = "/docs/search/prefix.md";
+ break;
+ case "regexp":
+ filePath = "/docs/search/regexp.md";
+ break;
+ case "term":
+ filePath = "/docs/search/term.md";
+ break;
+ case "terms":
+ filePath = "/docs/search/terms.md";
+ break;
+ case "wildcard":
+ filePath = "/docs/search/wildcard.md";
+ break;
+ case "min":
+ filePath = "/docs/search/min.md";
+ break;
+ case "max":
+ filePath = "/docs/search/max.md";
+ break;
+ case "inclusive_max":
+ filePath = "/docs/search/inclusive_max.md";
+ break;
+ case "inclusive_min":
+ filePath = "/docs/search/inclusive_min.md";
+ break;
+ case "start":
+ filePath = "/docs/search/start.md";
+ break;
+ case "end":
+ filePath = "/docs/search/end.md";
+ break;
+ case "inclusive_start":
+ filePath = "/docs/search/inclusive_start.md";
+ break;
+ case "inclusive_end":
+ filePath = "/docs/search/inclusive_end.md";
+ break;
+ case "cidr":
+ filePath = "/docs/search/cidr.md";
+ break;
+ case "knn":
+ filePath = "/docs/search/knn.md";
+ break;
+ case "k":
+ filePath = "/docs/search/k.md";
+ break;
+ case "vector":
+ filePath = "/docs/search/vector.md";
+ break;
+ case "distance":
+ filePath = "/docs/search/distance.md";
+ break;
+ case "location":
+ filePath = "/docs/search/location.md";
+ break;
+ case "lat":
+ filePath = "/docs/search/lat.md";
+ break;
+ case "lon":
+ filePath = "/docs/search/lon.md";
+ break;
+ case "top_left":
+ filePath = "/docs/search/top_left.md";
+ break;
+ case "bottom_right":
+ filePath = "/docs/search/bottom_right.md";
+ break;
+ case "polygon_points":
+ filePath = "/docs/search/polygon_points.md";
+ break;
+ case "geometry":
+ filePath = "/docs/search/geometry.md";
+ break;
+ case "shape":
+ filePath = "/docs/search/shape.md";
+ break;
+ case "type":
+ filePath = type === "shape" ? "/docs/search/type_shape.md" : "/docs/search/type_facet.md";
+ break;
+ case "coordinates":
+ filePath = "/docs/search/coordinates.md";
+ break;
+ case "relation":
+ filePath = "/docs/search/relation.md";
+ break;
+ case "geometries":
+ filePath = "/docs/search/geometries.md";
+ break;
+ case "radius":
+ filePath = "/docs/search/radius.md";
+ break;
+ case "match_all":
+ filePath = "/docs/search/match_all.md";
+ break;
+ case "match_none":
+ filePath = "/docs/search/match_none.md";
+ break;
+ case "analyzer":
+ filePath = "/docs/search/analyzer.md";
+ break;
+ case "boost":
+ filePath = "/docs/search/boost.md";
+ break;
+ case "field":
+ filePath = "/docs/search/field.md";
+ break;
+ case "fuzziness":
+ filePath = "/docs/search/fuzziness.md";
+ break;
+ case "operator":
+ filePath = "/docs/search/operator.md";
+ break;
+ case "prefix_length":
+ filePath = "/docs/search/prefix_length.md";
+ break;
+ case "size":
+ case "limit":
+ filePath = "/docs/search/limit.md";
+ break;
+ case "from":
+ case "offset":
+ filePath = "/docs/search/offset.md";
+ break;
+ case "fields":
+ filePath = "/docs/search/fields.md";
+ break;
+ case "facets":
+ filePath = "/docs/search/facets.md";
+ break;
+ case "explain":
+ filePath = "/docs/search/explain.md";
+ break;
+ case "sort":
+ filePath = "/docs/search/sort.md";
+ break;
+ case "includeLocations":
+ filePath = "/docs/search/includeLocations.md";
+ break;
+ case "score":
+ filePath = "/docs/search/score.md";
+ break;
+ case "search_after":
+ filePath = "/docs/search/search_after.md";
+ break;
+ case "search_before":
+ filePath = "/docs/search/search_before.md";
+ break;
+ case "collections":
+ filePath = "/docs/search/collections.md";
+ break;
+ case "ctl":
+ filePath = "/docs/search/ctl.md";
+ break;
+ case "timeout":
+ filePath = "/docs/search/timeout.md";
+ break;
+ case "consistency":
+ filePath = "/docs/search/consistency.md";
+ break;
+ case "vectors":
+ filePath = "/docs/search/vectors.md";
+ break;
+ case "level":
+ filePath = "/docs/search/level.md";
+ break;
+ case "results":
+ filePath = "/docs/search/results.md";
+ break;
+ case "highlight":
+ filePath = "/docs/search/highlight.md";
+ break;
+ case "style":
+ filePath = "/docs/search/style.md";
+ break;
+ default:
+ return new vscode.MarkdownString("No documentation available for this key.");
+ }
+ try {
+ const fullPath = path.join(this.context.extensionPath, filePath);
+ const content = fs.readFileSync(fullPath, 'utf8');
+ return new vscode.MarkdownString(content);
+ } catch (error) {
+ logger.error(`Error reading documentation file: ${error}`);
+ // Return empty for no documentation
+ return new vscode.MarkdownString("");
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/commands/fts/SearchWorkbench/indexParser/indexParser.ts b/src/commands/fts/SearchWorkbench/indexParser/indexParser.ts
new file mode 100644
index 00000000..f901c91d
--- /dev/null
+++ b/src/commands/fts/SearchWorkbench/indexParser/indexParser.ts
@@ -0,0 +1,62 @@
+export class SearchIndexParser {
+ static extractPropertiesMap(index: any): Map {
+ const rootNode = index;
+ const propertiesMap = new Map();
+ const typesNode = rootNode?.params?.mapping?.types;
+
+ if (typesNode && typeof typesNode === 'object') {
+ for (const [_, typeValue] of Object.entries(typesNode)) {
+ if (typeValue && typeof typeValue === 'object' && 'properties' in typeValue) {
+ const propertiesNode = (typeValue as any).properties;
+ this.extractProperties(propertiesNode, '', propertiesMap);
+ }
+ }
+ }
+ return propertiesMap;
+ }
+
+ private static extractProperties(node: any, parentKey: string, propertiesMap: Map) {
+ if (node && typeof node === 'object') {
+ for (const [key, value] of Object.entries(node)) {
+ if (typeof value === 'object' && value) {
+ if ('properties' in value) {
+ const newParentKey = parentKey ? `${parentKey}.${key}` : key;
+ this.extractProperties(value.properties, newParentKey, propertiesMap);
+ } else if ('fields' in value) {
+ for (const fieldNode of (value.fields as any[])) {
+ const type = fieldNode.type?.toString() || '';
+ const fieldName = fieldNode.name?.toString() || key;
+ const finalKey = parentKey ? `${parentKey}.${fieldName}` : fieldName;
+ propertiesMap.set(finalKey, type);
+ }
+ } else if ('type' in value) {
+ const type = value.type?.toString() || '';
+ const finalKey = parentKey ? `${parentKey}.${key}` : key;
+ propertiesMap.set(finalKey, type);
+ }
+ }
+ }
+ }
+ }
+
+ static isIndexDynamic(index: any): boolean {
+ const rootNode = index;
+ return rootNode?.params?.mapping?.index_dynamic || false;
+ }
+
+ static isCollectionDynamicallyIndexed(index: any, collection: string): boolean {
+ const rootNode = index;
+ return rootNode?.params?.mapping?.types?.[collection]?.dynamic || false;
+ }
+
+ static getDefaultField(index: any): string {
+ const rootNode = index;
+ return rootNode?.params?.mapping?.default_field || '';
+ }
+
+ static listCollections(index: any): string[] {
+ const rootNode = index;
+ const typesNode = rootNode?.params?.mapping?.types;
+ return typesNode ? Object.keys(typesNode) : [];
+ }
+}
\ No newline at end of file
diff --git a/src/commands/fts/SearchWorkbench/openSearchIndex.ts b/src/commands/fts/SearchWorkbench/openSearchIndex.ts
index 37c042ab..546ca4da 100644
--- a/src/commands/fts/SearchWorkbench/openSearchIndex.ts
+++ b/src/commands/fts/SearchWorkbench/openSearchIndex.ts
@@ -33,6 +33,7 @@ export const openSearchIndex = async (searchIndexNode: SearchIndexNode, clusterC
{ create: true, overwrite: true }
);
} catch (error) {
+ logger.error("Failed to open Index definition, as it is not a valid JSON");
vscode.window.showInformationMessage("Unable to open Index definition: It is not a valid JSON ", { modal: true });
return false;
}
diff --git a/src/commands/fts/SearchWorkbench/searchWorkbench.ts b/src/commands/fts/SearchWorkbench/searchWorkbench.ts
index 18506303..66d4b214 100644
--- a/src/commands/fts/SearchWorkbench/searchWorkbench.ts
+++ b/src/commands/fts/SearchWorkbench/searchWorkbench.ts
@@ -1,6 +1,5 @@
import * as vscode from 'vscode';
import { getActiveConnection } from '../../../util/connections';
-import UntitledSqlppDocumentService from './controller';
import { WorkbenchWebviewProvider } from '../../../workbench/workbenchWebviewProvider';
import { CouchbaseError, QueryOptions, QueryProfileMode, QueryStatus } from "couchbase";
import { ISearchQueryContext } from '../../../types/ISearchQueryContext';
@@ -8,6 +7,7 @@ import { CouchbaseRestAPI } from '../../../util/apis/CouchbaseRestAPI';
import { MemFS } from "../../../util/fileSystemProvider";
import UntitledSearchJsonDocumentService from './controller';
import SearchIndexNode from '../../../model/SearchIndexNode';
+import { logger } from '../../../logger/logger';
export class SearchWorkbench {
private _untitledSearchJsonDocumentService: UntitledSearchJsonDocumentService;
@@ -33,7 +33,7 @@ export class SearchWorkbench {
// Get the active text editor
const activeTextEditor = vscode.window.activeTextEditor;
- if (activeTextEditor && activeTextEditor.document.languageId === "searchQuery") {
+ if (activeTextEditor && activeTextEditor.document.languageId === "json" && activeTextEditor.document.fileName.endsWith(".cbs.json")) {
activeTextEditor.document.save();
const indexQueryPayload = activeTextEditor.selection.isEmpty ? activeTextEditor.document.getText() : activeTextEditor.document.getText(activeTextEditor.selection);
@@ -48,10 +48,11 @@ export class SearchWorkbench {
const explainPlan = JSON.stringify("");
const couchbbaseRestAPI = new CouchbaseRestAPI(connection);
const searchQueryResult = await couchbbaseRestAPI.runSearchIndexes(queryContext?.indexName, indexQueryPayload);
- workbenchWebviewProvider.setSearchQueryResult(
+ workbenchWebviewProvider.setQueryResult(
JSON.stringify(searchQueryResult?.hits),
{},
- explainPlan
+ explainPlan,
+ true
);
} catch (err) {
const errorArray = [];
@@ -85,7 +86,8 @@ export class SearchWorkbench {
workbenchWebviewProvider.setQueryResult(
JSON.stringify(errorArray),
queryStatusProps,
- null
+ null,
+ true
);
}
@@ -96,7 +98,7 @@ export class SearchWorkbench {
try {
return this._untitledSearchJsonDocumentService.newQuery(searchIndexNode, memFs);
} catch (error) {
- console.log("Error in openSearchWorkbench:", error);
+ logger.error("Error while opening Search WorkBench:" + error);
throw error;
}
}
diff --git a/src/commands/fts/SearchWorkbench/test/queryTypeObject.test.ts b/src/commands/fts/SearchWorkbench/test/queryTypeObject.test.ts
index e27946ba..59e90c74 100644
--- a/src/commands/fts/SearchWorkbench/test/queryTypeObject.test.ts
+++ b/src/commands/fts/SearchWorkbench/test/queryTypeObject.test.ts
@@ -194,7 +194,7 @@ describe("Query Type Object Tests", () => {
await getDiagnosticsForJson(json);
const uri = vscode.Uri.parse('untitled:test.json');
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getUnexpectedAttributeMessageForQuery("min", "match")))).toBeTruthy();
+ expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getUnexpectedAttributeMessageForQuery("match", "numeric range")))).toBeTruthy();
});
test("Valid Match Phrase", async () => {
diff --git a/src/commands/fts/SearchWorkbench/validators/geometryObjectValidator.ts b/src/commands/fts/SearchWorkbench/validators/geometryObjectValidator.ts
index eecf6e4c..397af1ee 100644
--- a/src/commands/fts/SearchWorkbench/validators/geometryObjectValidator.ts
+++ b/src/commands/fts/SearchWorkbench/validators/geometryObjectValidator.ts
@@ -49,22 +49,30 @@ export class GeometryObjectValidator implements SearchObjectValidator {
private validateRelation(propertyValue: any, property: JsonProperty, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument): void {
if (!["intersects", "contains", "within"].includes(propertyValue.value)) {
const positionMap = ValidationHelper.getPositionMap(document);
- diagnosticsList.push(new vscode.Diagnostic(
+ const newDiagnostic = new vscode.Diagnostic(
positionMap.get("relation") || new vscode.Range(0, 0, 0, 1),
ValidationHelper.getRelationErrorMessage(),
vscode.DiagnosticSeverity.Error
- ));
+ );
+
+ if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ diagnosticsList.push(newDiagnostic);
+ }
}
}
- private checkMissingFields(requiredFields: string[], currentAttributes: string[], diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument,positionMap:any): void {
+ private checkMissingFields(requiredFields: string[], currentAttributes: string[], diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument, positionMap: any): void {
requiredFields.forEach(field => {
if (!currentAttributes.includes(field)) {
- diagnosticsList.push(new vscode.Diagnostic(
+ const newDiagnostic = new vscode.Diagnostic(
positionMap.get("geometry") || new vscode.Range(0, 0, 0, 1),
ValidationHelper.missingRequiredAttributeQuery(field, "geometry"),
vscode.DiagnosticSeverity.Error
- ));
+ );
+
+ if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ diagnosticsList.push(newDiagnostic);
+ }
}
});
}
diff --git a/src/commands/fts/SearchWorkbench/validators/queryTypeObjectValidator.ts b/src/commands/fts/SearchWorkbench/validators/queryTypeObjectValidator.ts
index a003a4ef..bf655995 100644
--- a/src/commands/fts/SearchWorkbench/validators/queryTypeObjectValidator.ts
+++ b/src/commands/fts/SearchWorkbench/validators/queryTypeObjectValidator.ts
@@ -23,29 +23,40 @@ export class QueryTypeObjectValidator implements SearchObjectValidator {
const isCompound = this.validateCompound(jsonObject, properties, diagnosticsList, document);
if (!containsMatchAllNone && !isCompound && !isBooleanQuery && !properties.includes("geometry")) {
+ let newDiagnostic: vscode.Diagnostic;
+
if (isFieldMissing && !containsQuery) {
- diagnosticsList.push(new vscode.Diagnostic(
+ newDiagnostic = new vscode.Diagnostic(
ValidationHelper.getPositionMap(document).get(key) || new vscode.Range(0, 0, 0, 1),
QueryTypeObjectValidator.getMissingFieldOrQueryMessage(),
vscode.DiagnosticSeverity.Error
- ));
+ );
+ if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ diagnosticsList.push(newDiagnostic);
+ }
} else if (!isFieldMissing && !containsQuery) {
if (jsonObject.children.length === 1) {
- diagnosticsList.push(new vscode.Diagnostic(
+ newDiagnostic = new vscode.Diagnostic(
ValidationHelper.getPositionMap(document).get(key) || new vscode.Range(0, 0, 0, 1),
QueryTypeObjectValidator.getMissingFieldOperationMessage(),
vscode.DiagnosticSeverity.Error
- ));
+ );
+ if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ diagnosticsList.push(newDiagnostic);
+ }
} else {
this.validateQueryType(jsonObject, diagnosticsList, document);
}
} else {
if (jsonObject.children.length > 1) {
- diagnosticsList.push(new vscode.Diagnostic(
+ newDiagnostic = new vscode.Diagnostic(
ValidationHelper.getPositionMap(document).get(key) || new vscode.Range(0, 0, 0, 1),
QueryTypeObjectValidator.getInvalidFieldWithQueryMessage(),
vscode.DiagnosticSeverity.Error
- ));
+ );
+ if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ diagnosticsList.push(newDiagnostic);
+ }
}
}
}
@@ -62,11 +73,15 @@ export class QueryTypeObjectValidator implements SearchObjectValidator {
if (hasCompound) {
jsonObject.children.forEach(child => {
if (!(child instanceof JsonProperty) || !allowedCompoundAttrs.includes((child as JsonProperty).key)) {
- diagnosticsList.push(new vscode.Diagnostic(
+ const newDiagnostic = new vscode.Diagnostic(
ValidationHelper.getPositionMap(document).get((child as JsonProperty).key) || new vscode.Range(0, 0, 0, 1),
QueryTypeObjectValidator.getFieldNotAllowedOnCompound(),
vscode.DiagnosticSeverity.Error
- ));
+ );
+
+ if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ diagnosticsList.push(newDiagnostic);
+ }
}
});
}
@@ -91,15 +106,12 @@ export class QueryTypeObjectValidator implements SearchObjectValidator {
}
private containsQuery(jsonObject: JsonObject): boolean {
- // Check if jsonObject has any children
if (!jsonObject.children || jsonObject.children.length === 0) {
return false;
}
for (const child of jsonObject.children) {
- // Check if the child is a JsonProperty
if (child instanceof JsonProperty) {
- // Check if the key of the JsonProperty is "query"
if (child.key === "query") {
return true;
}
@@ -110,16 +122,16 @@ export class QueryTypeObjectValidator implements SearchObjectValidator {
}
private validateQueryType(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument): void {
- jsonObject.children.forEach(child => {
+ for (let i = 0; i < jsonObject.children.length; i++) {
+ const child = jsonObject.children[i];
if (!(child instanceof JsonProperty)) {
- return;
+ continue;
}
const property = child as JsonProperty;
const propertyKey = property.key;
-
switch (propertyKey) {
case "match":
this.validateMatch(jsonObject, diagnosticsList, document);
@@ -162,11 +174,15 @@ export class QueryTypeObjectValidator implements SearchObjectValidator {
this.validateTermRange(jsonObject, diagnosticsList, document);
return;
} else {
- diagnosticsList.push(new vscode.Diagnostic(
+ const newDiagnostic = new vscode.Diagnostic(
ValidationHelper.getPositionMap(document).get(propertyKey) || new vscode.Range(0, 0, 0, 1),
QueryTypeObjectValidator.invalidQueryFormatMessage(),
vscode.DiagnosticSeverity.Error
- ));
+ );
+
+ if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ diagnosticsList.push(newDiagnostic);
+ }
return;
}
case "inclusive_start":
@@ -188,8 +204,16 @@ export class QueryTypeObjectValidator implements SearchObjectValidator {
}
- });
-
+ }
+ const newDiagnostic = new vscode.Diagnostic(
+ ValidationHelper.getPositionMap(document).get("query") || new vscode.Range(0, 0, 0, 1),
+ QueryTypeObjectValidator.invalidQueryFormatMessage(),
+ vscode.DiagnosticSeverity.Error
+ );
+
+ if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ diagnosticsList.push(newDiagnostic);
+ }
}
@@ -207,11 +231,15 @@ export class QueryTypeObjectValidator implements SearchObjectValidator {
currentAttributes.push(propertyKey);
if (!allowedFields.includes(propertyKey)) {
- diagnosticsList.push(new vscode.Diagnostic(
+ const newDiagnostic = new vscode.Diagnostic(
ValidationHelper.getPositionMap(document).get(propertyKey) || new vscode.Range(0, 0, 0, 1),
ValidationHelper.getUnexpectedAttributeMessageForQuery(propertyKey, target),
vscode.DiagnosticSeverity.Error
- ));
+ );
+
+ if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ diagnosticsList.push(newDiagnostic);
+ }
} else {
counter.set(propertyKey, (counter.get(propertyKey) || 0) + 1);
}
@@ -221,11 +249,15 @@ export class QueryTypeObjectValidator implements SearchObjectValidator {
const missingFields = requiredFields.filter(field => !currentAttributes.includes(field));
if (currentAttributes.length > 0 && missingFields.length > 0) {
- diagnosticsList.push(new vscode.Diagnostic(
+ const newDiagnostic = new vscode.Diagnostic(
ValidationHelper.getPositionMap(document).get(target) || new vscode.Range(0, 0, 0, 1),
ValidationHelper.missingRequiredAttributeQuery(missingFields.join(", "), target),
vscode.DiagnosticSeverity.Error
- ));
+ );
+
+ if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ diagnosticsList.push(newDiagnostic);
+ }
}
}
@@ -260,11 +292,15 @@ export class QueryTypeObjectValidator implements SearchObjectValidator {
validateGenericRange(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument): void {
const properties = jsonObject.children.map(child => (child as JsonProperty).key);
if (!properties.includes("min") && !properties.includes("max")) {
- diagnosticsList.push(new vscode.Diagnostic(
+ const newDiagnostic = new vscode.Diagnostic(
ValidationHelper.getPositionMap(document).get("min") || new vscode.Range(0, 0, 0, 1),
QueryTypeObjectValidator.minOrMaxRequiredMessage(),
vscode.DiagnosticSeverity.Error
- ));
+ );
+
+ if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ diagnosticsList.push(newDiagnostic);
+ }
}
}
@@ -289,11 +325,15 @@ export class QueryTypeObjectValidator implements SearchObjectValidator {
const properties = jsonObject.children.map(child => (child as JsonProperty).key);
if (!properties.includes("start") && !properties.includes("end")) {
- diagnosticsList.push(new vscode.Diagnostic(
+ const newDiagnostic = new vscode.Diagnostic(
ValidationHelper.getPositionMap(document).get("start") || new vscode.Range(0, 0, 0, 1),
QueryTypeObjectValidator.startOrEndRequiredMessage(),
vscode.DiagnosticSeverity.Error
- ));
+ );
+
+ if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ diagnosticsList.push(newDiagnostic);
+ }
}
}
@@ -319,11 +359,15 @@ export class QueryTypeObjectValidator implements SearchObjectValidator {
}
});
if (matchValue !== null && (matchValue as string).includes(" ") && !isOperatorPresent) {
- diagnosticsList.push(new vscode.Diagnostic(
+ const newDiagnostic = new vscode.Diagnostic(
ValidationHelper.getPositionMap(document).get("match") || new vscode.Range(0, 0, 0, 1),
QueryTypeObjectValidator.matchWithSpaceMessage(),
vscode.DiagnosticSeverity.Error
- ));
+ );
+
+ if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ diagnosticsList.push(newDiagnostic);
+ }
}
}
@@ -345,11 +389,15 @@ export class QueryTypeObjectValidator implements SearchObjectValidator {
private validateOperatorValue(diagnosticsList: vscode.Diagnostic[], property: JsonProperty, document: vscode.TextDocument): void {
if (property.value.value !== "or" && property.value.value !== "and") {
- diagnosticsList.push(new vscode.Diagnostic(
+ const newDiagnostic = new vscode.Diagnostic(
ValidationHelper.getPositionMap(document).get(property.key) || new vscode.Range(0, 0, 0, 1),
QueryTypeObjectValidator.invalidOperatorMessage(),
vscode.DiagnosticSeverity.Error
- ));
+ );
+
+ if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ diagnosticsList.push(newDiagnostic);
+ }
}
}
static matchWithSpaceMessage(): string {
diff --git a/src/commands/fts/SearchWorkbench/validators/shapeObjectValidator.ts b/src/commands/fts/SearchWorkbench/validators/shapeObjectValidator.ts
index 9b547eb0..84e6a6e7 100644
--- a/src/commands/fts/SearchWorkbench/validators/shapeObjectValidator.ts
+++ b/src/commands/fts/SearchWorkbench/validators/shapeObjectValidator.ts
@@ -1,6 +1,6 @@
import * as vscode from 'vscode';
import { SearchObjectValidator } from './searchValidator';
-import { JsonArray, JsonObject,JsonProperty } from './JsonNodes';
+import { JsonArray, JsonObject, JsonProperty } from './JsonNodes';
import { ValidationHelper } from './validationHelper';
@@ -11,7 +11,7 @@ export class ShapeObjectValidator implements SearchObjectValidator {
validate(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument, key: string): void {
const target = "shape";
- const requiredFields = ['type'];
+ let requiredFields = ['type'];
const counter: Map = new Map();
const currentAttributes: string[] = [];
const positionMap = ValidationHelper.getPositionMap(document);
@@ -33,11 +33,15 @@ export class ShapeObjectValidator implements SearchObjectValidator {
}
if (!["type", "coordinates", "geometries", "radius"].includes(propertyKey)) {
- diagnosticsList.push(new vscode.Diagnostic(
+ const newDiagnostic = new vscode.Diagnostic(
positionMap.get(propertyKey) || new vscode.Range(0, 0, 0, 1),
`Unexpected attribute '${propertyKey}' for query '${target}'`,
vscode.DiagnosticSeverity.Error
- ));
+ );
+
+ if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ diagnosticsList.push(newDiagnostic);
+ }
} else {
counter.set(propertyKey, (counter.get(propertyKey) || 0) + 1);
@@ -49,14 +53,18 @@ export class ShapeObjectValidator implements SearchObjectValidator {
// this.validateMultipleOccurrences(counter, jsonObject, diagnosticsList, positionMap);
});
-
+ requiredFields = requiredFields.filter(item => !currentAttributes.includes(item));
requiredFields.forEach(field => {
- if (!currentAttributes.includes(field)) {
- diagnosticsList.push(new vscode.Diagnostic(
+ if (!currentAttributes.includes(field) && currentAttributes.length !== 0 && requiredFields.length !== 0) {
+ const newDiagnostic = new vscode.Diagnostic(
positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
ValidationHelper.missingRequiredAttributeQuery(field, key),
vscode.DiagnosticSeverity.Error
- ));
+ );
+
+ if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ diagnosticsList.push(newDiagnostic);
+ }
}
});
@@ -65,11 +73,13 @@ export class ShapeObjectValidator implements SearchObjectValidator {
} else if (typeValue === "GeometryCollection") {
this.validateGeometryCollection(currentAttributes, diagnosticsList, positionMap, key);
} else {
- this.validateCoordinates(typeValue, currentAttributes, coordinates, diagnosticsList, positionMap);
+ if (typeValue) {
+ this.validateCoordinates(typeValue, currentAttributes, coordinates, diagnosticsList, positionMap);
+ }
}
if (typeValue && coordinates != null && (["LineString", "Polygon", "MultiLineString", "MultiPolygon", "Envelope", "MultiPoint"].includes(typeValue))) {
- this.validateCoordinatesStructure(coordinates,typeValue,diagnosticsList,document,key)
+ this.validateCoordinatesStructure(coordinates, typeValue, diagnosticsList, document, key)
}
}
@@ -79,64 +89,88 @@ export class ShapeObjectValidator implements SearchObjectValidator {
"Point", "Circle", "Envelope", "LineString", "MultiPoint",
"MultiLineString", "MultiPolygon", "GeometryCollection", "Polygon"
];
-
+
if (!validTypes.includes(typeValue)) {
- diagnosticsList.push(new vscode.Diagnostic(
+ const newDiagnostic = new vscode.Diagnostic(
positionMap.get(property.key) || new vscode.Range(0, 0, 0, 1),
`Invalid type '${typeValue}'`,
vscode.DiagnosticSeverity.Error
- ));
+ );
+
+ if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ diagnosticsList.push(newDiagnostic);
+ }
}
}
}
- private validateCoordinatesStructure(coordinates: JsonArray, type: string, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument, key:string): void {
+ private validateCoordinatesStructure(coordinates: JsonArray, type: string, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument, key: string): void {
if (type && coordinates instanceof JsonArray) {
- if (!coordinates.children.every(child => child instanceof JsonArray)) {
- const positionMap = ValidationHelper.getPositionMap(document);
- diagnosticsList.push(new vscode.Diagnostic(
- positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
- `'${type}' in '${key}' requires 'coordinates' to be an array of arrays.`,
- vscode.DiagnosticSeverity.Error
- ));
+ if (!coordinates.children.every(child => child instanceof JsonArray)) {
+ const positionMap = ValidationHelper.getPositionMap(document);
+ const newDiagnostic = new vscode.Diagnostic(
+ positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
+ `'${type}' in '${key}' requires 'coordinates' to be an array of arrays.`,
+ vscode.DiagnosticSeverity.Error
+ );
+
+ if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ diagnosticsList.push(newDiagnostic);
+ }
+ }
}
}
- }
private validateCircle(currentAttributes: string[], diagnosticsList: vscode.Diagnostic[], positionMap: any, key: string): void {
if (!currentAttributes.includes("radius")) {
- diagnosticsList.push(new vscode.Diagnostic(
+ const newDiagnostic = new vscode.Diagnostic(
positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
ValidationHelper.missingRequiredAttributeQuery("radius", key),
vscode.DiagnosticSeverity.Error
- ));
+ );
+
+ if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ diagnosticsList.push(newDiagnostic);
+ }
}
if (!currentAttributes.includes("coordinates")) {
- diagnosticsList.push(new vscode.Diagnostic(
+ const newDiagnostic = new vscode.Diagnostic(
positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
ValidationHelper.missingRequiredAttributeQuery("coordinates", key),
vscode.DiagnosticSeverity.Error
- ));
+ );
+
+ if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ diagnosticsList.push(newDiagnostic);
+ }
}
}
private validateGeometryCollection(currentAttributes: string[], diagnosticsList: vscode.Diagnostic[], positionMap: any, key: string): void {
if (!currentAttributes.includes("geometries")) {
- diagnosticsList.push(new vscode.Diagnostic(
+ const newDiagnostic = new vscode.Diagnostic(
positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
ValidationHelper.missingRequiredAttributeQuery("geometries", key),
vscode.DiagnosticSeverity.Error
- ));
+ );
+
+ if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ diagnosticsList.push(newDiagnostic);
+ }
}
}
private validateCoordinates(typeValue: string | null, currentAttributes: string[], coordinates: JsonProperty | null, diagnosticsList: vscode.Diagnostic[], positionMap: any): void {
if (!currentAttributes.includes("coordinates")) {
- diagnosticsList.push(new vscode.Diagnostic(
+ const newDiagnostic = new vscode.Diagnostic(
positionMap.get("type") || new vscode.Range(0, 0, 0, 1),
ValidationHelper.missingRequiredAttributeQuery("coordinates", "shape"),
vscode.DiagnosticSeverity.Error
- ));
+ );
+
+ if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ diagnosticsList.push(newDiagnostic);
+ }
}
}
diff --git a/src/commands/fts/SearchWorkbench/validators/validationUtil.ts b/src/commands/fts/SearchWorkbench/validators/validationUtil.ts
index 55e491d0..fb4fd4df 100644
--- a/src/commands/fts/SearchWorkbench/validators/validationUtil.ts
+++ b/src/commands/fts/SearchWorkbench/validators/validationUtil.ts
@@ -13,6 +13,7 @@ import { GeometryObjectValidator } from './geometryObjectValidator'
import { ShapeObjectValidator } from './shapeObjectValidator'
import { JsonObject, JsonArray, JsonProperty, JsonNode } from './JsonNodes';
import { ValidationHelper } from './validationHelper';
+import { logger } from '../../../../logger/logger';
@@ -104,6 +105,7 @@ export function validateDocument(document: vscode.TextDocument | undefined, diag
visitJsonObject(jsonObject, diagnosticsList, document);
} catch (error) {
+ logger.error("Invalid Json Error: "+ error)
diagnosticsList.push(new vscode.Diagnostic(new vscode.Range(0, 0, 0, 1), `Invalid JSON: ${error}`,vscode.DiagnosticSeverity.Error));
}
@@ -229,7 +231,6 @@ function validateProperty(property: JsonProperty, contextKey:string, diagnostics
function isTopLevel(property: JsonProperty): boolean {
- // Checks if the property's parent is either null or the root JsonObject
return !property.parent || property.parent.parent === null;
}
diff --git a/src/extension.ts b/src/extension.ts
index 40eb49e5..50f248fc 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -81,6 +81,8 @@ import SearchIndexNode from "./model/SearchIndexNode";
import { openSearchIndex } from "./commands/fts/SearchWorkbench/openSearchIndex";
import { handleSearchContextStatusbar } from "./handlers/handleSearchQueryContextStatusBar";
import { validateDocument } from "./commands/fts/SearchWorkbench/validators/validationUtil";
+import { AutocompleteVisitor } from "./commands/fts/SearchWorkbench/contributor/autoCompleteVisitor";
+import { CbsJsonHoverProvider } from "./commands/fts/SearchWorkbench/documentation/documentationProvider";
export function activate(context: vscode.ExtensionContext) {
Global.setState(context.globalState);
@@ -108,11 +110,52 @@ export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(diagnosticCollection);
context.subscriptions.push(vscode.workspace.onDidChangeTextDocument(event => {
- if (event.document === vscode.window.activeTextEditor?.document && event.document.languageId == "searchQuery") {
+ if (event.document === vscode.window.activeTextEditor?.document && event.document.languageId == "json" && vscode.window.activeTextEditor?.document.fileName.endsWith(".cbs.json")) {
validateDocument(event.document, diagnosticCollection);
}
}));
+const hoverProvider = new CbsJsonHoverProvider(context);
+context.subscriptions.push(
+ vscode.languages.registerHoverProvider({ language: 'json', pattern: '**/*.cbs.json' }, hoverProvider)
+);
+
+const provider = vscode.languages.registerCompletionItemProvider(
+ { language: 'json', pattern: '**/*.cbs.json' },
+ {
+ async provideCompletionItems(document, position, token, context) {
+ const autoComplete = new AutocompleteVisitor();
+ const suggestions = await autoComplete.getAutoCompleteContributor(document, position, currentSearchWorkbench);
+ if (suggestions.length === 0) {
+ return [new vscode.CompletionItem('', vscode.CompletionItemKind.Text)].map(item => {
+ item.sortText = '\u0000';
+ item.preselect = true;
+ item.keepWhitespace = true;
+ item.insertText = '';
+ item.range = new vscode.Range(position, position);
+ return item;
+ });
+ }
+ return suggestions;
+ }
+ },
+ '\"'
+);
+
+
+
+context.subscriptions.push(provider);
+
+const disposable = vscode.window.onDidChangeTextEditorSelection(async (e) => {
+ if (e.kind === vscode.TextEditorSelectionChangeKind.Command) {
+ const activeEditor = vscode.window.activeTextEditor;
+ if (activeEditor && activeEditor.document.fileName.endsWith('.cbs.json')) {
+ await vscode.commands.executeCommand('editor.action.formatDocument');
+ }
+ }
+});
+
+context.subscriptions.push(disposable);
const subscriptions = context.subscriptions;
@@ -208,8 +251,8 @@ context.subscriptions.push(vscode.workspace.onDidChangeTextDocument(event => {
editor &&
editor.document.languageId === "json" &&
editor.document.uri.scheme === "couchbase" &&
- // TODO: Find better way to identify index def files
- !editor.document.uri.path.includes("Search")
+ !editor.document.uri.path.endsWith("cbs.json") &&
+ !editor.document.uri.path.includes("/Search/")
) {
await handleActiveEditorChange(editor, uriToCasMap, memFs);
}
@@ -221,7 +264,9 @@ context.subscriptions.push(vscode.workspace.onDidChangeTextDocument(event => {
async (document: vscode.TextDocument) => {
if (
document && document.languageId === "json" &&
- document.uri.scheme === "couchbase"
+ document.uri.scheme === "couchbase" &&
+ !document.uri.path.endsWith("cbs.json") &&
+ !document.uri.path.includes("/Search/")
) {
await handleOnSaveTextDocument(document, uriToCasMap, memFs, cacheService);
clusterConnectionTreeProvider.refresh();
@@ -725,7 +770,7 @@ context.subscriptions.push(vscode.workspace.onDidChangeTextDocument(event => {
searchWorkbench.openSearchWorkbench(searchIndexNode, memFs);
const editorChangeSubscription = vscode.window.onDidChangeActiveTextEditor(async (editor) => {
- if (editor && editor.document.languageId === "searchQuery") {
+ if (editor && editor.document.languageId === "json" && editor.document.fileName.endsWith(".cbs.json")) {
await handleSearchContextStatusbar(editor, searchIndexNode, searchWorkbench, globalStatusBarItem);
}
});
diff --git a/src/handlers/handleSearchQueryContextStatusBar.ts b/src/handlers/handleSearchQueryContextStatusBar.ts
index 478e6eb6..3825abd2 100644
--- a/src/handlers/handleSearchQueryContextStatusBar.ts
+++ b/src/handlers/handleSearchQueryContextStatusBar.ts
@@ -4,7 +4,7 @@ import { showSearchContextStatusbar } from '../util/queryContextUtils';
import SearchIndexNode from '../model/SearchIndexNode';
export const handleSearchContextStatusbar = async (editor: vscode.TextEditor | undefined,searchNode:SearchIndexNode, workbench:SearchWorkbench, globalStatusBarItem: vscode.StatusBarItem) => {
- if( editor && editor.document.languageId === "searchQuery"){
+ if( editor && editor.document.languageId === "json" && editor.document.fileName.endsWith(".cbs.json")){
// Case 1: Show Status bar
showSearchContextStatusbar(editor,searchNode, workbench, globalStatusBarItem);
} else {
diff --git a/src/model/ScopeNode.ts b/src/model/ScopeNode.ts
index 51bebee4..9b8baff8 100644
--- a/src/model/ScopeNode.ts
+++ b/src/model/ScopeNode.ts
@@ -20,6 +20,7 @@ import { getActiveConnection } from "../util/connections";
import { CacheService } from "../../src/util/cacheService/cacheService";
import { SearchDirectory } from "./SearchDirectory";
import { CollectionDirectory } from "./CollectionDirectory";
+import { hasSearchService } from "../util/common";
export class ScopeNode implements INode {
@@ -74,6 +75,7 @@ export class ScopeNode implements INode {
const childrenDirectoriesList: INode[] = [];
// Search Directory
+ if (hasSearchService(connection?.services)){
childrenDirectoriesList.push(
new SearchDirectory(
this,
@@ -82,6 +84,7 @@ export class ScopeNode implements INode {
this.scopeName
)
);
+ }
// Collections Directory
const collectionDirectory = new CollectionDirectory(
diff --git a/src/pages/queryContext/queryContext.ts b/src/pages/queryContext/queryContext.ts
index 30b5051c..6908729f 100644
--- a/src/pages/queryContext/queryContext.ts
+++ b/src/pages/queryContext/queryContext.ts
@@ -106,7 +106,7 @@ export async function fetchSearchContext(searchIndexNode: SearchIndexNode, workb
}
try {
const activeEditor = vscode.window.activeTextEditor;
- if (!(activeEditor && activeEditor.document.languageId === "searchQuery")) {
+ if (!(activeEditor && activeEditor.document.languageId === "json" && activeEditor.document.fileName.endsWith(".cbs.json"))) {
vscode.window.showErrorMessage("Please ensure that the workbench is open/active");
return;
}
diff --git a/src/reactViews/app/bootstrap.tsx b/src/reactViews/app/bootstrap.tsx
index 539c58ff..0f82eee4 100644
--- a/src/reactViews/app/bootstrap.tsx
+++ b/src/reactViews/app/bootstrap.tsx
@@ -24,6 +24,8 @@ export const App: React.FC = () => {
const [explainPlan, setExplainPlan] = React.useState(null);
const [theme, setTheme] = React.useState("vs-dark");
const [currentTab, setCurrentTab] = React.useState(QueryTabs.JSON); // TODO: initial value should be chart
+ const [isSearch, setIsSearch] = React.useState(false);
+
window.addEventListener('message', event => {
const message = event.data; // The JSON data our extension sent
@@ -31,7 +33,10 @@ export const App: React.FC = () => {
case 'queryResult':
setQueryResult(JSON.parse(message.result));
setQueryStatus(message.queryStatus);
+ setIsSearch(message.isSearch);
+ if (!message.isSearch) {
setExplainPlan(JSON.parse(message.explainPlan));
+ }
message.isDarkTheme ? setTheme("vs-dark") : setTheme("vs-light");
break;
case 'theme':
@@ -42,7 +47,7 @@ export const App: React.FC = () => {
return (
-
+
item.key === QueryTabs.JSON) : TAB_BAR_ITEMS} value={currentTab} onChange={setCurrentTab} />
{currentTab === QueryTabs.JSON && {
theme={theme}
language="json"
/>}
- {currentTab === QueryTabs.Table && }
- {currentTab === QueryTabs.PLAN && }
+ {!isSearch && currentTab === QueryTabs.Table && }
+ {!isSearch && currentTab === QueryTabs.PLAN && }
);
diff --git a/src/test/contributor/cbsCtlCodeCompletion.test.ts b/src/test/contributor/cbsCtlCodeCompletion.test.ts
new file mode 100644
index 00000000..c62b3de2
--- /dev/null
+++ b/src/test/contributor/cbsCtlCodeCompletion.test.ts
@@ -0,0 +1,149 @@
+import * as assert from 'assert';
+import * as vscode from 'vscode';
+import * as path from 'path';
+import * as os from 'os';
+import * as fs from 'fs';
+import { AutocompleteVisitor } from '../../commands/fts/SearchWorkbench/contributor/autoCompleteVisitor';
+import { consistencyCbsContributor } from '../../commands/fts/SearchWorkbench/contributor/consistencyCbsContributor';
+import { ctlCbsContributor } from '../../commands/fts/SearchWorkbench/contributor/ctlCbsContributor';
+
+
+
+
+suite('CBSCtlCodeCompletion Test Suite', () => {
+ let autocompleteVisitor: AutocompleteVisitor;
+ let tempDir: string;
+
+ setup(async () => {
+ autocompleteVisitor = new AutocompleteVisitor();
+ tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'vscode-test-'));
+ });
+
+ teardown(async () => {
+ await fs.promises.rm(tempDir, { recursive: true, force: true });
+ });
+
+ const getCompletions = async (content: string): Promise => {
+ const tempFile = path.join(tempDir, 'test.json');
+ await fs.promises.writeFile(tempFile, content);
+
+ const uri = vscode.Uri.file(tempFile);
+ const document = await vscode.workspace.openTextDocument(uri);
+
+ const caretIndex = content.indexOf('');
+ const position = document.positionAt(caretIndex);
+
+ const completionItems = await autocompleteVisitor.getAutoCompleteContributor(document, position);
+ return completionItems.map(item => item.label as string);
+ };
+
+ test('completion for ctl', async () => {
+ const content = `{
+ "ctl": {""}
+ }`;
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ for (const keyword of ctlCbsContributor.keys) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('dont suggest keyword already exists', async () => {
+ const content = `{
+ "ctl": { "timeout": 10000,
+ ""}
+ }`;
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ const expected = ["consistency"];
+ for (const keyword of expected) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('completion consistency', async () => {
+ const content = `{
+ "ctl": {
+ "timeout": 10000,
+ "consistency": {
+ ""
+ }
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ for (const keyword of consistencyCbsContributor.keys) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('completion consistency existing values', async () => {
+ const content = `{
+ "ctl": {
+ "timeout": 10000,
+ "consistency": {
+ "level": "at_plus",
+ ""
+ }
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ for (const keyword of ["vectors", "results"]) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('suggest level values', async () => {
+ const content = `{
+ "ctl": {
+ "timeout": 10000,
+ "consistency": {
+ "vectors": {
+ "searchIndexName": {
+ "607/205096593892159": 2,
+ "640/298739127912798": 4
+ }
+ },
+ "level": "",
+ "results": "complete"
+ }
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ const expected = ["at_plus", "not_bounded"];
+ for (const keyword of expected) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('suggest results values', async () => {
+ const content = `{
+ "ctl": {
+ "timeout": 10000,
+ "consistency": {
+ "vectors": {
+ "searchIndexName": {
+ "607/205096593892159": 2,
+ "640/298739127912798": 4
+ }
+ },
+ "results": ""
+ }
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ const expected = ["complete"];
+ for (const keyword of expected) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+});
\ No newline at end of file
diff --git a/src/test/contributor/cbsGeometryCodeCompletion.test.ts b/src/test/contributor/cbsGeometryCodeCompletion.test.ts
new file mode 100644
index 00000000..e1fbdf9f
--- /dev/null
+++ b/src/test/contributor/cbsGeometryCodeCompletion.test.ts
@@ -0,0 +1,70 @@
+import * as assert from 'assert';
+import * as vscode from 'vscode';
+import * as path from 'path';
+import * as os from 'os';
+import * as fs from 'fs';
+import { AutocompleteVisitor } from '../../commands/fts/SearchWorkbench/contributor/autoCompleteVisitor';
+import { geometryCbsContributor } from '../../commands/fts/SearchWorkbench/contributor/geometryCbsContributor';
+
+suite('CBSGeometryCodeCompletion Test Suite', () => {
+ let autocompleteVisitor: AutocompleteVisitor;
+ let tempDir: string;
+
+ setup(async () => {
+ autocompleteVisitor = new AutocompleteVisitor();
+ tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'vscode-test-'));
+ });
+
+ teardown(async () => {
+ await fs.promises.rm(tempDir, { recursive: true, force: true });
+ });
+
+ const getCompletions = async (content: string): Promise => {
+ const tempFile = path.join(tempDir, 'test.json');
+ await fs.promises.writeFile(tempFile, content);
+
+ const uri = vscode.Uri.file(tempFile);
+ const document = await vscode.workspace.openTextDocument(uri);
+
+ const caretIndex = content.indexOf('');
+ const position = document.positionAt(caretIndex);
+
+ const completionItems = await autocompleteVisitor.getAutoCompleteContributor(document, position);
+ return completionItems.map(item => item.label as string);
+ };
+
+ test('completion for geometry', async () => {
+ const content = `{
+ "query": {
+ "field": "geojson",
+ "geometry": {
+ ""
+ }
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ for (const keyword of geometryCbsContributor.keys) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('completion for geometry relation', async () => {
+ const content = `{
+ "query": {
+ "field": "geojson",
+ "geometry": {
+ "relation": ""
+ }
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ const expected = ["intersects", "within"];
+ for (const keyword of expected) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+ });
\ No newline at end of file
diff --git a/src/test/contributor/cbsHighlightCodeCompletion.test.ts b/src/test/contributor/cbsHighlightCodeCompletion.test.ts
new file mode 100644
index 00000000..fc4a4e6c
--- /dev/null
+++ b/src/test/contributor/cbsHighlightCodeCompletion.test.ts
@@ -0,0 +1,77 @@
+import * as assert from 'assert';
+import * as vscode from 'vscode';
+import * as path from 'path';
+import * as os from 'os';
+import * as fs from 'fs';
+import { AutocompleteVisitor } from '../../commands/fts/SearchWorkbench/contributor/autoCompleteVisitor';
+import { highlightCbsContributor } from '../../commands/fts/SearchWorkbench/contributor/highlightCbsContributor';
+
+
+suite('CBSHighlightCodeCompletion Test Suite', () => {
+ let autocompleteVisitor: AutocompleteVisitor;
+ let tempDir: string;
+
+ setup(async () => {
+ autocompleteVisitor = new AutocompleteVisitor();
+ tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'vscode-test-'));
+ });
+
+ teardown(async () => {
+ await fs.promises.rm(tempDir, { recursive: true, force: true });
+ });
+
+ const getCompletions = async (content: string): Promise => {
+ const tempFile = path.join(tempDir, 'test.json');
+ await fs.promises.writeFile(tempFile, content);
+
+ const uri = vscode.Uri.file(tempFile);
+ const document = await vscode.workspace.openTextDocument(uri);
+
+ const caretIndex = content.indexOf('');
+ const position = document.positionAt(caretIndex);
+
+ const completionItems = await autocompleteVisitor.getAutoCompleteContributor(document, position);
+ return completionItems.map(item => item.label as string);
+ };
+
+ test('completion for highlight', async () => {
+ const content = `{
+ "highlight": {""}
+ }`;
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ for (const keyword of highlightCbsContributor.keys) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('dont suggest keyword already exists', async () => {
+ const content = `{
+ "highlight": { "fields": ["textField"],
+ ""}
+ }`;
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ const expected = ["style"];
+ for (const keyword of expected) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('suggest style values', async () => {
+ const content = `{
+ "highlight": { "fields": ["textField"],
+ "style": ""
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ const expected = ["html", "ansi"];
+ for (const keyword of expected) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+ });
\ No newline at end of file
diff --git a/src/test/contributor/cbsKnnCodeCompletion.test.ts b/src/test/contributor/cbsKnnCodeCompletion.test.ts
new file mode 100644
index 00000000..1c820a8f
--- /dev/null
+++ b/src/test/contributor/cbsKnnCodeCompletion.test.ts
@@ -0,0 +1,62 @@
+import * as assert from 'assert';
+import * as vscode from 'vscode';
+import * as path from 'path';
+import * as os from 'os';
+import * as fs from 'fs';
+import { AutocompleteVisitor } from '../../commands/fts/SearchWorkbench/contributor/autoCompleteVisitor';
+import { knnCbsContributor } from '../../commands/fts/SearchWorkbench/contributor/knnCbsContributor';
+
+
+suite('CBSKnnCodeCompletion Test Suite', () => {
+ let autocompleteVisitor: AutocompleteVisitor;
+ let tempDir: string;
+
+ setup(async () => {
+ autocompleteVisitor = new AutocompleteVisitor();
+ tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'vscode-test-'));
+ });
+
+ teardown(async () => {
+ await fs.promises.rm(tempDir, { recursive: true, force: true });
+ });
+
+ const getCompletions = async (content: string): Promise => {
+ const tempFile = path.join(tempDir, 'test.json');
+ await fs.promises.writeFile(tempFile, content);
+
+ const uri = vscode.Uri.file(tempFile);
+ const document = await vscode.workspace.openTextDocument(uri);
+
+ const caretIndex = content.indexOf('');
+ const position = document.positionAt(caretIndex);
+
+ const completionItems = await autocompleteVisitor.getAutoCompleteContributor(document, position);
+ return completionItems.map(item => item.label as string);
+ };
+
+ test('empty json completion', async () => {
+ const content = `{ "knn": { "" } }`;
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ for (const keyword of knnCbsContributor.keys) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('dont suggest keyword already exists', async () => {
+ const content = `{
+ "knn": {
+ "field": "vector_field",
+ ""
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ const expected = ["k", "vector"];
+ for (const keyword of expected) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+ });
\ No newline at end of file
diff --git a/src/test/contributor/cbsQueryCodeCompletion.test.ts b/src/test/contributor/cbsQueryCodeCompletion.test.ts
new file mode 100644
index 00000000..1acb5112
--- /dev/null
+++ b/src/test/contributor/cbsQueryCodeCompletion.test.ts
@@ -0,0 +1,446 @@
+import * as assert from 'assert';
+import * as vscode from 'vscode';
+import * as path from 'path';
+import * as os from 'os';
+import * as fs from 'fs';
+import { AutocompleteVisitor } from '../../commands/fts/SearchWorkbench/contributor/autoCompleteVisitor';
+import { queryCbsContributor } from '../../commands/fts/SearchWorkbench/contributor/queryCbsContributor';
+import { locationCbsContributor } from '../../commands/fts/SearchWorkbench/contributor/locationCbsContributor';
+
+suite('CBSQueryCodeCompletion Test Suite', () => {
+ let autocompleteVisitor: AutocompleteVisitor;
+ let tempDir: string;
+
+ setup(async () => {
+ autocompleteVisitor = new AutocompleteVisitor();
+ tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'vscode-test-'));
+ });
+
+ teardown(async () => {
+ await fs.promises.rm(tempDir, { recursive: true, force: true });
+ });
+
+ const getCompletions = async (content: string): Promise => {
+ const tempFile = path.join(tempDir, 'test.json');
+ await fs.promises.writeFile(tempFile, content);
+
+ const uri = vscode.Uri.file(tempFile);
+ const document = await vscode.workspace.openTextDocument(uri);
+
+ const caretIndex = content.indexOf('');
+ const position = document.positionAt(caretIndex);
+ const completionItems = await autocompleteVisitor.getAutoCompleteContributor(document, position);
+ return completionItems.map(item => item.label as string);
+ };
+
+ test('query completion', async () => {
+ const content = `{
+ "query": {
+ ""
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ for (const keyword of queryCbsContributor.allQueryKeys) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('query completion conjuncts', async () => {
+ const content = `{
+ "query": {
+ "conjuncts":[
+ {
+ ""
+ }
+ ]
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ for (const keyword of queryCbsContributor.allQueryKeys) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('query completion disjuncts', async () => {
+ const content = `{
+ "query": {
+ "disjuncts":[
+ {
+ ""
+ }
+ ]
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ for (const keyword of queryCbsContributor.allQueryKeys) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('query completion disjuncts no recommendation', async () => {
+ const content = `{
+ "query": {
+ "disjuncts":[
+ ""
+ ]
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+ assert.strictEqual(completionResults.length, 0);
+ });
+
+ test('query completion conjuncts no recommendation', async () => {
+ const content = `{
+ "query": {
+ "conjuncts":[
+ ""
+ ]
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+ assert.strictEqual(completionResults.length, 0);
+ });
+
+ test('query completion empty', async () => {
+ const content = `{
+ "query": {
+ "query": "",
+
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+ assert.strictEqual(completionResults.length, 0);
+ });
+
+ test('match', async () => {
+ const content = `{
+ "query": {
+ "match":"",
+ ""
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+ const expected = ["field", "analyzer", "operator", "boost", "fuzziness", "prefix_length"];
+ for (const keyword of expected) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('operator', async () => {
+ const content = `{
+ "query": {
+ "operator": "or",
+ ""
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+ const expected = ["field", "analyzer", "boost", "fuzziness", "prefix_length"];
+ for (const keyword of expected) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('bool', async () => {
+ const content = `{
+ "query": {
+ "bool": true
+ ""
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+ const expected = ["field", "boost"];
+ for (const keyword of expected) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('prefix', async () => {
+ const content = `{
+ "query": {
+ "prefix": ""
+ ""
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+ const expected = ["field", "boost"];
+ for (const keyword of expected) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('regex', async () => {
+ const content = `{
+ "query": {
+ "regexp": ""
+ ""
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+ const expected = ["field", "boost"];
+ for (const keyword of expected) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('term', async () => {
+ const content = `{
+ "query": {
+ "term": ""
+ ""
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+ const expected = ["field", "boost", "fuzziness"];
+ for (const keyword of expected) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('terms', async () => {
+ const content = `{
+ "query": {
+ "terms": []
+ ""
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+ const expected = ["field", "boost"];
+ for (const keyword of expected) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('wildcard', async () => {
+ const content = `{
+ "query": {
+ "wildcard": "*"
+ ""
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+ const expected = ["field", "boost"];
+ for (const keyword of expected) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('numeric min', async () => {
+ const content = `{
+ "query": {
+ "min": 3,
+ ""
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+ const expected = ["max", "inclusive_min", "inclusive_max", "field", "boost"];
+ for (const keyword of expected) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('numeric min max', async () => {
+ const content = `{
+ "query": {
+ "min": 3,
+ "min": 10,
+ ""
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+ const expected = ["inclusive_min", "inclusive_max", "field", "boost"];
+ for (const keyword of expected) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('date start', async () => {
+ const content = `{
+ "query": {
+ "start": "2001-10-09T10:20:30-08:00",
+ ""
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+ const expected = ["end", "inclusive_start", "inclusive_end", "field", "boost"];
+ for (const keyword of expected) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('date start inclusive end', async () => {
+ const content = `{
+ "query": {
+ "start": "2001-10-09T10:20:30-08:00",
+ "inclusive_end": false,
+ ""
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+ const expected = ["end", "inclusive_start", "field", "boost"];
+ for (const keyword of expected) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('date inclusive end', async () => {
+ const content = `{
+ "query": {
+ "inclusive_start": false,
+ ""
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+ const expected = ["start", "end", "inclusive_end", "field", "boost"];
+ for (const keyword of expected) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('distance', async () => {
+ const content = `{
+ "query": {
+ "location": {
+ "lon": -2.235143,
+ "lat": 53.482358
+ },
+ ""
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+ const expected = ["distance", "field", "boost"];
+ for (const keyword of expected) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('rectangle', async () => {
+ const content = `{
+ "query": {
+ "top_left": [-2.235143, 53.482358],
+ ""
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+ const expected = ["bottom_right", "field", "boost"];
+ for (const keyword of expected) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('polygon', async () => {
+ const content = `{
+ "query": {
+ "polygon_points": [
+ "37.79393211306212,-122.44234633404847",
+ "37.77995881733997,-122.43977141339417",
+ "37.788031092020155,-122.42925715405579",
+ "37.79026946582319,-122.41149020154114",
+ "37.79571192027403,-122.40735054016113",
+ "37.79393211306212,-122.44234633404847"
+ ],
+ ""
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+ const expected = ["field", "boost"];
+ for (const keyword of expected) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('must', async () => {
+ const content = `{
+ "query":{
+ "must":{
+ ""
+ }
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ assert.ok(completionResults.includes("conjuncts"), "Expected completion 'conjuncts' not found");
+ });
+
+ test('must not', async () => {
+ const content = `{
+ "query":{
+ "must_not":{
+ ""
+ }
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ assert.ok(completionResults.includes("disjuncts"), "Expected completion 'disjuncts' not found");
+ });
+
+ test('should', async () => {
+ const content = `{
+ "query":{
+ "disjuncts":{
+ ""
+ }
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ assert.ok(completionResults.includes("disjuncts"), "Expected completion 'disjuncts' not found");
+ });
+
+ test('top left', async () => {
+ const content = `{
+ "query": {
+ "top_left": {""},
+ "bottom_right": {
+ "lon": 28.955043,
+ "lat": 40.991862
+ },
+ "field": "geo"
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ for (const keyword of locationCbsContributor.keys) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('bottom right', async () => {
+ const content = `{
+ "query": {
+ "top_left": [-2.235143, 53.482358],
+ "bottom_right": {
+ "lon": 28.955043,
+ ""
+ },
+ "field": "geo"
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ assert.ok(completionResults.includes("lat"), "Expected completion 'lat' not found");
+ });
+
+ test('location', async () => {
+ const content = `{
+ "query": {
+ "location": {
+ ""
+ },
+ "distance": "100mi",
+ "field": "geo"
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ for (const keyword of locationCbsContributor.keys) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+ });
\ No newline at end of file
diff --git a/src/test/contributor/cbsRootCodeCompletion.test.ts b/src/test/contributor/cbsRootCodeCompletion.test.ts
new file mode 100644
index 00000000..be2a2a65
--- /dev/null
+++ b/src/test/contributor/cbsRootCodeCompletion.test.ts
@@ -0,0 +1,77 @@
+import * as assert from 'assert';
+import * as vscode from 'vscode';
+import * as path from 'path';
+import * as os from 'os';
+import * as fs from 'fs';
+import { AutocompleteVisitor } from '../../commands/fts/SearchWorkbench/contributor/autoCompleteVisitor';
+
+suite('CBSRootCodeCompletion Test Suite', () => {
+ let autocompleteVisitor: AutocompleteVisitor;
+ let tempDir: string;
+
+ setup(async () => {
+ autocompleteVisitor = new AutocompleteVisitor();
+ tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'vscode-test-'));
+ });
+
+ teardown(async () => {
+ await fs.promises.rm(tempDir, { recursive: true, force: true });
+ });
+
+ const getCompletions = async (content: string): Promise => {
+ const tempFile = path.join(tempDir, 'test.json');
+ await fs.promises.writeFile(tempFile, content);
+
+ const uri = vscode.Uri.file(tempFile);
+ const document = await vscode.workspace.openTextDocument(uri);
+
+ const caretIndex = content.indexOf('');
+ const position = document.positionAt(caretIndex);
+
+ const completionItems = await autocompleteVisitor.getAutoCompleteContributor(document, position);
+ return completionItems.map(item => item.label as string);
+ };
+
+ test('empty json completion', async () => {
+ const content = `{}`;
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ const expected = autocompleteVisitor.topLevelKeywords.map(e => `"${e}"`);
+ for (const keyword of expected) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('dont suggest keyword already exists', async () => {
+ const content = `{
+ "query": {},
+
+ }`;
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ const expected = autocompleteVisitor.topLevelKeywords
+ .filter(e => e !== "query")
+ .map(e => `"${e}"`);
+ for (const keyword of expected) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+
+
+ test('score completion', async () => {
+ const content = `{
+ "query": {
+ "query": "your_query_here"
+ },
+ "fields": ["*"],
+ "score": ""
+ }`;
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ assert.ok(completionResults.includes("none"), "Expected completion 'none' not found");
+ });
+ });
\ No newline at end of file
diff --git a/src/test/contributor/cbsShapeCodeCompletion.test.ts b/src/test/contributor/cbsShapeCodeCompletion.test.ts
new file mode 100644
index 00000000..64f12e9d
--- /dev/null
+++ b/src/test/contributor/cbsShapeCodeCompletion.test.ts
@@ -0,0 +1,118 @@
+import * as assert from 'assert';
+import * as vscode from 'vscode';
+import * as path from 'path';
+import * as os from 'os';
+import * as fs from 'fs';
+import { AutocompleteVisitor } from '../../commands/fts/SearchWorkbench/contributor/autoCompleteVisitor';
+
+suite('CBSShapeCodeCompletion Test Suite', () => {
+ let autocompleteVisitor: AutocompleteVisitor;
+ let tempDir: string;
+
+ setup(async () => {
+ autocompleteVisitor = new AutocompleteVisitor();
+ tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'vscode-test-'));
+ });
+
+ teardown(async () => {
+ await fs.promises.rm(tempDir, { recursive: true, force: true });
+ });
+
+ const getCompletions = async (content: string): Promise => {
+ const tempFile = path.join(tempDir, 'test.json');
+ await fs.promises.writeFile(tempFile, content);
+
+ const uri = vscode.Uri.file(tempFile);
+ const document = await vscode.workspace.openTextDocument(uri);
+
+ const caretIndex = content.indexOf('');
+ const position = document.positionAt(caretIndex);
+
+ const completionItems = await autocompleteVisitor.getAutoCompleteContributor(document, position);
+ return completionItems.map(item => item.label as string);
+ };
+
+ test('completion for shape', async () => {
+ const content = `{
+ "query": {
+ "field": "geojson",
+ "geometry": {
+ "shape": {
+ ""
+ },
+ "relation": "intersects"
+ }
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ const expected = ["coordinates", "type", "radius", "geometries"];
+ for (const keyword of expected) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('completion for circle', async () => {
+ const content = `{
+ "query": {
+ "field": "geojson",
+ "geometry": {
+ "shape": {
+ "type": "Circle",
+ ""
+ },
+ "relation": "intersects"
+ }
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ assert.strictEqual(completionResults.length, 2);
+ const expected = ["coordinates", "radius"];
+ for (const keyword of expected) {
+ assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
+ }
+ });
+
+ test('completion for geometry collection', async () => {
+ const content = `{
+ "query": {
+ "field": "geojson",
+ "geometry": {
+ "shape": {
+ "type": "GeometryCollection",
+ ""
+ },
+ "relation": "intersects"
+ }
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ assert.strictEqual(completionResults.length, 1);
+ assert.ok(completionResults.includes("geometries"), "Expected completion 'geometries' not found");
+ });
+
+ test('completion for polygon', async () => {
+ const content = `{
+ "query": {
+ "field": "geojson",
+ "geometry": {
+ "shape": {
+ "type": "Polygon",
+ ""
+ },
+ "relation": "intersects"
+ }
+ }
+ }`;
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ assert.strictEqual(completionResults.length, 1);
+ assert.ok(completionResults.includes("coordinates"), "Expected completion 'coordinates' not found");
+ });
+ });
\ No newline at end of file
diff --git a/src/test/runTest.ts b/src/test/runTest.ts
index d9dfb906..b8033fe5 100644
--- a/src/test/runTest.ts
+++ b/src/test/runTest.ts
@@ -14,24 +14,35 @@
* limitations under the License.
*/
-import * as path from "path";
-
-import { runTests } from "@vscode/test-electron";
+import * as path from 'path';
+import * as fs from 'fs';
+import { runTests } from '@vscode/test-electron';
async function main() {
try {
- // The folder containing the Extension Manifest package.json
- // Passed to `--extensionDevelopmentPath`
- const extensionDevelopmentPath = path.resolve(__dirname, "../../");
+ const extensionDevelopmentPath = path.resolve(__dirname, '../');
+ const extensionTestsPath = path.resolve(__dirname, './suite/index');
+
+ // Cleanup step
+ const userDataPath = path.resolve(__dirname, '../../.vscode-test/user-data');
+ if (fs.existsSync(userDataPath)) {
+ fs.rmdirSync(userDataPath, { recursive: true });
+ }
- // The path to test runner
- // Passed to --extensionTestsPath
- const extensionTestsPath = path.resolve(__dirname, "./suite/index");
+ // Get the test file from command line arguments
+ const testFile = process.argv[2];
+ if (testFile) {
+ process.env.VSCODE_TEST_FILE = testFile;
+ }
// Download VS Code, unzip it and run the integration test
- await runTests({ extensionDevelopmentPath, extensionTestsPath });
- } catch (err: any) {
- console.error("Failed to run tests");
+ await runTests({
+ extensionDevelopmentPath,
+ extensionTestsPath,
+ launchArgs: testFile ? ['--disable-extensions', '--extensionTestsPath=' + extensionTestsPath, '--testFile=' + testFile] : undefined
+ });
+ } catch (err) {
+ console.error('Failed to run tests', err);
process.exit(1);
}
}
diff --git a/src/test/suite/index.ts b/src/test/suite/index.ts
index fdffa874..07e7e753 100644
--- a/src/test/suite/index.ts
+++ b/src/test/suite/index.ts
@@ -16,7 +16,8 @@
import * as path from "path";
import Mocha from "mocha";
-import glob from "glob";
+import util from 'util';
+const glob = util.promisify(require('glob'));
export function run(): Promise {
// Create the mocha test
@@ -25,17 +26,23 @@ export function run(): Promise {
color: true,
});
- const testsRoot = path.resolve(__dirname, "..");
+ const testsRoot = path.resolve(__dirname, '..');
- return new Promise((c, e) => {
- glob("**/**.test.js", { cwd: testsRoot }, (err, files) => {
- if (err) {
- return e(err);
- }
-
- // Add files to the test suite
- files.forEach((f) => mocha.addFile(path.resolve(testsRoot, f)));
+ return new Promise(async (c, e) => {
+ const testFile = process.env.VSCODE_TEST_FILE;
+ if (testFile) {
+ // If a specific test file is specified, only add that file
+ mocha.addFile(path.resolve(testsRoot, testFile));
+ } else {
+ try {
+ const files = await glob("contributor/*.test.js", { cwd: testsRoot });
+ files.forEach((f: string) => mocha.addFile(path.resolve(testsRoot, f)));
+ } catch (err) {
+ console.error("Error during glob operation:", err);
+ return;
+ }
+ }
try {
// Run the mocha test
mocha.run((failures) => {
@@ -50,5 +57,4 @@ export function run(): Promise {
e(err);
}
});
- });
}
diff --git a/src/util/cacheService/cacheService.ts b/src/util/cacheService/cacheService.ts
index 38f0a54f..95321974 100644
--- a/src/util/cacheService/cacheService.ts
+++ b/src/util/cacheService/cacheService.ts
@@ -51,16 +51,25 @@ export class CacheService {
const type = propertyValue.type;
if (type === 'object') {
const children = this.schemaTreeTraversal(propertyValue.properties);
- currentNodes[property[0]] = children;
+ currentNodes[property[0]] = {
+ type: 'object',
+ value: children
+ };
} else if (type === 'array') {
try {
const items = propertyValue.items;
const itemType = items.type;
if (itemType === 'object') {
const children = this.schemaTreeTraversal(items.properties);
- currentNodes[property[0]] = children;
+ currentNodes[property[0]] = {
+ type: 'array',
+ value: children
+ };
} else {
- currentNodes[property[0]] = `array of ${itemType}`;
+ currentNodes[property[0]] = {
+ type: 'array',
+ value: `array of ${itemType}`
+ };;
}
} catch (error) {
logger.error(`Error processing array type for ${property[0]}: ${error}`);
@@ -70,7 +79,10 @@ export class CacheService {
try {
let currentType: string = type.toString();
currentType = currentType.replace(',', " | ");
- currentNodes[property[0]] = currentType;
+ currentNodes[property[0]] = {
+ type: currentType,
+ value: currentType
+ };
} catch (e) {
logger.error("Type can't be stringified: " + e);
}
@@ -582,6 +594,10 @@ export class CacheService {
// return vscode.globalState.update(BUCKETS_STATE_KEY, finalJson);
}
+ public getCache(bucketName:string){
+ return this.bucketsData.get(bucketName)
+ }
+
public async loadCache(connection: IConnection): Promise {
const storedDataJson = Global.state.get(`vscode-couchbase.iq.bucketsCache.${connection.connectionIdentifier}`);
if (!storedDataJson) {
diff --git a/src/util/common.ts b/src/util/common.ts
index 34a17fa8..51a15cef 100644
--- a/src/util/common.ts
+++ b/src/util/common.ts
@@ -58,4 +58,11 @@ export const hasQueryService = (services: string[] | undefined) => {
return false;
}
return services.includes('n1ql');
+};
+
+export const hasSearchService = (services: string[] | undefined) => {
+ if (!services) {
+ return false;
+ }
+ return services.includes('fts');
};
\ No newline at end of file
diff --git a/src/util/connections.ts b/src/util/connections.ts
index cd12df49..cac487e9 100644
--- a/src/util/connections.ts
+++ b/src/util/connections.ts
@@ -24,7 +24,7 @@ import ClusterConnectionTreeProvider from "../tree/ClusterConnectionTreeProvider
import { logger } from "../logger/logger";
import { getServices } from "./OverviewClusterUtils/ClusterOverviewGeneralTab";
import { CouchbaseRestAPI } from "./apis/CouchbaseRestAPI";
-import { hasQueryService } from "./common";
+import { hasQueryService, hasSearchService } from "./common";
import { SecretService } from "./secretService";
export function getConnectionId(connection: IConnection) {
@@ -197,6 +197,7 @@ export async function useConnection(connection: IConnection): Promise {
connection.services = getServices(serviceOverview!);
// Set the isKVCluster context
vscode.commands.executeCommand('setContext', 'isKVCluster', !hasQueryService(connection.services));
+ vscode.commands.executeCommand('setContext', 'isSearchEnabled', hasSearchService(connection.services));
status = true;
vscode.window.showInformationMessage("Connection established successfully!");
logger.info(`Connection established successfully with ${connection.connectionIdentifier}`);
diff --git a/src/workbench/queryWorkbench.ts b/src/workbench/queryWorkbench.ts
index e11f18a4..c5296001 100644
--- a/src/workbench/queryWorkbench.ts
+++ b/src/workbench/queryWorkbench.ts
@@ -85,7 +85,8 @@ export class QueryWorkbench {
workbenchWebviewProvider.setQueryResult(
JSON.stringify(result?.rows),
queryStatusProps,
- explainPlan
+ explainPlan,
+ false
);
await saveQuery({ query: query, id: getUUID() });
queryHistoryTreeProvider.refresh();
@@ -126,7 +127,8 @@ export class QueryWorkbench {
workbenchWebviewProvider.setQueryResult(
JSON.stringify(errorArray),
queryStatusProps,
- null
+ null,
+ false
);
}
}
diff --git a/src/workbench/workbenchWebviewProvider.ts b/src/workbench/workbenchWebviewProvider.ts
index f2eea89e..e99bb912 100644
--- a/src/workbench/workbenchWebviewProvider.ts
+++ b/src/workbench/workbenchWebviewProvider.ts
@@ -18,7 +18,8 @@ type IQueryStatusProps = {
type IQueryResultProps = {
queryResult: string;
queryStatus: IQueryStatusProps;
- plan: string | null
+ plan: string | null;
+ isSearch: boolean
};
export class WorkbenchWebviewProvider implements vscode.WebviewViewProvider {
public _view?: vscode.WebviewView;
@@ -49,7 +50,7 @@ export class WorkbenchWebviewProvider implements vscode.WebviewViewProvider {
this._view?.webview.postMessage({ command: "theme", isDarkTheme });
this._view?.onDidChangeVisibility(() => {
if (Memory.state.get(Constants.QUERY_RESULT)) {
- this.sendQueryResult(JSON.stringify([{ "status": "Loading last executed result" }]), { queryStatus: QueryStatus.Running }, null);
+ this.sendQueryResult(JSON.stringify([{ "status": "Loading last executed result" }]), { queryStatus: QueryStatus.Running }, null,);
const previousResult = Memory.state.get(Constants.QUERY_RESULT);
if (previousResult) {
this.sendQueryResult(previousResult.queryResult, previousResult.queryStatus, previousResult.plan);
@@ -58,21 +59,16 @@ export class WorkbenchWebviewProvider implements vscode.WebviewViewProvider {
});
}
- async sendQueryResult(queryResult: string, queryStatus: IQueryStatusProps, plan: string | null) {
+ async sendQueryResult(queryResult: string, queryStatus: IQueryStatusProps, plan: string | null, isSearch?: boolean) {
const isDarkTheme: boolean = vscode.window.activeColorTheme.kind === vscode.ColorThemeKind.Dark;
- await this._view?.webview.postMessage({ command: "queryResult", result: queryResult, queryStatus: queryStatus, explainPlan: plan, isDarkTheme });
- Memory.state.update(Constants.QUERY_RESULT, { queryResult, queryStatus, plan });
+ await this._view?.webview.postMessage({ command: "queryResult", result: queryResult, queryStatus: queryStatus, explainPlan: plan, isDarkTheme, isSearch:isSearch });
+ Memory.state.update(Constants.QUERY_RESULT, { queryResult, queryStatus, plan, isSearch });
}
- async setQueryResult(queryResult: string, queryStatus: IQueryStatusProps, plan: string | null) {
+ async setQueryResult(queryResult: string, queryStatus: any, plan: string | null, isSearch: boolean) {
this._view?.show();
this._queryResult = queryResult;
- await this.sendQueryResult(queryResult, queryStatus, plan);
+ await this.sendQueryResult(queryResult, queryStatus, plan, isSearch);
}
- async setSearchQueryResult(queryResult: string, queryStatus: any, plan: string | null) {
- this._view?.show();
- this._queryResult = queryResult;
- await this.sendQueryResult(queryResult, queryStatus, plan);
- }
}
\ No newline at end of file
From 0c9cb88d3db45a589d6d2b0f4963d7d51fe6a84a Mon Sep 17 00:00:00 2001
From: Prajwal Pai
Date: Tue, 16 Jul 2024 12:26:33 +0530
Subject: [PATCH 12/24] Update test.yml CI to use node version 20
---
.github/workflows/test.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 25097a3e..3227ea43 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -14,7 +14,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@v3
with:
- node-version: 16.x
+ node-version: 20
- name: Install Dependencies
run: npm install
- name: Run Tests
From d6a17b4dfc1b9d0b87520722433e0ed197a31dfe Mon Sep 17 00:00:00 2001
From: Prajwal Pai
Date: Tue, 16 Jul 2024 12:35:15 +0530
Subject: [PATCH 13/24] Update Test ci
---
.github/workflows/test.yml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 3227ea43..ccc4c3c7 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -17,6 +17,8 @@ jobs:
node-version: 20
- name: Install Dependencies
run: npm install
+ - name: Rebuild Electron Modules
+ run: ./node_modules/.bin/electron-rebuild
- name: Run Tests
if: runner.os == 'Linux'
run: xvfb-run -a npm test
From a97e3317b1da7fd50116e2bb60cc8d4e37673315 Mon Sep 17 00:00:00 2001
From: Prajwal Pai
Date: Tue, 16 Jul 2024 12:38:49 +0530
Subject: [PATCH 14/24] Update package.json
---
package-lock.json | 266 ++++++++++++++++++++++++++++++++++++++++++++++
package.json | 1 +
2 files changed, 267 insertions(+)
diff --git a/package-lock.json b/package-lock.json
index 7ecaad19..8305bec0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -71,6 +71,7 @@
"class-transformer": "^0.5.1",
"cmake-js": "^6.3.2",
"css-loader": "^6.10.0",
+ "electron": "^31.2.1",
"eslint": "^8.56.0",
"file-loader": "^6.2.0",
"glob": "^7.2.0",
@@ -1932,6 +1933,41 @@
"node": ">=10.0.0"
}
},
+ "node_modules/@electron/get": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz",
+ "integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^4.1.1",
+ "env-paths": "^2.2.0",
+ "fs-extra": "^8.1.0",
+ "got": "^11.8.5",
+ "progress": "^2.0.3",
+ "semver": "^6.2.0",
+ "sumchecker": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "global-agent": "^3.0.0"
+ }
+ },
+ "node_modules/@electron/get/node_modules/fs-extra": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=6 <7 || >=8"
+ }
+ },
"node_modules/@electron/rebuild": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.6.0.tgz",
@@ -3793,6 +3829,16 @@
"integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==",
"dev": true
},
+ "node_modules/@types/yauzl": {
+ "version": "2.10.3",
+ "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz",
+ "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.5.0.tgz",
@@ -5038,6 +5084,13 @@
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
"dev": true
},
+ "node_modules/boolean": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz",
+ "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==",
+ "dev": true,
+ "optional": true
+ },
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -6835,6 +6888,13 @@
"node": ">=8"
}
},
+ "node_modules/detect-node": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
+ "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
+ "dev": true,
+ "optional": true
+ },
"node_modules/devlop": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz",
@@ -6904,6 +6964,24 @@
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
"dev": true
},
+ "node_modules/electron": {
+ "version": "31.2.1",
+ "resolved": "https://registry.npmjs.org/electron/-/electron-31.2.1.tgz",
+ "integrity": "sha512-g3CLKjl4yuXt6VWm/KpgEjYYhFiCl19RgUn8lOC8zV/56ZXAS3+mqV4wWzicE/7vSYXs6GRO7vkYRwrwhX3Gaw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "dependencies": {
+ "@electron/get": "^2.0.0",
+ "@types/node": "^20.9.0",
+ "extract-zip": "^2.0.1"
+ },
+ "bin": {
+ "electron": "cli.js"
+ },
+ "engines": {
+ "node": ">= 12.20.55"
+ }
+ },
"node_modules/electron-to-chromium": {
"version": "1.4.722",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.722.tgz",
@@ -7133,6 +7211,13 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/es6-error": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
+ "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
+ "dev": true,
+ "optional": true
+ },
"node_modules/escalade": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
@@ -7555,6 +7640,41 @@
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
},
+ "node_modules/extract-zip": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
+ "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^4.1.1",
+ "get-stream": "^5.1.0",
+ "yauzl": "^2.10.0"
+ },
+ "bin": {
+ "extract-zip": "cli.js"
+ },
+ "engines": {
+ "node": ">= 10.17.0"
+ },
+ "optionalDependencies": {
+ "@types/yauzl": "^2.9.1"
+ }
+ },
+ "node_modules/extract-zip/node_modules/get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "dev": true,
+ "dependencies": {
+ "pump": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -8102,6 +8222,37 @@
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
"dev": true
},
+ "node_modules/global-agent": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz",
+ "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "boolean": "^3.0.1",
+ "es6-error": "^4.1.1",
+ "matcher": "^3.0.0",
+ "roarr": "^2.15.3",
+ "semver": "^7.3.2",
+ "serialize-error": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=10.0"
+ }
+ },
+ "node_modules/global-agent/node_modules/semver": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
+ "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
+ "dev": true,
+ "optional": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/globals": {
"version": "11.12.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
@@ -11157,6 +11308,13 @@
"integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
"dev": true
},
+ "node_modules/json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
+ "dev": true,
+ "optional": true
+ },
"node_modules/json5": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
@@ -11632,6 +11790,32 @@
"tmpl": "1.0.5"
}
},
+ "node_modules/matcher": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz",
+ "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "escape-string-regexp": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/matcher/node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/mdast-util-from-markdown": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.0.tgz",
@@ -13939,6 +14123,15 @@
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
},
+ "node_modules/progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
"node_modules/promise-inflight": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
@@ -14735,6 +14928,31 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/roarr": {
+ "version": "2.15.4",
+ "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz",
+ "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "boolean": "^3.0.1",
+ "detect-node": "^2.0.4",
+ "globalthis": "^1.0.1",
+ "json-stringify-safe": "^5.0.1",
+ "semver-compare": "^1.0.0",
+ "sprintf-js": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/roarr/node_modules/sprintf-js": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
+ "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==",
+ "dev": true,
+ "optional": true
+ },
"node_modules/run-parallel": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
@@ -14950,6 +15168,42 @@
"semver": "bin/semver.js"
}
},
+ "node_modules/semver-compare": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
+ "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==",
+ "dev": true,
+ "optional": true
+ },
+ "node_modules/serialize-error": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz",
+ "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "type-fest": "^0.13.1"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/serialize-error/node_modules/type-fest": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
+ "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/serialize-javascript": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
@@ -15507,6 +15761,18 @@
"inline-style-parser": "0.2.3"
}
},
+ "node_modules/sumchecker": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz",
+ "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^4.1.0"
+ },
+ "engines": {
+ "node": ">= 8.0"
+ }
+ },
"node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
diff --git a/package.json b/package.json
index 55db319e..c3ea5b2d 100644
--- a/package.json
+++ b/package.json
@@ -72,6 +72,7 @@
"class-transformer": "^0.5.1",
"cmake-js": "^6.3.2",
"css-loader": "^6.10.0",
+ "electron": "^31.2.1",
"eslint": "^8.56.0",
"file-loader": "^6.2.0",
"glob": "^7.2.0",
From ed114d4bea1563ad49939c1aaf732798a5f8db7e Mon Sep 17 00:00:00 2001
From: Prajwal Pai
Date: Tue, 16 Jul 2024 12:43:11 +0530
Subject: [PATCH 15/24] Update test ci
---
.github/workflows/test.yml | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index ccc4c3c7..1d06a70f 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -15,8 +15,14 @@ jobs:
uses: actions/setup-node@v3
with:
node-version: 20
- - name: Install Dependencies
- run: npm install
+ - name: Clear node_modules and Reinstall Dependencies
+ run: |
+ if [ "$RUNNER_OS" == "Windows" ]; then
+ if exist node_modules rmdir /s /q node_modules
+ else
+ rm -rf node_modules
+ fi
+ npm install
- name: Rebuild Electron Modules
run: ./node_modules/.bin/electron-rebuild
- name: Run Tests
From 868f6e13d67d95d3abb8a4e954ae33d26b779f6e Mon Sep 17 00:00:00 2001
From: Prajwal Pai
Date: Tue, 16 Jul 2024 12:45:24 +0530
Subject: [PATCH 16/24] Update test ci
---
.github/workflows/test.yml | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 1d06a70f..4ee084e7 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -15,14 +15,10 @@ jobs:
uses: actions/setup-node@v3
with:
node-version: 20
- - name: Clear node_modules and Reinstall Dependencies
- run: |
- if [ "$RUNNER_OS" == "Windows" ]; then
- if exist node_modules rmdir /s /q node_modules
- else
- rm -rf node_modules
- fi
- npm install
+ - name: Remove Node modules
+ run: rm -rf node_modules
+ - name: Install Dependencies
+ run: npm install
- name: Rebuild Electron Modules
run: ./node_modules/.bin/electron-rebuild
- name: Run Tests
From 567375153ef1f39028c1f2286cc7f162e4bf8e42 Mon Sep 17 00:00:00 2001
From: Prajwal Pai
Date: Tue, 16 Jul 2024 13:27:41 +0530
Subject: [PATCH 17/24] Add Rebuild step
---
.github/workflows/test.yml | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 4ee084e7..95bdfac2 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -14,13 +14,11 @@ jobs:
- name: Setup Node
uses: actions/setup-node@v3
with:
- node-version: 20
- - name: Remove Node modules
- run: rm -rf node_modules
+ node-version: 20
- name: Install Dependencies
run: npm install
- - name: Rebuild Electron Modules
- run: ./node_modules/.bin/electron-rebuild
+ - name: Run Rebuild
+ run: npm run rebuild
- name: Run Tests
if: runner.os == 'Linux'
run: xvfb-run -a npm test
From b7d54904a5b8ead6dd8b4741b3d3c1f731bfdcfc Mon Sep 17 00:00:00 2001
From: Prajwal Pai
Date: Tue, 16 Jul 2024 14:54:28 +0530
Subject: [PATCH 18/24] Add prerequisite steps
---
.github/workflows/test.yml | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 95bdfac2..d26fd51c 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -14,7 +14,24 @@ jobs:
- name: Setup Node
uses: actions/setup-node@v3
with:
- node-version: 20
+ node-version: 20
+ - run: echo '${{ secrets.CONFIG_JSON }}' > ${{ github.workspace }}/src/config.json
+ - uses: ilammy/setup-nasm@v1
+ - name: windows-specific
+ shell: pwsh
+ if: runner.os == 'windows-latest'
+ run: choco install openssl.light --version=1.1.1 && choco install cmake --global && npm install --global cmake-js node-gyp && echo CMAKE_JS_LIB - $CMAKE_JS_LIB
+ - name: linux-specific
+ shell: bash
+ if: runner.os == 'ubuntu-latest'
+ run: |
+ ldd --version
+ rm -rf /usr/local/bin/cmake
+ wget https://cmake.org/files/v3.27/cmake-3.27.9-linux-x86_64.tar.gz
+ tar xf cmake-3.27.9-linux-x86_64.tar.gz
+ WORKING_DIRECTORY=$(pwd)
+ echo "${WORKING_DIRECTORY}/cmake-3.27.9-linux-x86_64/bin" >> $GITHUB_PATH
+ echo "PATH=${WORKING_DIRECTORY}/cmake-3.27.9-linux-x86_64/bin:$PATH" >> $GITHUB_ENV
- name: Install Dependencies
run: npm install
- name: Run Rebuild
From 8241aa07a396728dcedcd2212c77088cedb57e38 Mon Sep 17 00:00:00 2001
From: Prajwal Pai
Date: Tue, 16 Jul 2024 14:59:35 +0530
Subject: [PATCH 19/24] Update trigger in CI
---
.github/workflows/test.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index d26fd51c..03265754 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -19,11 +19,11 @@ jobs:
- uses: ilammy/setup-nasm@v1
- name: windows-specific
shell: pwsh
- if: runner.os == 'windows-latest'
+ if: runner.os == 'Windows'
run: choco install openssl.light --version=1.1.1 && choco install cmake --global && npm install --global cmake-js node-gyp && echo CMAKE_JS_LIB - $CMAKE_JS_LIB
- name: linux-specific
shell: bash
- if: runner.os == 'ubuntu-latest'
+ if: runner.os == 'Linux'
run: |
ldd --version
rm -rf /usr/local/bin/cmake
From cfc0dd9fd99e60d13a27b108a2ef9ac775e19052 Mon Sep 17 00:00:00 2001
From: Prajwal Pai
Date: Thu, 18 Jul 2024 12:01:57 +0530
Subject: [PATCH 20/24] Big Fixes from suggestions
---
package.json | 19 ++++
src/commands/extensionCommands/commands.ts | 1 +
.../fts/SearchWorkbench/controller.ts | 15 ++--
.../fts/SearchWorkbench/searchWorkbench.ts | 86 +++++++++++++++----
src/extension.ts | 25 ++++--
src/model/CollectionDirectory.ts | 2 +-
src/model/SearchDirectory.ts | 8 +-
src/model/SearchIndexNode.ts | 3 +-
src/pages/queryContext/queryContext.ts | 28 +++---
src/util/ftsIndexUtils.ts | 24 ++++++
src/util/queryContextUtils.ts | 34 ++++----
11 files changed, 176 insertions(+), 69 deletions(-)
create mode 100644 src/util/ftsIndexUtils.ts
diff --git a/package.json b/package.json
index c3ea5b2d..f397c3c4 100644
--- a/package.json
+++ b/package.json
@@ -486,6 +486,11 @@
"title": "Delete Cluster Connection",
"category": "Couchbase"
},
+ {
+ "command": "vscode-couchbase.deleteSearchIndex",
+ "title": "Delete Search Index",
+ "category": "Couchbase"
+ },
{
"command": "vscode-couchbase.useClusterConnection",
"title": "Connect to Cluster",
@@ -851,6 +856,10 @@
"command": "vscode-couchbase.openSearchWorkbench",
"when": "false"
},
+ {
+ "command": "vscode-couchbase.deleteSearchIndex",
+ "when": "false"
+ },
{
"command": "vscode-couchbase.deleteClusterConnection",
"when": "false"
@@ -1033,11 +1042,21 @@
"when": "view == couchbase && viewItem == active_connection && !isKVCluster",
"group": "workbench@1"
},
+ {
+ "command": "vscode-couchbase.openSearchWorkbench",
+ "when": "view == couchbase && viewItem == active_connection && !isKVCluster && isSearchEnabled",
+ "group": "workbench@1"
+ },
{
"command": "vscode-couchbase.openSearchWorkbench",
"when": "view == couchbase && viewItem == searchIndex && !isKVCluster && isSearchEnabled",
"group": "workbench@1"
},
+ {
+ "command": "vscode-couchbase.deleteSearchIndex",
+ "when": "view == couchbase && viewItem == searchIndex && !isKVCluster && isSearchEnabled",
+ "group": "workbench@2"
+ },
{
"submenu": "vscode-couchbase.toolsMenu",
"when": "view == couchbase && viewItem == active_connection"
diff --git a/src/commands/extensionCommands/commands.ts b/src/commands/extensionCommands/commands.ts
index 2c4d7ecb..13328ff0 100644
--- a/src/commands/extensionCommands/commands.ts
+++ b/src/commands/extensionCommands/commands.ts
@@ -38,6 +38,7 @@ export namespace Commands {
export const openQueryNotebook: string = "vscode-couchbase.openQueryNotebook";
export const openQueryWorkbench: string = "vscode-couchbase.openQueryWorkbench";
export const openSearchWorkbench: string = "vscode-couchbase.openSearchWorkbench";
+ export const deleteSearchIndex: string = "vscode-couchbase.deleteSearchIndex";
export const getSampleProjects: string = "vscode-couchbase.openSampleProjects";
export const loadMore: string = "vscode-couchbase.loadMore";
export const showOutputConsole: string = "vscode-couchbase.showOutputConsole";
diff --git a/src/commands/fts/SearchWorkbench/controller.ts b/src/commands/fts/SearchWorkbench/controller.ts
index f0fd7e3b..5f6d48a2 100644
--- a/src/commands/fts/SearchWorkbench/controller.ts
+++ b/src/commands/fts/SearchWorkbench/controller.ts
@@ -36,13 +36,16 @@ export default class UntitledSearchJsonDocumentService {
public async openSearchJsonTextDocument(searchIndexNode: SearchIndexNode, memFs: MemFS): Promise {
- const uri = vscode.Uri.parse(`couchbase:/search-workbench-${searchIndexNode.searchIndexName}-${this.untitledCount}.cbs.json`);
+ const uri = vscode.Uri.parse(`couchbase:/search-workbench-${searchIndexNode.indexName}-${this.untitledCount}.cbs.json`);
this.untitledCount++;
- const defaultJsonContent = `{
- "query": {
- "query": "your_query_here"
- },
- "fields": ["*"]
+ const defaultJsonContent =
+`{
+ "query": {
+ "query": "your_query_here"
+ },
+ "fields": [
+ "*"
+ ]
}`;
let documentContent = Buffer.from(defaultJsonContent);
memFs.writeFile(uri, documentContent, {
diff --git a/src/commands/fts/SearchWorkbench/searchWorkbench.ts b/src/commands/fts/SearchWorkbench/searchWorkbench.ts
index 66d4b214..f9f4bc5e 100644
--- a/src/commands/fts/SearchWorkbench/searchWorkbench.ts
+++ b/src/commands/fts/SearchWorkbench/searchWorkbench.ts
@@ -1,7 +1,7 @@
import * as vscode from 'vscode';
import { getActiveConnection } from '../../../util/connections';
import { WorkbenchWebviewProvider } from '../../../workbench/workbenchWebviewProvider';
-import { CouchbaseError, QueryOptions, QueryProfileMode, QueryStatus } from "couchbase";
+import { QueryStatus } from "couchbase";
import { ISearchQueryContext } from '../../../types/ISearchQueryContext';
import { CouchbaseRestAPI } from '../../../util/apis/CouchbaseRestAPI';
import { MemFS } from "../../../util/fileSystemProvider";
@@ -34,6 +34,33 @@ export class SearchWorkbench {
// Get the active text editor
const activeTextEditor = vscode.window.activeTextEditor;
if (activeTextEditor && activeTextEditor.document.languageId === "json" && activeTextEditor.document.fileName.endsWith(".cbs.json")) {
+ try {
+ JSON.parse(activeTextEditor.document.getText())
+ }
+ catch (err) {
+ // Invalid JSON case
+ let errorArray = []
+ errorArray.push({
+ code: 0,
+ msg: "The query is not a valid JSON",
+ query: false,
+ });
+ const queryStatusProps = {
+ queryStatus: QueryStatus.Fatal,
+ rtt: "-",
+ elapsed: "-",
+ executionTime: "-",
+ numDocs: "-",
+ size: "-",
+ };
+ workbenchWebviewProvider.setQueryResult(
+ JSON.stringify(errorArray),
+ queryStatusProps,
+ null,
+ true
+ );
+ return;
+ }
activeTextEditor.document.save();
const indexQueryPayload = activeTextEditor.selection.isEmpty ? activeTextEditor.document.getText() : activeTextEditor.document.getText(activeTextEditor.selection);
@@ -47,30 +74,52 @@ export class SearchWorkbench {
await workbenchWebviewProvider.sendQueryResult(JSON.stringify([{ "status": "Executing statement" }]), { queryStatus: QueryStatus.Running }, null);
const explainPlan = JSON.stringify("");
const couchbbaseRestAPI = new CouchbaseRestAPI(connection);
+ const searchIndexesManager = connection?.cluster?.searchIndexes();
+ const ftsIndexes = await searchIndexesManager?.getAllIndexes();
+ const bucketIndexes = ftsIndexes?.filter(index => index.name === queryContext?.indexName);
+ if (bucketIndexes?.length == 0) {
+ // Index was deleted/ Not found
+ let editorId = activeTextEditor.document.uri.toString();
+ let editorContext = this.editorToContext.get(editorId);
+ if (editorContext) {
+ editorContext.statusBarItem.text = `$(group-by-ref-type) No Search Query Context Set`;
+ throw new Error("Search Index not found");
+ }
+ }
+ const start = Date.now();
const searchQueryResult = await couchbbaseRestAPI.runSearchIndexes(queryContext?.indexName, indexQueryPayload);
+ const end = Date.now()
+ const rtt = end - start
+ const resultJson = JSON.stringify(searchQueryResult);
+ const resultSize = new TextEncoder().encode(resultJson).length;
+ const queryStatusProps = {
+ queryStatus: searchQueryResult?.status.successful === 1 ? "success" : "fatal",
+ rtt: rtt.toString() + " MS",
+ elapsed: (searchQueryResult?.took / 1000).toString() + " MS",
+ numDocs: searchQueryResult?.total_hits.toString() + " docs",
+ size: resultSize ? (resultSize > 1000 ? (resultSize / 1000).toFixed(2) + " KB" : resultSize + " Bytes") : ""
+ };
workbenchWebviewProvider.setQueryResult(
JSON.stringify(searchQueryResult?.hits),
- {},
+ queryStatusProps,
explainPlan,
true
);
- } catch (err) {
+ } catch (err: any) {
const errorArray = [];
- if (err instanceof CouchbaseError) {
- const { first_error_code, first_error_message, statement } =
- err.cause as any;
- if (
- first_error_code !== undefined ||
- first_error_message !== undefined ||
- statement !== undefined
- ) {
+ if (err.response && err.response.data) {
+ if (err.response.status === 400) {
errorArray.push({
- code: first_error_code,
- msg: first_error_message,
- query: statement,
+ code: err.response.status,
+ msg: err.response.data.error || 'Bad request',
+ query: (err.config && err.config.url) ? err.config.url : 'No URL',
});
} else {
- errorArray.push(err);
+ errorArray.push({
+ code: err.response.status,
+ msg: err.message,
+ query: err.config && err.config.url
+ });
}
} else {
errorArray.push(err);
@@ -90,18 +139,17 @@ export class SearchWorkbench {
true
);
}
-
+
}
-
+
}
openSearchWorkbench(searchIndexNode: SearchIndexNode, memFs: MemFS) {
try {
return this._untitledSearchJsonDocumentService.newQuery(searchIndexNode, memFs);
} catch (error) {
logger.error("Error while opening Search WorkBench:" + error);
- throw error;
+ throw error;
}
}
-
}
\ No newline at end of file
diff --git a/src/extension.ts b/src/extension.ts
index 50f248fc..d752824b 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -83,6 +83,7 @@ import { handleSearchContextStatusbar } from "./handlers/handleSearchQueryContex
import { validateDocument } from "./commands/fts/SearchWorkbench/validators/validationUtil";
import { AutocompleteVisitor } from "./commands/fts/SearchWorkbench/contributor/autoCompleteVisitor";
import { CbsJsonHoverProvider } from "./commands/fts/SearchWorkbench/documentation/documentationProvider";
+import { deleteIndex } from "./util/ftsIndexUtils";
export function activate(context: vscode.ExtensionContext) {
Global.setState(context.globalState);
@@ -369,6 +370,16 @@ context.subscriptions.push(disposable);
)
);
+ subscriptions.push(
+ vscode.commands.registerCommand(
+ Commands.deleteSearchIndex,
+ async (searchIndexNode: SearchIndexNode) => {
+ await deleteIndex(searchIndexNode);
+ clusterConnectionTreeProvider.refresh();
+ }
+ )
+ );
+
subscriptions.push(
vscode.commands.registerCommand(
Commands.openIndexInfo,
@@ -769,17 +780,19 @@ context.subscriptions.push(disposable);
searchWorkbench.openSearchWorkbench(searchIndexNode, memFs);
- const editorChangeSubscription = vscode.window.onDidChangeActiveTextEditor(async (editor) => {
- if (editor && editor.document.languageId === "json" && editor.document.fileName.endsWith(".cbs.json")) {
- await handleSearchContextStatusbar(editor, searchIndexNode, searchWorkbench, globalStatusBarItem);
- }
- });
- context.subscriptions.push(editorChangeSubscription);
});
context.subscriptions.push(openSearchWorkbenchCommand);
+ subscriptions.push(
+ vscode.window.onDidChangeActiveTextEditor(async (editor) => {
+ if (editor && editor.document.languageId === "json" && editor.document.fileName.endsWith(".cbs.json")) {
+ await handleSearchContextStatusbar(editor, currentSearchIndexNode, searchWorkbench, globalStatusBarItem);
+ }
+ })
+ );
+
context.subscriptions.push(
vscode.workspace.registerNotebookSerializer(
diff --git a/src/model/CollectionDirectory.ts b/src/model/CollectionDirectory.ts
index fbcba068..d09ce192 100644
--- a/src/model/CollectionDirectory.ts
+++ b/src/model/CollectionDirectory.ts
@@ -24,7 +24,7 @@ export class CollectionDirectory implements INode {
public getTreeItem(): vscode.TreeItem {
return {
label: `Collections`,
- collapsibleState: vscode.TreeItemCollapsibleState.Collapsed,
+ collapsibleState: vscode.TreeItemCollapsibleState.Expanded,
contextValue: "collectionDirectory",
};
}
diff --git a/src/model/SearchDirectory.ts b/src/model/SearchDirectory.ts
index fcb1ef87..ad548d2b 100644
--- a/src/model/SearchDirectory.ts
+++ b/src/model/SearchDirectory.ts
@@ -47,18 +47,16 @@ export class SearchDirectory implements INode {
return []
}
- const searchIndexesManager = connection?.cluster?.searchIndexes();
- const ftsIndexes = await searchIndexesManager?.getAllIndexes();
- const bucketIndexes = ftsIndexes?.filter(index => index.sourceName === this.bucketName);
+ const searchIndexesManager = connection?.cluster?.bucket(this.bucketName).scope(this.scopeName).searchIndexes();
+ const bucketIndexes = await searchIndexesManager?.getAllIndexes();
if (bucketIndexes === undefined) {
return [];
}
const searchIndexChildren: INode[] = bucketIndexes.map((searchIndex) =>
new SearchIndexNode(
- searchIndex.name,
this.bucketName,
this.scopeName,
- searchIndex.name
+ `${this.bucketName}.${this.scopeName}.${searchIndex.name}`
)
diff --git a/src/model/SearchIndexNode.ts b/src/model/SearchIndexNode.ts
index 53f0e35a..8d152069 100644
--- a/src/model/SearchIndexNode.ts
+++ b/src/model/SearchIndexNode.ts
@@ -4,14 +4,13 @@ import * as path from "path";
export default class SearchIndexNode implements INode {
constructor(
- public readonly searchIndexName: string,
public readonly bucketName: string,
public readonly scopeName: string,
public readonly indexName: string,
) { }
public async getTreeItem(): Promise {
return {
- label: `${this.searchIndexName}`,
+ label: `${this.indexName}`,
collapsibleState: vscode.TreeItemCollapsibleState.None,
contextValue: "searchIndex",
command: {
diff --git a/src/pages/queryContext/queryContext.ts b/src/pages/queryContext/queryContext.ts
index 6908729f..dafa5be3 100644
--- a/src/pages/queryContext/queryContext.ts
+++ b/src/pages/queryContext/queryContext.ts
@@ -4,7 +4,7 @@ import * as vscode from 'vscode';
import { logger } from "../../logger/logger";
import { Bucket, BucketSettings } from "couchbase";
import { QueryWorkbench } from "../../workbench/queryWorkbench";
-import { showQueryContextStatusbar } from "../../util/queryContextUtils";
+import { showQueryContextStatusbar, showSearchContextStatusbar } from "../../util/queryContextUtils";
import { getActiveConnection } from "../../util/connections";
import { SearchWorkbench } from "../../commands/fts/SearchWorkbench/searchWorkbench";
import SearchIndexNode from "../../model/SearchIndexNode";
@@ -124,7 +124,7 @@ export async function fetchSearchContext(searchIndexNode: SearchIndexNode, workb
label: bucket.name,
iconPath: new vscode.ThemeIcon("database")
})), {
- placeHolder: 'Query Context: Select a bucket',
+ placeHolder: 'Search Query Context: Select a bucket',
canPickMany: false
});
@@ -133,7 +133,7 @@ export async function fetchSearchContext(searchIndexNode: SearchIndexNode, workb
return;
}
- const bucketNameSelected = selectedItem.label;
+ let bucketNameSelected = selectedItem.label;
// Fetching search indexes specific to the selected bucket
const searchIndexesManager = connection?.cluster?.searchIndexes();
@@ -158,22 +158,22 @@ export async function fetchSearchContext(searchIndexNode: SearchIndexNode, workb
return;
}
- const editorId = activeEditor.document.uri.toString();
+ let editorId = activeEditor.document.uri.toString();
+ let editorContext = workbench.editorToContext.get(editorId);
+
+ let displayBucketName = bucketNameSelected.length > 15 ? `${bucketNameSelected.substring(0, 13)}...` : bucketNameSelected;
+ let displayIndexName = indexNameSelected.label.length > 15 ? `${indexNameSelected.label.substring(0, 13)}...` : indexNameSelected.label;
- // Setting new context
- workbench.editorToContext.set(editorId, {
+ editorContext = {
bucketName: bucketNameSelected,
indexName: indexNameSelected.label,
statusBarItem: globalStatusBarItem,
searchNode: searchIndexNode
- });
-
- // Update the status bar directly
- let displayBucketName = bucketNameSelected.length > 15 ? `${bucketNameSelected.substring(0, 13)}...` : bucketNameSelected;
- let displayIndexName = indexNameSelected.label.length > 15 ? `${indexNameSelected.label.substring(0, 13)}...` : indexNameSelected.label;
- globalStatusBarItem.text = `$(group-by-ref-type) ${displayBucketName} > ${displayIndexName}`;
- globalStatusBarItem.tooltip = "Search Query Context";
- globalStatusBarItem.command = Commands.searchContext;
+ };
+ workbench.editorToContext.set(editorId, editorContext);
+ editorContext.statusBarItem.text = `$(group-by-ref-type) ${displayBucketName} > ${displayIndexName}`;
+ editorContext.statusBarItem.tooltip = "Search Query Context";
+ editorContext.statusBarItem.command = Commands.searchContext;
} catch (err) {
logger.error(`Failed to open and set query context: ${err}`);
diff --git a/src/util/ftsIndexUtils.ts b/src/util/ftsIndexUtils.ts
new file mode 100644
index 00000000..cad360c6
--- /dev/null
+++ b/src/util/ftsIndexUtils.ts
@@ -0,0 +1,24 @@
+import * as vscode from "vscode";
+import SearchIndexNode from "../model/SearchIndexNode";
+import { getActiveConnection } from "./connections";
+import { logger } from "../logger/logger";
+
+export async function deleteIndex(searchIndexNode: SearchIndexNode) {
+ const connection = getActiveConnection()
+ if (!connection) {
+ return;
+ }
+
+ let answer = await vscode.window.showInformationMessage(`Are you sure you want to DELETE the index: ${searchIndexNode.indexName}?`, ...["Yes", "No"]);
+ if (answer !== "Yes") {
+ return;
+ }
+
+ try {
+ const searchIndexesManager = connection?.cluster?.searchIndexes();
+ searchIndexesManager?.dropIndex(searchIndexNode.indexName)
+ } catch (err) {
+ logger.error("An error occurred while trying to delete the index" + searchIndexNode.indexName + err)
+ await vscode.window.showInformationMessage(`Could not delete the index. Please check the logs.`)
+ }
+}
\ No newline at end of file
diff --git a/src/util/queryContextUtils.ts b/src/util/queryContextUtils.ts
index 3204c3d9..dc20116a 100644
--- a/src/util/queryContextUtils.ts
+++ b/src/util/queryContextUtils.ts
@@ -37,28 +37,30 @@ export const showSearchContextStatusbar = async (editor: vscode.TextEditor, sear
context.statusBarItem.hide();
}
});
+ if (!editorContext) {
+ editorContext = {
+ bucketName: searchNode.bucketName,
+ indexName: searchNode.indexName,
+ statusBarItem: globalStatusBarItem,
+ searchNode: searchNode
+ };
+ workbench.editorToContext.set(editorId, editorContext);
+ }
+
+ const contextSearchNode = editorContext;
- editorContext = {
- bucketName: searchNode.bucketName,
- indexName: searchNode.indexName,
- statusBarItem: globalStatusBarItem,
- searchNode: searchNode
- };
- workbench.editorToContext.set(editorId, editorContext);
-
+ let displayBucketName = contextSearchNode.bucketName ?? "";
+ let displayIndexName = contextSearchNode.indexName ?? "";
- // Update global status bar text based on Node selected by user
- let displayBucketName = searchNode.bucketName.length > 15 ? `${searchNode.bucketName.substring(0, 13)}...` : searchNode.bucketName;
- let displayIndexName = searchNode.searchIndexName.length > 15 ? `${searchNode.searchIndexName.substring(0, 13)}...` : searchNode.searchIndexName;
+ displayBucketName = displayBucketName.length > 15 ? `${displayBucketName.substring(0, 13)}...` : displayBucketName;
+ displayIndexName = displayIndexName.length > 15 ? `${displayIndexName.substring(0, 13)}...` : displayIndexName;
editorContext.statusBarItem.text = `$(group-by-ref-type) ${displayBucketName} > ${displayIndexName}`;
+ if (displayBucketName === "" || displayIndexName === ""){
+ editorContext.statusBarItem.text = `$(group-by-ref-type) No Search Query Context Set`;
+ }
editorContext.statusBarItem.tooltip = "Search Query Context";
editorContext.statusBarItem.command = Commands.searchContext;
- // Check and update the context if it has changed
- if (editorContext.searchNode !== searchNode) {
- editorContext.searchNode = searchNode;
- workbench.editorToContext.set(editorId, editorContext);
- }
editorContext.statusBarItem.show();
};
From b8f15904b179138bc471db136ac1e3272b4d57d6 Mon Sep 17 00:00:00 2001
From: Prajwal Pai
Date: Thu, 18 Jul 2024 13:26:20 +0530
Subject: [PATCH 21/24] Update package version and changelog
---
CHANGELOG.md | 6 ++++++
package-lock.json | 4 ++--
package.json | 2 +-
3 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 993b5ab9..c1f4de71 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
# Change Log
+## [v2.1.0]
+- Add FTS workbench support inside extension
+- Add FTS workbench json validation
+- Add FTS workbench json auto complete feature
+- Add FTS workbench documentation
+
## [v2.0.0]
- Bump Node.js version to 20
- Add MongoDB to Couchbase data Migration tool
diff --git a/package-lock.json b/package-lock.json
index 8305bec0..bdf480d2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "vscode-couchbase",
- "version": "2.0.2",
+ "version": "2.1.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "vscode-couchbase",
- "version": "2.0.2",
+ "version": "2.1.0",
"license": "SEE LICENSE IN LICENSE",
"dependencies": {
"@chatscope/chat-ui-kit-styles": "^1.4.0",
diff --git a/package.json b/package.json
index f397c3c4..3ea0ec6d 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "vscode-couchbase",
"displayName": "Couchbase",
"description": "",
- "version": "2.0.2",
+ "version": "2.1.0",
"engines": {
"vscode": "^1.63.1"
},
From f19d65901866d8d2d4ae1c321de156f7a2959079 Mon Sep 17 00:00:00 2001
From: Prajwal Pai
Date: Thu, 18 Jul 2024 16:00:40 +0530
Subject: [PATCH 22/24] Update changelog + format using prettier
---
CHANGELOG.md | 14 +
__mocks__/vscode.js | 33 +-
.../contributor/autoComplete.ts | 20 +-
.../contributor/autoCompleteVisitor.ts | 300 ++++++---
.../contributor/booleanCbsContributor.ts | 17 +-
.../contributor/cbsTemplates.ts | 136 ++--
.../contributor/consistencyCbsContributor.ts | 35 +-
.../contributor/ctlCbsContributor.ts | 27 +-
.../contributor/fieldsContributor.ts | 92 ++-
.../contributor/geometryCbsContributor.ts | 30 +-
.../contributor/highlightCbsContributor.ts | 23 +-
.../contributor/knnCbsContributor.ts | 32 +-
.../contributor/locationCbsContributor.ts | 33 +-
.../contributor/queryCbsContributor.ts | 558 ++++++++++++----
.../contributor/shapeCbsContributor.ts | 134 ++--
.../fts/SearchWorkbench/controller.ts | 60 +-
.../documentation/documentationProvider.ts | 66 +-
.../indexParser/indexParser.ts | 59 +-
.../fts/SearchWorkbench/openSearchIndex.ts | 45 +-
.../fts/SearchWorkbench/searchWorkbench.ts | 110 ++--
.../test/booleanObject.test.ts | 108 ++-
.../test/ctlConsistencyObject.test.ts | 174 +++--
.../test/geometryObject.test.ts | 149 +++--
.../test/highlightObject.test.ts | 119 ++--
.../SearchWorkbench/test/knnObject.test.ts | 66 +-
.../test/matchAllNoneObject.test.ts | 80 ++-
.../SearchWorkbench/test/queryObject.test.ts | 128 +++-
.../test/queryTypeObject.test.ts | 622 ++++++++++++++----
.../SearchWorkbench/test/rootObject.test.ts | 265 ++++++--
.../SearchWorkbench/validators/JsonNodes.ts | 6 +-
.../validators/booleanObjectValidator.ts | 63 +-
.../ctlConsistencyObjectValidator.ts | 127 ++--
.../validators/ctlObjectValidator.ts | 79 ++-
.../validators/geometryObjectValidator.ts | 102 ++-
.../validators/highlightObjectValidator.ts | 62 +-
.../validators/knnObjectValidator.ts | 69 +-
.../validators/matchAllNoneObjectValidator.ts | 38 +-
.../validators/queryObjectValidator.ts | 87 ++-
.../validators/queryTypeObjectValidator.ts | 568 ++++++++++++----
.../validators/rootObjectValidator.ts | 94 ++-
.../validators/searchValidator.ts | 11 +-
.../validators/shapeObjectValidator.ts | 255 +++++--
.../validators/validationHelper.ts | 75 ++-
.../validators/validationUtil.ts | 512 ++++++++------
.../handleSearchQueryContextStatusBar.ts | 30 +-
src/pages/queryContext/queryContext.ts | 189 ++++--
.../contributor/cbsCtlCodeCompletion.test.ts | 217 +++---
.../cbsGeometryCodeCompletion.test.ts | 102 +--
.../cbsHighlightCodeCompletion.test.ts | 126 ++--
.../contributor/cbsKnnCodeCompletion.test.ts | 103 +--
.../cbsQueryCodeCompletion.test.ts | 580 +++++++++-------
.../contributor/cbsRootCodeCompletion.test.ts | 125 ++--
.../cbsShapeCodeCompletion.test.ts | 142 ++--
src/util/ftsIndexUtils.ts | 21 +-
54 files changed, 5030 insertions(+), 2288 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c1f4de71..52588bda 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,20 @@
- Add FTS workbench json auto complete feature
- Add FTS workbench documentation
+## [v2.0.5]
+- Add UI support for DynamoDB To Couchbase Data Migration
+
+## [v2.0.4]
+- Add support for N1QL (.n1ql) files in query workbench
+
+## [v2.0.3]
+- KV Range based document filter
+- Named Parameters Support
+- Basic Autocomplete Support
+
+## [v2.0.1]
+- Update Filter Documents and Capella iQ Bug Fixes
+
## [v2.0.0]
- Bump Node.js version to 20
- Add MongoDB to Couchbase data Migration tool
diff --git a/__mocks__/vscode.js b/__mocks__/vscode.js
index 5e23aea0..5b39f452 100644
--- a/__mocks__/vscode.js
+++ b/__mocks__/vscode.js
@@ -7,10 +7,14 @@ const vscode = {
return {
clear: jest.fn(() => diagnosticsMap.clear()),
dispose: jest.fn(),
- get: jest.fn(uri => diagnosticsMap.get(uri.toString())),
- set: jest.fn((uri, diagnostics) => diagnosticsMap.set(uri.toString(), diagnostics)),
- delete: jest.fn(uri => diagnosticsMap.delete(uri.toString())),
- forEach: jest.fn(callback => diagnosticsMap.forEach(callback)),
+ get: jest.fn((uri) => diagnosticsMap.get(uri.toString())),
+ set: jest.fn((uri, diagnostics) =>
+ diagnosticsMap.set(uri.toString(), diagnostics),
+ ),
+ delete: jest.fn((uri) => diagnosticsMap.delete(uri.toString())),
+ forEach: jest.fn((callback) =>
+ diagnosticsMap.forEach(callback),
+ ),
};
}),
},
@@ -21,35 +25,38 @@ const vscode = {
},
workspace: {
openTextDocument: jest.fn().mockImplementation((uri) => ({
- getText: jest.fn(() => ''),
+ getText: jest.fn(() => ""),
uri: uri,
positionAt: jest.fn().mockImplementation((index) => {
- return new vscode.Position(Math.floor(index / 100), index % 100);
+ return new vscode.Position(
+ Math.floor(index / 100),
+ index % 100,
+ );
}),
})),
fs: {
writeFile: jest.fn(),
- }
+ },
},
Range: jest.fn().mockImplementation((start, end) => ({
start: start,
- end: end
+ end: end,
})),
Position: jest.fn().mockImplementation((line, character) => ({
line: line,
- character: character
+ character: character,
})),
Diagnostic: jest.fn().mockImplementation((range, message, severity) => ({
range: range,
message: message,
- severity: severity
+ severity: severity,
})),
DiagnosticSeverity: {
Error: 0,
Warning: 1,
Information: 2,
- Hint: 3
- }
+ Hint: 3,
+ },
};
-module.exports = vscode;
\ No newline at end of file
+module.exports = vscode;
diff --git a/src/commands/fts/SearchWorkbench/contributor/autoComplete.ts b/src/commands/fts/SearchWorkbench/contributor/autoComplete.ts
index cb5db227..fc210f8c 100644
--- a/src/commands/fts/SearchWorkbench/contributor/autoComplete.ts
+++ b/src/commands/fts/SearchWorkbench/contributor/autoComplete.ts
@@ -1,11 +1,21 @@
-import * as jsonc from 'jsonc-parser';
-import * as vscode from 'vscode';
+import * as jsonc from "jsonc-parser";
+import * as vscode from "vscode";
export interface CBSContributor {
-
accept(key: string | null): boolean;
- contributeKey(parentKey: string | null, node: jsonc.Node, suggestion: string[], result: vscode.CompletionItem[], existingKeys:string[]): any;
+ contributeKey(
+ parentKey: string | null,
+ node: jsonc.Node,
+ suggestion: string[],
+ result: vscode.CompletionItem[],
+ existingKeys: string[],
+ ): any;
- contributeValue(attributeKey: string | null, node: jsonc.Node, suggestion: string[], fields:string[]): any;
+ contributeValue(
+ attributeKey: string | null,
+ node: jsonc.Node,
+ suggestion: string[],
+ fields: string[],
+ ): any;
}
diff --git a/src/commands/fts/SearchWorkbench/contributor/autoCompleteVisitor.ts b/src/commands/fts/SearchWorkbench/contributor/autoCompleteVisitor.ts
index 3d78b027..74a4cdc4 100644
--- a/src/commands/fts/SearchWorkbench/contributor/autoCompleteVisitor.ts
+++ b/src/commands/fts/SearchWorkbench/contributor/autoCompleteVisitor.ts
@@ -1,43 +1,77 @@
-import * as vscode from 'vscode';
-import * as jsonc from 'jsonc-parser';
-import { CBSContributor } from './autoComplete';
-import { booleanCbsContributor } from './booleanCbsContributor';
-import { consistencyCbsContributor } from './consistencyCbsContributor';
-import { geometryCbsContributor } from './geometryCbsContributor';
-import { highlightCbsContributor } from './highlightCbsContributor';
-import { knnCbsContributor } from './knnCbsContributor';
-import { locationCbsContributor } from './locationCbsContributor';
-import { fieldsContributor } from './fieldsContributor';
-import { queryCbsContributor } from './queryCbsContributor';
-import { cbsTemplate } from './cbsTemplates';
-import { ctlCbsContributor } from './ctlCbsContributor';
-import { shapeCbsContributor } from './shapeCbsContributor';
-import { SearchWorkbench } from '../searchWorkbench';
-import { logger } from '../../../../logger/logger';
-
-
+import * as vscode from "vscode";
+import * as jsonc from "jsonc-parser";
+import { CBSContributor } from "./autoComplete";
+import { booleanCbsContributor } from "./booleanCbsContributor";
+import { consistencyCbsContributor } from "./consistencyCbsContributor";
+import { geometryCbsContributor } from "./geometryCbsContributor";
+import { highlightCbsContributor } from "./highlightCbsContributor";
+import { knnCbsContributor } from "./knnCbsContributor";
+import { locationCbsContributor } from "./locationCbsContributor";
+import { fieldsContributor } from "./fieldsContributor";
+import { queryCbsContributor } from "./queryCbsContributor";
+import { cbsTemplate } from "./cbsTemplates";
+import { ctlCbsContributor } from "./ctlCbsContributor";
+import { shapeCbsContributor } from "./shapeCbsContributor";
+import { SearchWorkbench } from "../searchWorkbench";
+import { logger } from "../../../../logger/logger";
export class AutocompleteVisitor {
- public topLevelKeywords: string[] = ["query", "knn", "ctl", "size", "limit", "from", "offset", "highlight", "fields", "facets", "explain", "sort", "includeLocations", "score", "search_after", "search_before", "collections"];
- private contributors: CBSContributor[] = [new booleanCbsContributor(), new consistencyCbsContributor(), new geometryCbsContributor(), new highlightCbsContributor(), new knnCbsContributor(), new locationCbsContributor(), new queryCbsContributor(), new ctlCbsContributor(), new shapeCbsContributor()];
-
- async getAutoCompleteContributor(document: vscode.TextDocument, position: vscode.Position, searchWorkBench?: SearchWorkbench): Promise {
+ public topLevelKeywords: string[] = [
+ "query",
+ "knn",
+ "ctl",
+ "size",
+ "limit",
+ "from",
+ "offset",
+ "highlight",
+ "fields",
+ "facets",
+ "explain",
+ "sort",
+ "includeLocations",
+ "score",
+ "search_after",
+ "search_before",
+ "collections",
+ ];
+ private contributors: CBSContributor[] = [
+ new booleanCbsContributor(),
+ new consistencyCbsContributor(),
+ new geometryCbsContributor(),
+ new highlightCbsContributor(),
+ new knnCbsContributor(),
+ new locationCbsContributor(),
+ new queryCbsContributor(),
+ new ctlCbsContributor(),
+ new shapeCbsContributor(),
+ ];
+
+ async getAutoCompleteContributor(
+ document: vscode.TextDocument,
+ position: vscode.Position,
+ searchWorkBench?: SearchWorkbench,
+ ): Promise {
const text = document.getText();
// const rootNode = jsonc.parseTree(text);
- const queryContext = searchWorkBench?.editorToContext.get(document.uri.toString());
+ const queryContext = searchWorkBench?.editorToContext.get(
+ document.uri.toString(),
+ );
const tempJsonString = this.addTemporaryQuotes(text, position);
const rootNode = jsonc.parseTree(tempJsonString);
-
if (!rootNode) {
return [];
}
- const node = jsonc.findNodeAtOffset(rootNode, document.offsetAt(position));
+ const node = jsonc.findNodeAtOffset(
+ rootNode,
+ document.offsetAt(position),
+ );
if (!node) {
return [];
}
- if(!this.isWithinObject(node)){
+ if (!this.isWithinObject(node)) {
return [];
}
const isKey = this.isKey(document, position);
@@ -50,46 +84,63 @@ export class AutocompleteVisitor {
const result: vscode.CompletionItem[] = [];
const existingKeys: string[] = [];
- await this.fetchKeys(node, existingKeys)
+ await this.fetchKeys(node, existingKeys);
const isWithinQuotes = this.isWithinQuotes(document, position);
if (this.isTopLevelProperty(rootNode, node)) {
-
if (!isKey) {
- if (attributeName == 'score') {
- suggestions.push('none');
+ if (attributeName == "score") {
+ suggestions.push("none");
}
} else {
- suggestions.push(...this.topLevelKeywords.filter(keyword => !existingKeys.includes(keyword)));
-
+ suggestions.push(
+ ...this.topLevelKeywords.filter(
+ (keyword) => !existingKeys.includes(keyword),
+ ),
+ );
- if (!existingKeys.includes('highlight')) {
+ if (!existingKeys.includes("highlight")) {
result.push(cbsTemplate.getHighlightTemplate());
}
- if (!existingKeys.includes('knn')) {
- result.push(cbsTemplate.getKNNTemplate())
+ if (!existingKeys.includes("knn")) {
+ result.push(cbsTemplate.getKNNTemplate());
}
}
-
} else {
let type = this.getNodeType(node, rootNode);
for (const contributor of this.contributors) {
if (contributor.accept(type)) {
if (isKey) {
- const existingKeys2 = existingKeys.filter(item => item !== '');
- contributor.contributeKey(type, node, suggestions, result, existingKeys2);
- }
- else {
- let fields: string[] = []
- if (attributeName == "field" && queryContext?.bucketName && queryContext?.indexName) {
- fields = await fieldsContributor.getFieldNames(queryContext?.bucketName, queryContext?.indexName)
+ const existingKeys2 = existingKeys.filter(
+ (item) => item !== "",
+ );
+ contributor.contributeKey(
+ type,
+ node,
+ suggestions,
+ result,
+ existingKeys2,
+ );
+ } else {
+ let fields: string[] = [];
+ if (
+ attributeName == "field" &&
+ queryContext?.bucketName &&
+ queryContext?.indexName
+ ) {
+ fields = await fieldsContributor.getFieldNames(
+ queryContext?.bucketName,
+ queryContext?.indexName,
+ );
}
- contributor.contributeValue(attributeName, node, suggestions, fields)
+ contributor.contributeValue(
+ attributeName,
+ node,
+ suggestions,
+ fields,
+ );
}
}
- };
-
-
-
+ }
}
for (const suggestion of suggestions) {
if (!existingKeys.includes(suggestion)) {
@@ -98,39 +149,44 @@ export class AutocompleteVisitor {
itemLabel = `"${suggestion}"`;
}
- const completionItem = new vscode.CompletionItem(itemLabel, vscode.CompletionItemKind.Text);
+ const completionItem = new vscode.CompletionItem(
+ itemLabel,
+ vscode.CompletionItemKind.Text,
+ );
result.push(completionItem);
}
- };
+ }
return result;
}
addTemporaryQuotes(jsonString: string, position: vscode.Position): string {
- const lines = jsonString.split('\n');
+ const lines = jsonString.split("\n");
const line = lines[position.line];
-
+
const regex = /("(\w+)")\s*:\s*,/;
-
+
if (regex.test(line)) {
- return lines.map((l, i) =>
- i === position.line ? l.replace(regex, '$1: "",') : l
- ).join('\n');
+ return lines
+ .map((l, i) =>
+ i === position.line ? l.replace(regex, '$1: "",') : l,
+ )
+ .join("\n");
}
-
+
return jsonString;
}
isTopLevelProperty(rootNode: jsonc.Node, currentNode: jsonc.Node) {
if (currentNode === rootNode) {
- return true
+ return true;
}
- if (currentNode.type === 'string') {
+ if (currentNode.type === "string") {
if (currentNode.parent && currentNode.parent.parent) {
- const propertyNode = currentNode.parent.parent
- return propertyNode === rootNode
+ const propertyNode = currentNode.parent.parent;
+ return propertyNode === rootNode;
}
}
- if (currentNode.type === 'property' && currentNode.parent) {
+ if (currentNode.type === "property" && currentNode.parent) {
return currentNode.parent === rootNode;
}
@@ -138,22 +194,29 @@ export class AutocompleteVisitor {
}
async fetchKeys(node: jsonc.Node, existingKeys: string[]): Promise {
- if (node.type === 'object') {
+ if (node.type === "object") {
for (const prop of node.children || []) {
- if (prop.type === 'property') {
- const keyNode = prop.children?.[0];
- if (keyNode && keyNode.type === 'string') {
+ if (prop.type === "property") {
+ const keyNode = prop.children?.[0];
+ if (keyNode && keyNode.type === "string") {
existingKeys.push(keyNode.value as string);
}
}
}
- } else if (node.type === 'string') {
- if (node.parent?.type === 'property' && node.parent.parent?.type === 'object') {
+ } else if (node.type === "string") {
+ if (
+ node.parent?.type === "property" &&
+ node.parent.parent?.type === "object"
+ ) {
const objectNode = node.parent.parent;
for (const prop of objectNode.children || []) {
- if (prop.type === 'property') {
- const keyNode = prop.children?.[0];
- if (keyNode && keyNode.type === 'string' && keyNode.value !== '') {
+ if (prop.type === "property") {
+ const keyNode = prop.children?.[0];
+ if (
+ keyNode &&
+ keyNode.type === "string" &&
+ keyNode.value !== ""
+ ) {
existingKeys.push(keyNode.value as string);
}
}
@@ -162,33 +225,50 @@ export class AutocompleteVisitor {
}
}
-
-
- getNodeType(node: jsonc.Node | undefined, rootNode: jsonc.Node): string | null {
- let currentNode = node ;
+ getNodeType(
+ node: jsonc.Node | undefined,
+ rootNode: jsonc.Node,
+ ): string | null {
+ let currentNode = node;
if (!currentNode) {
- logger.debug("Error fetching Node type, Node is undefined")
+ logger.debug("Error fetching Node type, Node is undefined");
return null;
}
-
let lastPropertyName = undefined;
let count = 0;
while (currentNode) {
- if (currentNode.type === 'property') {
+ if (currentNode.type === "property") {
if (currentNode.parent) {
count = count + 1;
- lastPropertyName = jsonc.findNodeAtOffset(rootNode, currentNode.offset)?.value;
+ lastPropertyName = jsonc.findNodeAtOffset(
+ rootNode,
+ currentNode.offset,
+ )?.value;
if (count == 2) {
break;
}
}
- } else if (currentNode.type === 'array' && currentNode.parent && currentNode.parent.type === 'property') {
- lastPropertyName = jsonc.findNodeAtOffset(rootNode, currentNode.parent.offset)?.value;
+ } else if (
+ currentNode.type === "array" &&
+ currentNode.parent &&
+ currentNode.parent.type === "property"
+ ) {
+ lastPropertyName = jsonc.findNodeAtOffset(
+ rootNode,
+ currentNode.parent.offset,
+ )?.value;
break;
- } else if ( currentNode.type === 'object' && currentNode.parent && currentNode.parent.type === 'property'){
- lastPropertyName = jsonc.findNodeAtOffset(rootNode,currentNode.parent.offset)?.value
+ } else if (
+ currentNode.type === "object" &&
+ currentNode.parent &&
+ currentNode.parent.type === "property"
+ ) {
+ lastPropertyName = jsonc.findNodeAtOffset(
+ rootNode,
+ currentNode.parent.offset,
+ )?.value;
break;
}
currentNode = currentNode.parent;
@@ -202,7 +282,9 @@ export class AutocompleteVisitor {
}
isKey(document: vscode.TextDocument, position: vscode.Position): boolean {
- const lineText = document.lineAt(position.line).text.substring(0, position.character);
+ const lineText = document
+ .lineAt(position.line)
+ .text.substring(0, position.character);
if (/^\s*[\{,]\s*$/.test(lineText)) {
return true;
@@ -212,15 +294,15 @@ export class AutocompleteVisitor {
for (let i = position.character - 1; i >= 0; i--) {
const char = lineText[i];
switch (char) {
- case ':':
+ case ":":
if (depth === 0) return false;
break;
- case '{':
- case '[':
+ case "{":
+ case "[":
depth++;
break;
- case '}':
- case ']':
+ case "}":
+ case "]":
depth--;
break;
}
@@ -229,17 +311,18 @@ export class AutocompleteVisitor {
return true;
}
-
-
-
getAttributeName(rootNode: jsonc.Node, currentNode: jsonc.Node) {
if (!rootNode) {
- return null
+ return null;
}
if (currentNode && currentNode.parent?.type === "object") {
return jsonc.findNodeAtOffset(rootNode, currentNode.offset)?.value;
}
- if (currentNode && currentNode.parent && currentNode.parent?.type === "property") {
+ if (
+ currentNode &&
+ currentNode.parent &&
+ currentNode.parent?.type === "property"
+ ) {
const propertyNode = currentNode.parent;
return jsonc.findNodeAtOffset(rootNode, propertyNode.offset)?.value;
}
@@ -247,7 +330,10 @@ export class AutocompleteVisitor {
return null;
}
- isWithinQuotes(document: vscode.TextDocument, position: vscode.Position): boolean {
+ isWithinQuotes(
+ document: vscode.TextDocument,
+ position: vscode.Position,
+ ): boolean {
const lineText = document.lineAt(position.line).text;
const charPos = position.character;
@@ -255,14 +341,14 @@ export class AutocompleteVisitor {
let quoteClose = false;
for (let i = charPos - 1; i >= 0; i--) {
- if (lineText[i] === '"' && (i === 0 || lineText[i - 1] !== '\\')) {
+ if (lineText[i] === '"' && (i === 0 || lineText[i - 1] !== "\\")) {
quoteOpen = true;
break;
}
}
for (let i = charPos; i < lineText.length; i++) {
- if (lineText[i] === '"' && (i === 0 || lineText[i - 1] !== '\\')) {
+ if (lineText[i] === '"' && (i === 0 || lineText[i - 1] !== "\\")) {
quoteClose = true;
break;
}
@@ -271,19 +357,25 @@ export class AutocompleteVisitor {
return quoteOpen && quoteClose;
}
- isWithinObject(currentNode: jsonc.Node): boolean{
+ isWithinObject(currentNode: jsonc.Node): boolean {
while (currentNode) {
- if (currentNode.type === 'array') {
+ if (currentNode.type === "array") {
let objectWithinArray: jsonc.Node | undefined = currentNode;
- while (objectWithinArray && objectWithinArray.type !== 'object') {
+ while (
+ objectWithinArray &&
+ objectWithinArray.type !== "object"
+ ) {
objectWithinArray = objectWithinArray.parent;
}
- return objectWithinArray !== undefined && objectWithinArray.parent === currentNode;
- } else if (currentNode.type === 'object') {
+ return (
+ objectWithinArray !== undefined &&
+ objectWithinArray.parent === currentNode
+ );
+ } else if (currentNode.type === "object") {
return true;
}
- if(currentNode.parent){
- currentNode = currentNode.parent;
+ if (currentNode.parent) {
+ currentNode = currentNode.parent;
}
}
diff --git a/src/commands/fts/SearchWorkbench/contributor/booleanCbsContributor.ts b/src/commands/fts/SearchWorkbench/contributor/booleanCbsContributor.ts
index 0d4038b0..4d59ddb8 100644
--- a/src/commands/fts/SearchWorkbench/contributor/booleanCbsContributor.ts
+++ b/src/commands/fts/SearchWorkbench/contributor/booleanCbsContributor.ts
@@ -1,23 +1,18 @@
-import { Node } from 'jsonc-parser'
-import { CBSContributor } from './autoComplete'
+import { Node } from "jsonc-parser";
+import { CBSContributor } from "./autoComplete";
export class booleanCbsContributor implements CBSContributor {
-
accept(key: string | null): boolean {
return key === "must" || key === "must_not" || key === "should";
}
contributeKey(parentKey: string, node: Node, suggestion: string[]) {
if (parentKey === "must") {
- suggestion.push("conjuncts")
+ suggestion.push("conjuncts");
} else if (parentKey == "must_not" || parentKey == "should") {
- suggestion.push("disjuncts")
+ suggestion.push("disjuncts");
}
-
- }
-
- contributeValue(attributeKey: string, node: Node, suggestion: string[]) {
-
}
-}
\ No newline at end of file
+ contributeValue(attributeKey: string, node: Node, suggestion: string[]) {}
+}
diff --git a/src/commands/fts/SearchWorkbench/contributor/cbsTemplates.ts b/src/commands/fts/SearchWorkbench/contributor/cbsTemplates.ts
index 4bf7d765..c9a01540 100644
--- a/src/commands/fts/SearchWorkbench/contributor/cbsTemplates.ts
+++ b/src/commands/fts/SearchWorkbench/contributor/cbsTemplates.ts
@@ -1,43 +1,50 @@
-import * as vscode from 'vscode';
+import * as vscode from "vscode";
export class cbsTemplate {
-
static getQueryTemplate(existingKeys: string[]): vscode.CompletionItem {
- const QUERY = 'query';
- const snippetCompletion = new vscode.CompletionItem(QUERY, vscode.CompletionItemKind.Module);
+ const QUERY = "query";
+ const snippetCompletion = new vscode.CompletionItem(
+ QUERY,
+ vscode.CompletionItemKind.Module,
+ );
snippetCompletion.detail = "Query string query syntax";
- let snippetText = '';
+ let snippetText = "";
if (!existingKeys.includes("query")) {
snippetText += '\t"query": "$1"\n';
}
- snippetText = snippetText.replace(/,\n\}/g, '\n}');
+ snippetText = snippetText.replace(/,\n\}/g, "\n}");
snippetCompletion.insertText = new vscode.SnippetString(snippetText);
return snippetCompletion;
}
-
static getHighlightTemplate(): vscode.CompletionItem {
-
- const snippetCompletion = new vscode.CompletionItem("Highlight Options", vscode.CompletionItemKind.Module);
+ const snippetCompletion = new vscode.CompletionItem(
+ "Highlight Options",
+ vscode.CompletionItemKind.Module,
+ );
snippetCompletion.detail = "Highlight Options";
let snippetText = `"highlight": {\n\t"style": "$1",\n\t"fields": [$2]\n}`;
-
snippetCompletion.insertText = new vscode.SnippetString(snippetText);
return snippetCompletion;
}
static getEmptyTemplate(name: string, desc: string): vscode.CompletionItem {
- const emptyTemplate = new vscode.CompletionItem(name, vscode.CompletionItemKind.Module);
+ const emptyTemplate = new vscode.CompletionItem(
+ name,
+ vscode.CompletionItemKind.Module,
+ );
emptyTemplate.detail = desc;
- emptyTemplate.documentation = new vscode.MarkdownString(`Inserts an empty JSON object for \`${name}\``);
+ emptyTemplate.documentation = new vscode.MarkdownString(
+ `Inserts an empty JSON object for \`${name}\``,
+ );
let snippetText = `"${name}": {}`;
@@ -48,10 +55,18 @@ export class cbsTemplate {
return emptyTemplate;
}
- static getGeoTemplate(key: string, desc: string, type: string, existingKeys: string[]): vscode.CompletionItem {
- const geoCompletion = new vscode.CompletionItem(key, vscode.CompletionItemKind.Module);
+ static getGeoTemplate(
+ key: string,
+ desc: string,
+ type: string,
+ existingKeys: string[],
+ ): vscode.CompletionItem {
+ const geoCompletion = new vscode.CompletionItem(
+ key,
+ vscode.CompletionItemKind.Module,
+ );
geoCompletion.detail = desc;
- let snippetText = '';
+ let snippetText = "";
let cursorPosition = 1;
@@ -74,24 +89,26 @@ export class cbsTemplate {
snippetText += `, "radius": "\${${cursorPosition++}}"\n`;
}
- snippetText += '},\n';
+ snippetText += "},\n";
snippetText += `"relation": "\${${cursorPosition++}}"\n`;
- snippetText += '}';
+ snippetText += "}";
}
- snippetText = snippetText.replace(/,\n}/g, '\n}');
+ snippetText = snippetText.replace(/,\n}/g, "\n}");
geoCompletion.insertText = new vscode.SnippetString(snippetText);
return geoCompletion;
}
-
-
static getKNNTemplate(): vscode.CompletionItem {
- const snippetCompletion = new vscode.CompletionItem("knn", vscode.CompletionItemKind.Module);
+ const snippetCompletion = new vscode.CompletionItem(
+ "knn",
+ vscode.CompletionItemKind.Module,
+ );
snippetCompletion.detail = "Knn filter";
- let snippetText = '"knn": [{\n\t"k": $1,\n\t"field": "$2",\n\t"vector": [$3]\n}]';
+ let snippetText =
+ '"knn": [{\n\t"k": $1,\n\t"field": "$2",\n\t"vector": [$3]\n}]';
snippetCompletion.insertText = new vscode.SnippetString(snippetText);
@@ -99,17 +116,20 @@ export class cbsTemplate {
}
static getConjunctsTemplate(existingKeys: string[]): vscode.CompletionItem {
- const CONJUNCTS_QUERY = 'conjuncts';
- const snippetCompletion = new vscode.CompletionItem(CONJUNCTS_QUERY, vscode.CompletionItemKind.Module);
+ const CONJUNCTS_QUERY = "conjuncts";
+ const snippetCompletion = new vscode.CompletionItem(
+ CONJUNCTS_QUERY,
+ vscode.CompletionItemKind.Module,
+ );
snippetCompletion.detail = "Query conjunction";
- let snippetText = '';
+ let snippetText = "";
if (!existingKeys.includes("conjuncts")) {
snippetText += '\t"conjuncts": [\n\t\t{\n\t\t\t$1\n\t\t}\n\t]\n';
}
- snippetText = snippetText.replace(/,\n\}/g, '\n}');
+ snippetText = snippetText.replace(/,\n\}/g, "\n}");
snippetCompletion.insertText = new vscode.SnippetString(snippetText);
@@ -117,17 +137,20 @@ export class cbsTemplate {
}
static getDisjunctsTemplate(existingKeys: string[]): vscode.CompletionItem {
- const DISJUNCTS_QUERY = 'disjuncts';
- const snippetCompletion = new vscode.CompletionItem(DISJUNCTS_QUERY, vscode.CompletionItemKind.Module);
+ const DISJUNCTS_QUERY = "disjuncts";
+ const snippetCompletion = new vscode.CompletionItem(
+ DISJUNCTS_QUERY,
+ vscode.CompletionItemKind.Module,
+ );
snippetCompletion.detail = "Query disjunction";
- let snippetText = '';
+ let snippetText = "";
if (!existingKeys.includes("disjuncts")) {
snippetText += '\t"disjuncts": [\n\t\t{\n\t\t\t$1\n\t\t}\n\t]\n';
}
- snippetText = snippetText.replace(/,\n\}/g, '\n}');
+ snippetText = snippetText.replace(/,\n\}/g, "\n}");
snippetCompletion.insertText = new vscode.SnippetString(snippetText);
@@ -135,11 +158,11 @@ export class cbsTemplate {
}
static getMustTemplate(): vscode.CompletionItem {
- const snippetCompletion = new vscode.CompletionItem('must');
+ const snippetCompletion = new vscode.CompletionItem("must");
snippetCompletion.detail = "Must boolean query template";
snippetCompletion.kind = vscode.CompletionItemKind.Module;
- let snippetText = '';
+ let snippetText = "";
snippetText += '"must": {\n\t"conjuncts": [\n\t\t{$1}\n\t]\n}';
@@ -149,11 +172,11 @@ export class cbsTemplate {
}
static getShouldTemplate(): vscode.CompletionItem {
- const snippetCompletion = new vscode.CompletionItem('should');
+ const snippetCompletion = new vscode.CompletionItem("should");
snippetCompletion.detail = "Should boolean query template";
snippetCompletion.kind = vscode.CompletionItemKind.Module;
- let snippetText = '';
+ let snippetText = "";
snippetText += '"should": {\n\t"disjuncts": [\n\t\t{$1}\n\t]\n}';
snippetCompletion.insertText = new vscode.SnippetString(snippetText);
@@ -162,11 +185,11 @@ export class cbsTemplate {
}
static getMustNotTemplate(): vscode.CompletionItem {
- const snippetCompletion = new vscode.CompletionItem('must_not');
+ const snippetCompletion = new vscode.CompletionItem("must_not");
snippetCompletion.detail = "MustNot boolean query template";
snippetCompletion.kind = vscode.CompletionItemKind.Module;
- let snippetText = '';
+ let snippetText = "";
snippetText += '"must_not": {\n\t"disjuncts": [\n\t\t{$1}\n\t]\n}';
@@ -175,12 +198,16 @@ export class cbsTemplate {
return snippetCompletion;
}
- static createGenericTemplate(key: string, description: string, attributes: string[]): vscode.CompletionItem {
+ static createGenericTemplate(
+ key: string,
+ description: string,
+ attributes: string[],
+ ): vscode.CompletionItem {
const snippetCompletion = new vscode.CompletionItem(key);
snippetCompletion.detail = description;
snippetCompletion.kind = vscode.CompletionItemKind.Module;
- let snippetText = '';
+ let snippetText = "";
attributes.forEach((attr, index) => {
snippetText += `\t"${attr}": $${index + 1}`;
@@ -189,19 +216,20 @@ export class cbsTemplate {
}
});
-
snippetCompletion.insertText = new vscode.SnippetString(snippetText);
return snippetCompletion;
}
-
static getRectangleTemplate(existingKeys: string[]): vscode.CompletionItem {
- const RECTANGLE_QUERY = 'rectangle_query';
- const snippetCompletion = new vscode.CompletionItem(RECTANGLE_QUERY, vscode.CompletionItemKind.Module);
+ const RECTANGLE_QUERY = "rectangle_query";
+ const snippetCompletion = new vscode.CompletionItem(
+ RECTANGLE_QUERY,
+ vscode.CompletionItemKind.Module,
+ );
snippetCompletion.detail = "Rectangle-Based Geopoint Query";
- let snippetText = '';
+ let snippetText = "";
if (!existingKeys.includes("field")) {
snippetText += '\t"field": "$1",\n';
@@ -215,7 +243,7 @@ export class cbsTemplate {
snippetText += `\t"bottom_right": {\n\t\t"lon": "$4",\n\t\t"lat": "$5"\n\t}\n`;
}
- snippetText = snippetText.replace(/,\n}$/g, '\n}');
+ snippetText = snippetText.replace(/,\n}$/g, "\n}");
snippetCompletion.insertText = new vscode.SnippetString(snippetText);
@@ -223,11 +251,14 @@ export class cbsTemplate {
}
static getRadiusTemplate(existingKeys: string[]): vscode.CompletionItem {
- const RADIUS_QUERY = 'radius_query';
- const snippetCompletion = new vscode.CompletionItem(RADIUS_QUERY, vscode.CompletionItemKind.Module);
+ const RADIUS_QUERY = "radius_query";
+ const snippetCompletion = new vscode.CompletionItem(
+ RADIUS_QUERY,
+ vscode.CompletionItemKind.Module,
+ );
snippetCompletion.detail = "Distance/Radius-Based Geopoint Query";
- let snippetText = '';
+ let snippetText = "";
if (!existingKeys.includes("field")) {
snippetText += '\t"field": "$1",\n';
@@ -241,7 +272,7 @@ export class cbsTemplate {
snippetText += `\t"location": {\n\t\t"lon": "$3",\n\t\t"lat": "$4"\n\t}\n`;
}
- snippetText = snippetText.replace(/,\n\}/g, '\n}');
+ snippetText = snippetText.replace(/,\n\}/g, "\n}");
snippetCompletion.insertText = new vscode.SnippetString(snippetText);
@@ -249,11 +280,11 @@ export class cbsTemplate {
}
static getVectorTemplate(existingKeys: string[]): vscode.CompletionItem {
- const snippetCompletion = new vscode.CompletionItem('vector_query');
+ const snippetCompletion = new vscode.CompletionItem("vector_query");
snippetCompletion.detail = "Vector search filter";
snippetCompletion.kind = vscode.CompletionItemKind.Module;
- let snippetText = '';
+ let snippetText = "";
if (!existingKeys.includes("field")) {
snippetText += '"field": "$1",\n';
@@ -265,7 +296,7 @@ export class cbsTemplate {
snippetText += '"vector": [$3]\n';
}
- snippetText = snippetText.replace(/,\n$/, '\n');
+ snippetText = snippetText.replace(/,\n$/, "\n");
snippetCompletion.insertText = new vscode.SnippetString(snippetText);
// snippetCompletion.command = {
@@ -275,5 +306,4 @@ export class cbsTemplate {
return snippetCompletion;
}
-
-}
\ No newline at end of file
+}
diff --git a/src/commands/fts/SearchWorkbench/contributor/consistencyCbsContributor.ts b/src/commands/fts/SearchWorkbench/contributor/consistencyCbsContributor.ts
index e0eb901c..c2b1f3fb 100644
--- a/src/commands/fts/SearchWorkbench/contributor/consistencyCbsContributor.ts
+++ b/src/commands/fts/SearchWorkbench/contributor/consistencyCbsContributor.ts
@@ -1,6 +1,6 @@
-import { Node } from 'jsonc-parser'
-import { CBSContributor } from './autoComplete'
-import * as vscode from 'vscode';
+import { Node } from "jsonc-parser";
+import { CBSContributor } from "./autoComplete";
+import * as vscode from "vscode";
export class consistencyCbsContributor implements CBSContributor {
public static keys: string[] = ["vectors", "level", "results"];
@@ -9,19 +9,26 @@ export class consistencyCbsContributor implements CBSContributor {
return key === "consistency";
}
- contributeKey(parentKey: string, node: Node, suggestion: string[], result: vscode.CompletionItem[], existingKeys: string[]) {
- suggestion.push(...consistencyCbsContributor.keys)
-
+ contributeKey(
+ parentKey: string,
+ node: Node,
+ suggestion: string[],
+ result: vscode.CompletionItem[],
+ existingKeys: string[],
+ ) {
+ suggestion.push(...consistencyCbsContributor.keys);
}
- contributeValue(attributeKey: string, node: Node, suggestion: string[], fields:string[]) {
+ contributeValue(
+ attributeKey: string,
+ node: Node,
+ suggestion: string[],
+ fields: string[],
+ ) {
if (attributeKey == "level") {
- suggestion.push("at_plus", "not_bounded")
- }
- else if (attributeKey == "results") {
- suggestion.push("complete")
+ suggestion.push("at_plus", "not_bounded");
+ } else if (attributeKey == "results") {
+ suggestion.push("complete");
}
-
}
-
-}
\ No newline at end of file
+}
diff --git a/src/commands/fts/SearchWorkbench/contributor/ctlCbsContributor.ts b/src/commands/fts/SearchWorkbench/contributor/ctlCbsContributor.ts
index 6c5ae789..0dd1b731 100644
--- a/src/commands/fts/SearchWorkbench/contributor/ctlCbsContributor.ts
+++ b/src/commands/fts/SearchWorkbench/contributor/ctlCbsContributor.ts
@@ -1,6 +1,6 @@
-import { Node } from 'jsonc-parser'
-import { CBSContributor } from './autoComplete'
-import * as vscode from 'vscode';
+import { Node } from "jsonc-parser";
+import { CBSContributor } from "./autoComplete";
+import * as vscode from "vscode";
export class ctlCbsContributor implements CBSContributor {
public static keys: string[] = ["timeout", "consistency"];
@@ -9,13 +9,20 @@ export class ctlCbsContributor implements CBSContributor {
return key === "ctl";
}
- contributeKey(parentKey: string, node: Node, suggestion: string[], result: vscode.CompletionItem[], existingKeys: string[]) {
+ contributeKey(
+ parentKey: string,
+ node: Node,
+ suggestion: string[],
+ result: vscode.CompletionItem[],
+ existingKeys: string[],
+ ) {
suggestion.push(...ctlCbsContributor.keys);
-
- }
-
- contributeValue(attributeKey: string, node: Node, suggestion: string[], fields:string[]) {
-
}
-}
\ No newline at end of file
+ contributeValue(
+ attributeKey: string,
+ node: Node,
+ suggestion: string[],
+ fields: string[],
+ ) {}
+}
diff --git a/src/commands/fts/SearchWorkbench/contributor/fieldsContributor.ts b/src/commands/fts/SearchWorkbench/contributor/fieldsContributor.ts
index b8b09681..a6b25717 100644
--- a/src/commands/fts/SearchWorkbench/contributor/fieldsContributor.ts
+++ b/src/commands/fts/SearchWorkbench/contributor/fieldsContributor.ts
@@ -1,15 +1,19 @@
-import { CacheService, IBucketCache } from "../../../../util/cacheService/cacheService";
+import {
+ CacheService,
+ IBucketCache,
+} from "../../../../util/cacheService/cacheService";
import { getActiveConnection } from "../../../../util/connections";
import { CouchbaseRestAPI } from "../../../../util/apis/CouchbaseRestAPI";
import { SearchIndexParser } from "../indexParser/indexParser";
import { logger } from "../../../../logger/logger";
-
export class fieldsContributor {
-
- static async getFieldNames(bucketName: string, indexName: string): Promise {
- const cache = new CacheService()
- const suggestions: string[] = []
+ static async getFieldNames(
+ bucketName: string,
+ indexName: string,
+ ): Promise {
+ const cache = new CacheService();
+ const suggestions: string[] = [];
const connection = getActiveConnection();
if (!connection) {
return [];
@@ -20,45 +24,67 @@ export class fieldsContributor {
const bucketCache = cache.getCache(bucketName);
const result = await api.fetchSearchIndexDefinition(indexName);
if (!bucketCache) {
- return []
+ return [];
}
- const index = result?.indexDef
+ const index = result?.indexDef;
if (index) {
try {
const fields = SearchIndexParser.extractPropertiesMap(index);
- fields.set(SearchIndexParser.getDefaultField(index), '');
+ fields.set(SearchIndexParser.getDefaultField(index), "");
const isDynamic = SearchIndexParser.isIndexDynamic(index);
if (isDynamic) {
const cols = SearchIndexParser.listCollections(index);
for (const prop of cols) {
- if (!SearchIndexParser.isCollectionDynamicallyIndexed(index, prop)) {
+ if (
+ !SearchIndexParser.isCollectionDynamicallyIndexed(
+ index,
+ prop,
+ )
+ ) {
continue;
}
- if (prop.includes('.')) {
- const parts = prop.split('.');
- const additionalFields = this.extractFieldsFromCollection(bucketCache, parts[0], parts[1]);
- if (additionalFields && typeof additionalFields[0] === 'object' && additionalFields[0] !== null) {
- const entries = Object.entries(additionalFields[0] as { [key: string]: any });
+ if (prop.includes(".")) {
+ const parts = prop.split(".");
+ const additionalFields =
+ this.extractFieldsFromCollection(
+ bucketCache,
+ parts[0],
+ parts[1],
+ );
+ if (
+ additionalFields &&
+ typeof additionalFields[0] === "object" &&
+ additionalFields[0] !== null
+ ) {
+ const entries = Object.entries(
+ additionalFields[0] as {
+ [key: string]: any;
+ },
+ );
- entries.map(property => {
+ entries.map((property) => {
const key = property[0];
const value = property[1];
- if (typeof value === 'object' && value !== null && 'type' in value) {
+ if (
+ typeof value === "object" &&
+ value !== null &&
+ "type" in value
+ ) {
const type = value.type;
- if (type !== 'array') {
- if (type === 'object') {
- Object.entries(value.value).forEach(([subKey, _]) => {
+ if (type !== "array") {
+ if (type === "object") {
+ Object.entries(
+ value.value,
+ ).forEach(([subKey, _]) => {
const fullKey = `${key}.${subKey}`;
- fields.set(fullKey, '')
+ fields.set(fullKey, "");
});
-
}
- fields.set(key, value)
+ fields.set(key, value);
}
-
}
});
}
@@ -68,21 +94,25 @@ export class fieldsContributor {
suggestions.push(...fields.keys());
return suggestions;
} catch (e) {
- logger.debug(`An error occurred while trying to extract fields from index: ${indexName}` + e);
+ logger.debug(
+ `An error occurred while trying to extract fields from index: ${indexName}` +
+ e,
+ );
}
}
return [];
}
-
- static extractFieldsFromCollection(bucketCache: IBucketCache, scopeName: string, collectionName: string): any {
+ static extractFieldsFromCollection(
+ bucketCache: IBucketCache,
+ scopeName: string,
+ collectionName: string,
+ ): any {
const scope = bucketCache.scopes.get(scopeName);
if (scope) {
const collection = scope.collections.get(collectionName);
- return collection?.schema?.patterns
+ return collection?.schema?.patterns;
}
- return
+ return;
}
}
-
-
diff --git a/src/commands/fts/SearchWorkbench/contributor/geometryCbsContributor.ts b/src/commands/fts/SearchWorkbench/contributor/geometryCbsContributor.ts
index fc77fa7b..a766d8b3 100644
--- a/src/commands/fts/SearchWorkbench/contributor/geometryCbsContributor.ts
+++ b/src/commands/fts/SearchWorkbench/contributor/geometryCbsContributor.ts
@@ -1,6 +1,6 @@
-import { Node } from 'jsonc-parser'
-import { CBSContributor } from './autoComplete'
-import * as vscode from 'vscode';
+import { Node } from "jsonc-parser";
+import { CBSContributor } from "./autoComplete";
+import * as vscode from "vscode";
export class geometryCbsContributor implements CBSContributor {
public static keys: string[] = ["shape", "relation"];
@@ -9,16 +9,24 @@ export class geometryCbsContributor implements CBSContributor {
return key === "geometry";
}
- contributeKey(parentKey: string, node: Node, suggestion: string[], result: vscode.CompletionItem[], existingKeys: string[]) {
- suggestion.push(...geometryCbsContributor.keys)
-
+ contributeKey(
+ parentKey: string,
+ node: Node,
+ suggestion: string[],
+ result: vscode.CompletionItem[],
+ existingKeys: string[],
+ ) {
+ suggestion.push(...geometryCbsContributor.keys);
}
- contributeValue(attributeKey: string, node: Node, suggestion: string[], fields:string[]) {
+ contributeValue(
+ attributeKey: string,
+ node: Node,
+ suggestion: string[],
+ fields: string[],
+ ) {
if (attributeKey == "relation") {
- suggestion.push("intersects", "contains", "within")
+ suggestion.push("intersects", "contains", "within");
}
-
}
-
-}
\ No newline at end of file
+}
diff --git a/src/commands/fts/SearchWorkbench/contributor/highlightCbsContributor.ts b/src/commands/fts/SearchWorkbench/contributor/highlightCbsContributor.ts
index 8b10f23f..1b8b433e 100644
--- a/src/commands/fts/SearchWorkbench/contributor/highlightCbsContributor.ts
+++ b/src/commands/fts/SearchWorkbench/contributor/highlightCbsContributor.ts
@@ -1,6 +1,6 @@
-import { Node } from 'jsonc-parser'
-import { CBSContributor } from './autoComplete'
-import * as vscode from 'vscode';
+import { Node } from "jsonc-parser";
+import { CBSContributor } from "./autoComplete";
+import * as vscode from "vscode";
export class highlightCbsContributor implements CBSContributor {
public static keys: string[] = ["style", "fields"];
@@ -9,16 +9,19 @@ export class highlightCbsContributor implements CBSContributor {
return key === "highlight";
}
- contributeKey(parentKey: string, node: Node, suggestion: string[], result: vscode.CompletionItem[], existingKeys: string[]) {
- suggestion.push(...highlightCbsContributor.keys)
-
+ contributeKey(
+ parentKey: string,
+ node: Node,
+ suggestion: string[],
+ result: vscode.CompletionItem[],
+ existingKeys: string[],
+ ) {
+ suggestion.push(...highlightCbsContributor.keys);
}
contributeValue(attributeKey: string, node: Node, suggestion: string[]) {
if (attributeKey == "style") {
- suggestion.push("ansi", "html")
+ suggestion.push("ansi", "html");
}
-
}
-
-}
\ No newline at end of file
+}
diff --git a/src/commands/fts/SearchWorkbench/contributor/knnCbsContributor.ts b/src/commands/fts/SearchWorkbench/contributor/knnCbsContributor.ts
index 1de87c96..b0a7186a 100644
--- a/src/commands/fts/SearchWorkbench/contributor/knnCbsContributor.ts
+++ b/src/commands/fts/SearchWorkbench/contributor/knnCbsContributor.ts
@@ -1,7 +1,7 @@
-import { Node } from 'jsonc-parser'
-import { CBSContributor } from './autoComplete'
-import * as vscode from 'vscode';
-import { cbsTemplate } from './cbsTemplates';
+import { Node } from "jsonc-parser";
+import { CBSContributor } from "./autoComplete";
+import * as vscode from "vscode";
+import { cbsTemplate } from "./cbsTemplates";
export class knnCbsContributor implements CBSContributor {
public static keys: string[] = ["k", "field", "vector", "boost"];
@@ -10,17 +10,25 @@ export class knnCbsContributor implements CBSContributor {
return key === "knn";
}
- contributeKey(parentKey: string, node: Node, suggestion: string[], result: vscode.CompletionItem[], existingKeys: string[] ) {
- suggestion.push(...knnCbsContributor.keys)
- result.push(cbsTemplate.getVectorTemplate(existingKeys))
-
+ contributeKey(
+ parentKey: string,
+ node: Node,
+ suggestion: string[],
+ result: vscode.CompletionItem[],
+ existingKeys: string[],
+ ) {
+ suggestion.push(...knnCbsContributor.keys);
+ result.push(cbsTemplate.getVectorTemplate(existingKeys));
}
- contributeValue(attributeKey: string, node: Node, suggestion: string[], fields:string[]) {
+ contributeValue(
+ attributeKey: string,
+ node: Node,
+ suggestion: string[],
+ fields: string[],
+ ) {
if (attributeKey == "field") {
suggestion.push(...fields);
}
-
}
-
-}
\ No newline at end of file
+}
diff --git a/src/commands/fts/SearchWorkbench/contributor/locationCbsContributor.ts b/src/commands/fts/SearchWorkbench/contributor/locationCbsContributor.ts
index e4f650bc..a5db543b 100644
--- a/src/commands/fts/SearchWorkbench/contributor/locationCbsContributor.ts
+++ b/src/commands/fts/SearchWorkbench/contributor/locationCbsContributor.ts
@@ -1,21 +1,30 @@
-import { Node } from 'jsonc-parser'
-import { CBSContributor } from './autoComplete'
-import * as vscode from 'vscode';
+import { Node } from "jsonc-parser";
+import { CBSContributor } from "./autoComplete";
+import * as vscode from "vscode";
export class locationCbsContributor implements CBSContributor {
public static keys: string[] = ["lat", "lon"];
accept(key: string | null): boolean {
- return key === "location" || key === "top_left" || key === "bottom_right";
+ return (
+ key === "location" || key === "top_left" || key === "bottom_right"
+ );
}
- contributeKey(parentKey: string, node: Node, suggestion: string[], result: vscode.CompletionItem[], existingKeys: string[]) {
- suggestion.push(...locationCbsContributor.keys)
-
- }
-
- contributeValue(attributeKey: string, node: Node, suggestion: string[], fields: string[]) {
-
+ contributeKey(
+ parentKey: string,
+ node: Node,
+ suggestion: string[],
+ result: vscode.CompletionItem[],
+ existingKeys: string[],
+ ) {
+ suggestion.push(...locationCbsContributor.keys);
}
-}
\ No newline at end of file
+ contributeValue(
+ attributeKey: string,
+ node: Node,
+ suggestion: string[],
+ fields: string[],
+ ) {}
+}
diff --git a/src/commands/fts/SearchWorkbench/contributor/queryCbsContributor.ts b/src/commands/fts/SearchWorkbench/contributor/queryCbsContributor.ts
index e70e1a2e..f3d8e7a7 100644
--- a/src/commands/fts/SearchWorkbench/contributor/queryCbsContributor.ts
+++ b/src/commands/fts/SearchWorkbench/contributor/queryCbsContributor.ts
@@ -3,16 +3,31 @@ import { CompletionItem } from "vscode";
import { CBSContributor } from "./autoComplete";
import { cbsTemplate } from "./cbsTemplates";
import { cbsTemplateDef } from "./cbsTemplateDef";
-import * as vscode from 'vscode';
+import * as vscode from "vscode";
export class queryCbsContributor implements CBSContributor {
-
public static allQueryKeys: Set = new Set();
private boolQueries = ["must", "must_not", "should"];
private compound = ["disjuncts", "conjuncts"];
private query = ["boost", "conjuncts"];
- private match = ["match", "analyzer", "operator", "boost", "fuzziness", "prefix_length", "field"];
- private matchPhrase = ["match_phrase", "analyzer", "operator", "boost", "fuzziness", "prefix_length", "field"];
+ private match = [
+ "match",
+ "analyzer",
+ "operator",
+ "boost",
+ "fuzziness",
+ "prefix_length",
+ "field",
+ ];
+ private matchPhrase = [
+ "match_phrase",
+ "analyzer",
+ "operator",
+ "boost",
+ "fuzziness",
+ "prefix_length",
+ "field",
+ ];
private bool = ["bool", "boost", "field"];
private prefix = ["prefix", "boost", "field"];
private regexp = ["regexp", "boost", "field"];
@@ -21,21 +36,34 @@ export class queryCbsContributor implements CBSContributor {
private wildcard = ["wildcard", "boost", "field"];
private term = ["term", "boost", "field", "fuzziness"];
private polygon = ["polygon_points", "boost", "field"];
- private numeric = ["min", "max", "inclusive_min", "inclusive_max", "field", "boost"];
- private date = ["start", "end", "inclusive_start", "inclusive_end", "field", "boost"];
+ private numeric = [
+ "min",
+ "max",
+ "inclusive_min",
+ "inclusive_max",
+ "field",
+ "boost",
+ ];
+ private date = [
+ "start",
+ "end",
+ "inclusive_start",
+ "inclusive_end",
+ "field",
+ "boost",
+ ];
private radius = ["location", "distance", "field", "boost"];
private rectangle = ["top_left", "bottom_right", "field", "boost"];
private geometry = ["geometry", "field", "boost"];
private special = ["match_all", "match_none"];
-
constructor() {
this.addAllKeys();
}
private addAllKeys(): void {
-
- ["query",
+ [
+ "query",
...this.boolQueries,
...this.compound,
...this.query,
@@ -54,28 +82,40 @@ export class queryCbsContributor implements CBSContributor {
...this.radius,
...this.rectangle,
...this.geometry,
- ...this.special].forEach(key => {
- queryCbsContributor.allQueryKeys.add(key);
- });
+ ...this.special,
+ ].forEach((key) => {
+ queryCbsContributor.allQueryKeys.add(key);
+ });
}
accept(key: string | null): boolean {
return key === "query" || key === "disjuncts" || key === "conjuncts";
}
- contributeKey(parentKey: string | null, node: Node, suggestion: string[], result: CompletionItem[], existingKeys: string[]) {
-
+ contributeKey(
+ parentKey: string | null,
+ node: Node,
+ suggestion: string[],
+ result: CompletionItem[],
+ existingKeys: string[],
+ ) {
if (existingKeys.length === 0) {
- queryCbsContributor.allQueryKeys.forEach(key => suggestion.push(key));
+ queryCbsContributor.allQueryKeys.forEach((key) =>
+ suggestion.push(key),
+ );
}
- if (this.boolQueries.some(query => existingKeys.includes(query))) {
- this.boolQueries.filter(query => !existingKeys.includes(query)).forEach(query => {
- suggestion.push(query);
- });
+ if (this.boolQueries.some((query) => existingKeys.includes(query))) {
+ this.boolQueries
+ .filter((query) => !existingKeys.includes(query))
+ .forEach((query) => {
+ suggestion.push(query);
+ });
this.addBooleanTemplates(existingKeys, result);
- } else if (!existingKeys.includes("query") && !this.compound.some(comp => existingKeys.includes(comp))) {
-
+ } else if (
+ !existingKeys.includes("query") &&
+ !this.compound.some((comp) => existingKeys.includes(comp))
+ ) {
if (!existingKeys.includes("field")) {
suggestion.push("field");
}
@@ -86,148 +126,423 @@ export class queryCbsContributor implements CBSContributor {
this.addBooleanTemplates(existingKeys, result);
result.push(cbsTemplate.getConjunctsTemplate(existingKeys));
result.push(cbsTemplate.getDisjunctsTemplate(existingKeys));
- result.push(cbsTemplate.getEmptyTemplate("match_all", "match_all template"))
- result.push(cbsTemplate.getEmptyTemplate("match_none", "match_all template"))
+ result.push(
+ cbsTemplate.getEmptyTemplate(
+ "match_all",
+ "match_all template",
+ ),
+ );
+ result.push(
+ cbsTemplate.getEmptyTemplate(
+ "match_none",
+ "match_all template",
+ ),
+ );
}
- const boolContributors = this.getBoolContributors(existingKeys, result);
- const cidrContributors = this.getCidrContributors(existingKeys, result);
- const prefixContributors = this.getPrefixContributors(existingKeys, result)
- const regexexpContributors = this.getRegexpContributors(existingKeys, result)
- const termContributors = this.getTermContributors(existingKeys, result)
- const termsContributors = this.getTermsContributors(existingKeys, result)
- const rectangleContributors = this.getRectangleContributors(existingKeys, result)
- const polygonContributors = this.getPolygonContributors(existingKeys, result)
- const radiusContributors = this.getRadiusContributors(existingKeys, result)
- const wildCardContributors = this.getWildCardContributors(existingKeys, result)
- const numericContributors = this.getNumericContributors(existingKeys, result)
- const dateContributors = this.getDateContributors(existingKeys, result)
- const matchQuery = this.getMatchContributors(existingKeys, result)
- const matchPhraseQuery = this.getMatchPhraseContributors(existingKeys, result)
- this.addGeometryContributors(existingKeys, result)
- const allContributors = [...boolContributors, ...cidrContributors, ...prefixContributors, ...regexexpContributors, ...termContributors, ...termsContributors, ...rectangleContributors, ...polygonContributors, ...radiusContributors, ...wildCardContributors, ...numericContributors, ...dateContributors, ...matchQuery, ...matchPhraseQuery];
-
- allContributors.forEach(contributor => {
+ const boolContributors = this.getBoolContributors(
+ existingKeys,
+ result,
+ );
+ const cidrContributors = this.getCidrContributors(
+ existingKeys,
+ result,
+ );
+ const prefixContributors = this.getPrefixContributors(
+ existingKeys,
+ result,
+ );
+ const regexexpContributors = this.getRegexpContributors(
+ existingKeys,
+ result,
+ );
+ const termContributors = this.getTermContributors(
+ existingKeys,
+ result,
+ );
+ const termsContributors = this.getTermsContributors(
+ existingKeys,
+ result,
+ );
+ const rectangleContributors = this.getRectangleContributors(
+ existingKeys,
+ result,
+ );
+ const polygonContributors = this.getPolygonContributors(
+ existingKeys,
+ result,
+ );
+ const radiusContributors = this.getRadiusContributors(
+ existingKeys,
+ result,
+ );
+ const wildCardContributors = this.getWildCardContributors(
+ existingKeys,
+ result,
+ );
+ const numericContributors = this.getNumericContributors(
+ existingKeys,
+ result,
+ );
+ const dateContributors = this.getDateContributors(
+ existingKeys,
+ result,
+ );
+ const matchQuery = this.getMatchContributors(existingKeys, result);
+ const matchPhraseQuery = this.getMatchPhraseContributors(
+ existingKeys,
+ result,
+ );
+ this.addGeometryContributors(existingKeys, result);
+ const allContributors = [
+ ...boolContributors,
+ ...cidrContributors,
+ ...prefixContributors,
+ ...regexexpContributors,
+ ...termContributors,
+ ...termsContributors,
+ ...rectangleContributors,
+ ...polygonContributors,
+ ...radiusContributors,
+ ...wildCardContributors,
+ ...numericContributors,
+ ...dateContributors,
+ ...matchQuery,
+ ...matchPhraseQuery,
+ ];
+
+ allContributors.forEach((contributor) => {
if (!suggestion.includes(contributor)) {
suggestion.push(contributor);
}
});
-
-
}
}
addBooleanTemplates(existingKeys: string[], result: CompletionItem[]) {
if (!existingKeys.includes("must")) {
- result.push(cbsTemplate.getMustTemplate())
+ result.push(cbsTemplate.getMustTemplate());
}
if (!existingKeys.includes("must_not")) {
- result.push(cbsTemplate.getMustNotTemplate())
+ result.push(cbsTemplate.getMustNotTemplate());
}
if (!existingKeys.includes("should")) {
- result.push(cbsTemplate.getShouldTemplate())
+ result.push(cbsTemplate.getShouldTemplate());
}
-
}
addGeometryContributors(existingKeys: string[], result: CompletionItem[]) {
- if (existingKeys.every(key => this.geometry.includes(key))) {
- result.push(cbsTemplate.getGeoTemplate("point_geo_query", "Point GeoJSON Query", "Point", existingKeys))
- result.push(cbsTemplate.getGeoTemplate("linestring_geo_query", "LineString GeoJSON Query", "Point", existingKeys))
- result.push(cbsTemplate.getGeoTemplate("polygon_geo_query", "Polygon GeoJSON Query", "Polygon", existingKeys))
- result.push(cbsTemplate.getGeoTemplate("multi_point_geo_query", "MultiPoint GeoJSON Query", "MultiPoint", existingKeys))
- result.push(cbsTemplate.getGeoTemplate("multi_linestring_geo_query", "MultiLineString GeoJSON Query", "MultiLineString", existingKeys))
- result.push(cbsTemplate.getGeoTemplate("multi_polygon_geo_query", "MultiPolygon GeoJSON Query", "MultiPolygon", existingKeys))
- result.push(cbsTemplate.getGeoTemplate("envelope_geo_query", "Envelope GeoJSON Query", "Envelope", existingKeys))
- result.push(cbsTemplate.getGeoTemplate("circle_geo_query", "Circle GeoJSON Query", "Circle", existingKeys))
- result.push(cbsTemplate.getGeoTemplate("geometry_col_geo_query", "Geometry Collection GeoJSON Query", "GeometryCollection", existingKeys))
+ if (existingKeys.every((key) => this.geometry.includes(key))) {
+ result.push(
+ cbsTemplate.getGeoTemplate(
+ "point_geo_query",
+ "Point GeoJSON Query",
+ "Point",
+ existingKeys,
+ ),
+ );
+ result.push(
+ cbsTemplate.getGeoTemplate(
+ "linestring_geo_query",
+ "LineString GeoJSON Query",
+ "Point",
+ existingKeys,
+ ),
+ );
+ result.push(
+ cbsTemplate.getGeoTemplate(
+ "polygon_geo_query",
+ "Polygon GeoJSON Query",
+ "Polygon",
+ existingKeys,
+ ),
+ );
+ result.push(
+ cbsTemplate.getGeoTemplate(
+ "multi_point_geo_query",
+ "MultiPoint GeoJSON Query",
+ "MultiPoint",
+ existingKeys,
+ ),
+ );
+ result.push(
+ cbsTemplate.getGeoTemplate(
+ "multi_linestring_geo_query",
+ "MultiLineString GeoJSON Query",
+ "MultiLineString",
+ existingKeys,
+ ),
+ );
+ result.push(
+ cbsTemplate.getGeoTemplate(
+ "multi_polygon_geo_query",
+ "MultiPolygon GeoJSON Query",
+ "MultiPolygon",
+ existingKeys,
+ ),
+ );
+ result.push(
+ cbsTemplate.getGeoTemplate(
+ "envelope_geo_query",
+ "Envelope GeoJSON Query",
+ "Envelope",
+ existingKeys,
+ ),
+ );
+ result.push(
+ cbsTemplate.getGeoTemplate(
+ "circle_geo_query",
+ "Circle GeoJSON Query",
+ "Circle",
+ existingKeys,
+ ),
+ );
+ result.push(
+ cbsTemplate.getGeoTemplate(
+ "geometry_col_geo_query",
+ "Geometry Collection GeoJSON Query",
+ "GeometryCollection",
+ existingKeys,
+ ),
+ );
}
}
- getPolygonContributors(existingKeys: string[], result: CompletionItem[]): string[] {
- const template = this.getSingleTemplate("polygon_points_query", "Polygon Based Geopoint queries", this.polygon);
- return this.genericContributor(this.polygon, existingKeys, result, [template]);
+ getPolygonContributors(
+ existingKeys: string[],
+ result: CompletionItem[],
+ ): string[] {
+ const template = this.getSingleTemplate(
+ "polygon_points_query",
+ "Polygon Based Geopoint queries",
+ this.polygon,
+ );
+ return this.genericContributor(this.polygon, existingKeys, result, [
+ template,
+ ]);
}
- getRectangleContributors(existingKeys: string[], result: CompletionItem[]): string[] {
- if (existingKeys.every(key => this.rectangle.includes(key))) {
- result.push(cbsTemplate.getRectangleTemplate(existingKeys))
+ getRectangleContributors(
+ existingKeys: string[],
+ result: CompletionItem[],
+ ): string[] {
+ if (existingKeys.every((key) => this.rectangle.includes(key))) {
+ result.push(cbsTemplate.getRectangleTemplate(existingKeys));
}
- return this.genericContributor(this.rectangle, existingKeys, result, [])
+ return this.genericContributor(
+ this.rectangle,
+ existingKeys,
+ result,
+ [],
+ );
}
- getRadiusContributors(existingKeys: string[], result: CompletionItem[]): string[] {
- if (existingKeys.every(key => this.radius.includes(key))) {
- result.push(cbsTemplate.getRadiusTemplate(existingKeys))
+ getRadiusContributors(
+ existingKeys: string[],
+ result: CompletionItem[],
+ ): string[] {
+ if (existingKeys.every((key) => this.radius.includes(key))) {
+ result.push(cbsTemplate.getRadiusTemplate(existingKeys));
}
- return this.genericContributor(this.radius, existingKeys, result, [])
+ return this.genericContributor(this.radius, existingKeys, result, []);
}
- getBoolContributors(existingKeys: string[], result: CompletionItem[]): string[] {
- const template = this.getSingleTemplate("bool_query", "Boolean query", this.bool);
- return this.genericContributor(this.bool, existingKeys, result, [template]);
+ getBoolContributors(
+ existingKeys: string[],
+ result: CompletionItem[],
+ ): string[] {
+ const template = this.getSingleTemplate(
+ "bool_query",
+ "Boolean query",
+ this.bool,
+ );
+ return this.genericContributor(this.bool, existingKeys, result, [
+ template,
+ ]);
}
- getCidrContributors(existingKeys: string[], result: CompletionItem[]): string[] {
- const template = this.getSingleTemplate("cidr_query", "CIDR query", this.cidr);
- return this.genericContributor(this.cidr, existingKeys, result, [template]);
+ getCidrContributors(
+ existingKeys: string[],
+ result: CompletionItem[],
+ ): string[] {
+ const template = this.getSingleTemplate(
+ "cidr_query",
+ "CIDR query",
+ this.cidr,
+ );
+ return this.genericContributor(this.cidr, existingKeys, result, [
+ template,
+ ]);
}
-
- getPrefixContributors(existingKeys: string[], result: CompletionItem[]): string[] {
- const template = this.getSingleTemplate("prefix_query", "Prefix query", this.prefix);
- return this.genericContributor(this.prefix, existingKeys, result, [template]);
+ getPrefixContributors(
+ existingKeys: string[],
+ result: CompletionItem[],
+ ): string[] {
+ const template = this.getSingleTemplate(
+ "prefix_query",
+ "Prefix query",
+ this.prefix,
+ );
+ return this.genericContributor(this.prefix, existingKeys, result, [
+ template,
+ ]);
}
- getRegexpContributors(existingKeys: string[], result: CompletionItem[]): string[] {
- const template = this.getSingleTemplate("regex_query", "Regex query", this.regexp);
- return this.genericContributor(this.regexp, existingKeys, result, [template]);
+ getRegexpContributors(
+ existingKeys: string[],
+ result: CompletionItem[],
+ ): string[] {
+ const template = this.getSingleTemplate(
+ "regex_query",
+ "Regex query",
+ this.regexp,
+ );
+ return this.genericContributor(this.regexp, existingKeys, result, [
+ template,
+ ]);
}
- getTermContributors(existingKeys: string[], result: CompletionItem[]): string[] {
- const template = this.getSingleTemplate("term_query", "Term query", this.term);
- return this.genericContributor(this.term, existingKeys, result, [template]);
+ getTermContributors(
+ existingKeys: string[],
+ result: CompletionItem[],
+ ): string[] {
+ const template = this.getSingleTemplate(
+ "term_query",
+ "Term query",
+ this.term,
+ );
+ return this.genericContributor(this.term, existingKeys, result, [
+ template,
+ ]);
}
- getTermsContributors(existingKeys: string[], result: CompletionItem[]): string[] {
- const template = this.getSingleTemplate("terms_query", "Terms query", this.terms);
- return this.genericContributor(this.terms, existingKeys, result, [template]);
+ getTermsContributors(
+ existingKeys: string[],
+ result: CompletionItem[],
+ ): string[] {
+ const template = this.getSingleTemplate(
+ "terms_query",
+ "Terms query",
+ this.terms,
+ );
+ return this.genericContributor(this.terms, existingKeys, result, [
+ template,
+ ]);
}
- getWildCardContributors(existingKeys: string[], result: CompletionItem[]): string[] {
- const template = this.getSingleTemplate("wildcard_query", "Wildcard query", this.wildcard);
- return this.genericContributor(this.wildcard, existingKeys, result, [template]);
+ getWildCardContributors(
+ existingKeys: string[],
+ result: CompletionItem[],
+ ): string[] {
+ const template = this.getSingleTemplate(
+ "wildcard_query",
+ "Wildcard query",
+ this.wildcard,
+ );
+ return this.genericContributor(this.wildcard, existingKeys, result, [
+ template,
+ ]);
}
- getNumericContributors(existingKeys: string[], result: CompletionItem[]): string[] {
- const numericRangeTemplate = this.getSingleTemplate("numeric_range", "Simple numeric range search", ["field", "min", "max"]);
- const numericRangeAllTemplate = this.getSingleTemplate("numeric_range_all", "Data numeric search with all attributes", this.numeric)
- return this.genericContributor(this.numeric, existingKeys, result, [numericRangeTemplate, numericRangeAllTemplate]);
+ getNumericContributors(
+ existingKeys: string[],
+ result: CompletionItem[],
+ ): string[] {
+ const numericRangeTemplate = this.getSingleTemplate(
+ "numeric_range",
+ "Simple numeric range search",
+ ["field", "min", "max"],
+ );
+ const numericRangeAllTemplate = this.getSingleTemplate(
+ "numeric_range_all",
+ "Data numeric search with all attributes",
+ this.numeric,
+ );
+ return this.genericContributor(this.numeric, existingKeys, result, [
+ numericRangeTemplate,
+ numericRangeAllTemplate,
+ ]);
}
- getDateContributors(existingKeys: string[], result: CompletionItem[]): string[] {
- const dateRangeTemplate = this.getSingleTemplate("date_range", "Simple data range search", ["field", "start", "end"]);
- const dateRangeAllTemplate = this.getSingleTemplate("date_range_all", "Data range search with all attributes", this.date)
- return this.genericContributor(this.date, existingKeys, result, [dateRangeTemplate, dateRangeAllTemplate]);
+ getDateContributors(
+ existingKeys: string[],
+ result: CompletionItem[],
+ ): string[] {
+ const dateRangeTemplate = this.getSingleTemplate(
+ "date_range",
+ "Simple data range search",
+ ["field", "start", "end"],
+ );
+ const dateRangeAllTemplate = this.getSingleTemplate(
+ "date_range_all",
+ "Data range search with all attributes",
+ this.date,
+ );
+ return this.genericContributor(this.date, existingKeys, result, [
+ dateRangeTemplate,
+ dateRangeAllTemplate,
+ ]);
}
- getMatchContributors(existingKeys: string[], result: CompletionItem[]): string[] {
- const matchQueryTemplate = this.getSingleTemplate("match_query", "Simple match query search", ["field", "match"]);
- const matchQueryAllTemplate = this.getSingleTemplate("match_query_all", "Match query search with all attributes", this.match)
- return this.genericContributor(this.match, existingKeys, result, [matchQueryTemplate, matchQueryAllTemplate]);
+ getMatchContributors(
+ existingKeys: string[],
+ result: CompletionItem[],
+ ): string[] {
+ const matchQueryTemplate = this.getSingleTemplate(
+ "match_query",
+ "Simple match query search",
+ ["field", "match"],
+ );
+ const matchQueryAllTemplate = this.getSingleTemplate(
+ "match_query_all",
+ "Match query search with all attributes",
+ this.match,
+ );
+ return this.genericContributor(this.match, existingKeys, result, [
+ matchQueryTemplate,
+ matchQueryAllTemplate,
+ ]);
}
- getMatchPhraseContributors(existingKeys: string[], result: CompletionItem[]): string[] {
- const matchPhraseQueryTemplate = this.getSingleTemplate("match_phrase_query", "Simple match phrase query search", ["field", "match_phrase"]);
- const matchPhraseQueryAllTemplate = this.getSingleTemplate("match_phrase_query_all", "Match phrase query search with all attributes", this.matchPhrase)
- return this.genericContributor(this.matchPhrase, existingKeys, result, [matchPhraseQueryTemplate, matchPhraseQueryAllTemplate]);
+ getMatchPhraseContributors(
+ existingKeys: string[],
+ result: CompletionItem[],
+ ): string[] {
+ const matchPhraseQueryTemplate = this.getSingleTemplate(
+ "match_phrase_query",
+ "Simple match phrase query search",
+ ["field", "match_phrase"],
+ );
+ const matchPhraseQueryAllTemplate = this.getSingleTemplate(
+ "match_phrase_query_all",
+ "Match phrase query search with all attributes",
+ this.matchPhrase,
+ );
+ return this.genericContributor(this.matchPhrase, existingKeys, result, [
+ matchPhraseQueryTemplate,
+ matchPhraseQueryAllTemplate,
+ ]);
}
- genericContributor(keys: string[], existingKeys: string[], result: vscode.CompletionItem[], templateDefs: cbsTemplateDef[]): string[] {
- if (existingKeys.every(key => keys.includes(key))) {
- templateDefs.forEach(def => {
- def.attrs = def.attrs.filter(attr => !existingKeys.includes(attr) && attr !== 'boost');
- result.push(cbsTemplate.createGenericTemplate(def.key, def.desc, def.attrs))
+ genericContributor(
+ keys: string[],
+ existingKeys: string[],
+ result: vscode.CompletionItem[],
+ templateDefs: cbsTemplateDef[],
+ ): string[] {
+ if (existingKeys.every((key) => keys.includes(key))) {
+ templateDefs.forEach((def) => {
+ def.attrs = def.attrs.filter(
+ (attr) => !existingKeys.includes(attr) && attr !== "boost",
+ );
+ result.push(
+ cbsTemplate.createGenericTemplate(
+ def.key,
+ def.desc,
+ def.attrs,
+ ),
+ );
});
return keys;
} else {
@@ -235,19 +550,24 @@ export class queryCbsContributor implements CBSContributor {
}
}
- private getSingleTemplate(key: string, desc: string, fields: string[]): cbsTemplateDef {
+ private getSingleTemplate(
+ key: string,
+ desc: string,
+ fields: string[],
+ ): cbsTemplateDef {
return new cbsTemplateDef(key, desc, fields);
}
- contributeValue(attributeKey: string | null, node: Node, suggestion: string[], fields: string[]) {
-
+ contributeValue(
+ attributeKey: string | null,
+ node: Node,
+ suggestion: string[],
+ fields: string[],
+ ) {
if (attributeKey == "operator") {
suggestion.push("or", "and");
- }
- else if (attributeKey == "field") {
+ } else if (attributeKey == "field") {
suggestion.push(...fields);
}
-
}
-
-}
\ No newline at end of file
+}
diff --git a/src/commands/fts/SearchWorkbench/contributor/shapeCbsContributor.ts b/src/commands/fts/SearchWorkbench/contributor/shapeCbsContributor.ts
index 52b2615d..575b8c0e 100644
--- a/src/commands/fts/SearchWorkbench/contributor/shapeCbsContributor.ts
+++ b/src/commands/fts/SearchWorkbench/contributor/shapeCbsContributor.ts
@@ -3,74 +3,82 @@ import { CompletionItem } from "vscode";
import { CBSContributor } from "./autoComplete";
export class shapeCbsContributor implements CBSContributor {
-
- accept(key: string | null): boolean {
- return key === "shape"
- }
-
- contributeKey(parentKey: string | null, node: Node, suggestion: string[], result: CompletionItem[], existingKeys: string[]) {
- let type: string = "";
- if (node.type === 'string') {
- if (node.parent && node.parent.parent) {
- node = node.parent.parent
- }
+ accept(key: string | null): boolean {
+ return key === "shape";
}
- if (!node.children) {
- return
- }
- for (const propertyNode of node.children) {
- if (propertyNode.type === 'property' && propertyNode.children) {
- let keyNode = null;
- let valueNode = null;
-
- for (const childNode of propertyNode.children) {
- if (childNode.type === 'string' && childNode.value === 'type') {
- keyNode = childNode;
- } else if (childNode.type === 'string') {
- valueNode = childNode;
- }
- if (keyNode && valueNode) {
- type = valueNode.value;
- }
+ contributeKey(
+ parentKey: string | null,
+ node: Node,
+ suggestion: string[],
+ result: CompletionItem[],
+ existingKeys: string[],
+ ) {
+ let type: string = "";
+ if (node.type === "string") {
+ if (node.parent && node.parent.parent) {
+ node = node.parent.parent;
+ }
}
- }
- }
-
- if (type === "Circle") {
- suggestion.push("coordinates")
- suggestion.push("type")
- suggestion.push("radius")
- } else if (type === "GeometryCollection") {
- suggestion.push("type")
- suggestion.push("geometries")
- } else if (type === "") {
- suggestion.push("coordinates")
- suggestion.push("type")
- suggestion.push("radius")
- suggestion.push("geometries")
- } else {
- suggestion.push("coordinates")
- suggestion.push("type")
- }
+ if (!node.children) {
+ return;
+ }
+ for (const propertyNode of node.children) {
+ if (propertyNode.type === "property" && propertyNode.children) {
+ let keyNode = null;
+ let valueNode = null;
+ for (const childNode of propertyNode.children) {
+ if (
+ childNode.type === "string" &&
+ childNode.value === "type"
+ ) {
+ keyNode = childNode;
+ } else if (childNode.type === "string") {
+ valueNode = childNode;
+ }
- }
+ if (keyNode && valueNode) {
+ type = valueNode.value;
+ }
+ }
+ }
+ }
- contributeValue(attributeKey: string | null, node: Node, suggestion: string[], fields: string[]) {
- if (attributeKey === "type") {
- suggestion.push("Point");
- suggestion.push("LineString");
- suggestion.push("Polygon");
- suggestion.push("MultiPoint");
- suggestion.push("MultiLineString");
- suggestion.push("MultiPolygon");
- suggestion.push("GeometryCollection");
- suggestion.push("Circle");
- suggestion.push("Envelope");
+ if (type === "Circle") {
+ suggestion.push("coordinates");
+ suggestion.push("type");
+ suggestion.push("radius");
+ } else if (type === "GeometryCollection") {
+ suggestion.push("type");
+ suggestion.push("geometries");
+ } else if (type === "") {
+ suggestion.push("coordinates");
+ suggestion.push("type");
+ suggestion.push("radius");
+ suggestion.push("geometries");
+ } else {
+ suggestion.push("coordinates");
+ suggestion.push("type");
+ }
}
- }
-
-
-}
\ No newline at end of file
+ contributeValue(
+ attributeKey: string | null,
+ node: Node,
+ suggestion: string[],
+ fields: string[],
+ ) {
+ if (attributeKey === "type") {
+ suggestion.push("Point");
+ suggestion.push("LineString");
+ suggestion.push("Polygon");
+ suggestion.push("MultiPoint");
+ suggestion.push("MultiLineString");
+ suggestion.push("MultiPolygon");
+ suggestion.push("GeometryCollection");
+ suggestion.push("Circle");
+ suggestion.push("Envelope");
+ }
+ }
+}
diff --git a/src/commands/fts/SearchWorkbench/controller.ts b/src/commands/fts/SearchWorkbench/controller.ts
index 5f6d48a2..91298f80 100644
--- a/src/commands/fts/SearchWorkbench/controller.ts
+++ b/src/commands/fts/SearchWorkbench/controller.ts
@@ -13,33 +13,39 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import * as vscode from 'vscode';
-import { MemFS } from '../../../util/fileSystemProvider';
-import SearchIndexNode from '../../../model/SearchIndexNode';
+import * as vscode from "vscode";
+import { MemFS } from "../../../util/fileSystemProvider";
+import SearchIndexNode from "../../../model/SearchIndexNode";
-class SearchJsonDocumentContentProvider implements vscode.TextDocumentContentProvider {
+class SearchJsonDocumentContentProvider
+ implements vscode.TextDocumentContentProvider
+{
provideTextDocumentContent(uri: vscode.Uri): string {
- return '';
+ return "";
}
}
export default class UntitledSearchJsonDocumentService {
public searchJsonProvider = new SearchJsonDocumentContentProvider();
private untitledCount: number = 1;
- private searchJsonScheme: string = '.cbs.json';
+ private searchJsonScheme: string = ".cbs.json";
- public disposable = vscode.workspace.registerTextDocumentContentProvider(this.searchJsonScheme, this.searchJsonProvider);
-
- constructor() {
- }
+ public disposable = vscode.workspace.registerTextDocumentContentProvider(
+ this.searchJsonScheme,
+ this.searchJsonProvider,
+ );
+ constructor() {}
-
- public async openSearchJsonTextDocument(searchIndexNode: SearchIndexNode, memFs: MemFS): Promise {
- const uri = vscode.Uri.parse(`couchbase:/search-workbench-${searchIndexNode.indexName}-${this.untitledCount}.cbs.json`);
+ public async openSearchJsonTextDocument(
+ searchIndexNode: SearchIndexNode,
+ memFs: MemFS,
+ ): Promise {
+ const uri = vscode.Uri.parse(
+ `couchbase:/search-workbench-${searchIndexNode.indexName}-${this.untitledCount}.cbs.json`,
+ );
this.untitledCount++;
- const defaultJsonContent =
-`{
+ const defaultJsonContent = `{
"query": {
"query": "your_query_here"
},
@@ -53,22 +59,30 @@ export default class UntitledSearchJsonDocumentService {
overwrite: true,
});
-
const document = await vscode.workspace.openTextDocument(uri);
document.save();
await vscode.window.showTextDocument(document, { preview: false });
- return await vscode.window.showTextDocument(document, { preview: false });
+ return await vscode.window.showTextDocument(document, {
+ preview: false,
+ });
}
-
- public showTextDocument(document: vscode.TextDocument, column?: vscode.ViewColumn, preserveFocus?: boolean): Thenable {
+ public showTextDocument(
+ document: vscode.TextDocument,
+ column?: vscode.ViewColumn,
+ preserveFocus?: boolean,
+ ): Thenable {
return vscode.window.showTextDocument(document, column, preserveFocus);
}
-
- public newQuery(searchIndexNode: SearchIndexNode, memFs: MemFS): Promise {
+ public newQuery(
+ searchIndexNode: SearchIndexNode,
+ memFs: MemFS,
+ ): Promise {
return new Promise((resolve, reject) => {
- this.openSearchJsonTextDocument(searchIndexNode, memFs).then(resolve).catch(reject);
+ this.openSearchJsonTextDocument(searchIndexNode, memFs)
+ .then(resolve)
+ .catch(reject);
});
}
-}
\ No newline at end of file
+}
diff --git a/src/commands/fts/SearchWorkbench/documentation/documentationProvider.ts b/src/commands/fts/SearchWorkbench/documentation/documentationProvider.ts
index c1db1a33..f5f4c36a 100644
--- a/src/commands/fts/SearchWorkbench/documentation/documentationProvider.ts
+++ b/src/commands/fts/SearchWorkbench/documentation/documentationProvider.ts
@@ -1,10 +1,8 @@
-import * as vscode from 'vscode';
-import * as jsonc from 'jsonc-parser';
-import * as fs from 'fs';
-import * as path from 'path';
-import { logger } from '../../../../logger/logger';
-
-
+import * as vscode from "vscode";
+import * as jsonc from "jsonc-parser";
+import * as fs from "fs";
+import * as path from "path";
+import { logger } from "../../../../logger/logger";
export class CbsJsonHoverProvider implements vscode.HoverProvider {
private context: vscode.ExtensionContext;
@@ -13,7 +11,11 @@ export class CbsJsonHoverProvider implements vscode.HoverProvider {
this.context = context;
}
- provideHover(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): vscode.ProviderResult {
+ provideHover(
+ document: vscode.TextDocument,
+ position: vscode.Position,
+ token: vscode.CancellationToken,
+ ): vscode.ProviderResult {
if (!this.isCbsJsonFile(document)) {
return null;
}
@@ -21,16 +23,23 @@ export class CbsJsonHoverProvider implements vscode.HoverProvider {
const offset = document.offsetAt(position);
const text = document.getText();
const rootNode = jsonc.parseTree(text);
- if (!rootNode){
- return
+ if (!rootNode) {
+ return;
}
let node = jsonc.findNodeAtOffset(rootNode, offset);
- node = node?.parent
-
- if (node && node.type === 'property' && node.children && node.children[0].type === 'string') {
+ node = node?.parent;
+ if (
+ node &&
+ node.type === "property" &&
+ node.children &&
+ node.children[0].type === "string"
+ ) {
const key = node.children[0].value;
- const parentNode = jsonc.findNodeAtOffset(rootNode, node.parent!.offset);
+ const parentNode = jsonc.findNodeAtOffset(
+ rootNode,
+ node.parent!.offset,
+ );
const type = this.getParentType(parentNode);
const documentation = this.getDocumentationForKey(key, type);
@@ -43,24 +52,29 @@ export class CbsJsonHoverProvider implements vscode.HoverProvider {
}
private isCbsJsonFile(document: vscode.TextDocument): boolean {
- return document.fileName.endsWith('.cbs.json');
+ return document.fileName.endsWith(".cbs.json");
}
private getParentType(node: jsonc.Node | undefined): string | null {
if (!node || !node.parent) return null;
- if (node.parent.type === 'property') {
+ if (node.parent.type === "property") {
return node.parent.children![0].value;
}
return null;
}
-
- private getDocumentationForKey(key: string, type: string | null): vscode.MarkdownString | null {
+ private getDocumentationForKey(
+ key: string,
+ type: string | null,
+ ): vscode.MarkdownString | null {
let filePath: string;
switch (key) {
case "query":
- filePath = type === null ? "/docs/search/query.md" : "/docs/search/query_string.md";
+ filePath =
+ type === null
+ ? "/docs/search/query.md"
+ : "/docs/search/query_string.md";
break;
case "must":
filePath = "/docs/search/must.md";
@@ -165,7 +179,10 @@ export class CbsJsonHoverProvider implements vscode.HoverProvider {
filePath = "/docs/search/shape.md";
break;
case "type":
- filePath = type === "shape" ? "/docs/search/type_shape.md" : "/docs/search/type_facet.md";
+ filePath =
+ type === "shape"
+ ? "/docs/search/type_shape.md"
+ : "/docs/search/type_facet.md";
break;
case "coordinates":
filePath = "/docs/search/coordinates.md";
@@ -263,11 +280,13 @@ export class CbsJsonHoverProvider implements vscode.HoverProvider {
filePath = "/docs/search/style.md";
break;
default:
- return new vscode.MarkdownString("No documentation available for this key.");
+ return new vscode.MarkdownString(
+ "No documentation available for this key.",
+ );
}
try {
const fullPath = path.join(this.context.extensionPath, filePath);
- const content = fs.readFileSync(fullPath, 'utf8');
+ const content = fs.readFileSync(fullPath, "utf8");
return new vscode.MarkdownString(content);
} catch (error) {
logger.error(`Error reading documentation file: ${error}`);
@@ -275,5 +294,4 @@ export class CbsJsonHoverProvider implements vscode.HoverProvider {
return new vscode.MarkdownString("");
}
}
-
-}
\ No newline at end of file
+}
diff --git a/src/commands/fts/SearchWorkbench/indexParser/indexParser.ts b/src/commands/fts/SearchWorkbench/indexParser/indexParser.ts
index f901c91d..8b0b1105 100644
--- a/src/commands/fts/SearchWorkbench/indexParser/indexParser.ts
+++ b/src/commands/fts/SearchWorkbench/indexParser/indexParser.ts
@@ -4,34 +4,52 @@ export class SearchIndexParser {
const propertiesMap = new Map();
const typesNode = rootNode?.params?.mapping?.types;
- if (typesNode && typeof typesNode === 'object') {
+ if (typesNode && typeof typesNode === "object") {
for (const [_, typeValue] of Object.entries(typesNode)) {
- if (typeValue && typeof typeValue === 'object' && 'properties' in typeValue) {
+ if (
+ typeValue &&
+ typeof typeValue === "object" &&
+ "properties" in typeValue
+ ) {
const propertiesNode = (typeValue as any).properties;
- this.extractProperties(propertiesNode, '', propertiesMap);
+ this.extractProperties(propertiesNode, "", propertiesMap);
}
}
}
return propertiesMap;
}
- private static extractProperties(node: any, parentKey: string, propertiesMap: Map) {
- if (node && typeof node === 'object') {
+ private static extractProperties(
+ node: any,
+ parentKey: string,
+ propertiesMap: Map,
+ ) {
+ if (node && typeof node === "object") {
for (const [key, value] of Object.entries(node)) {
- if (typeof value === 'object' && value) {
- if ('properties' in value) {
- const newParentKey = parentKey ? `${parentKey}.${key}` : key;
- this.extractProperties(value.properties, newParentKey, propertiesMap);
- } else if ('fields' in value) {
- for (const fieldNode of (value.fields as any[])) {
- const type = fieldNode.type?.toString() || '';
+ if (typeof value === "object" && value) {
+ if ("properties" in value) {
+ const newParentKey = parentKey
+ ? `${parentKey}.${key}`
+ : key;
+ this.extractProperties(
+ value.properties,
+ newParentKey,
+ propertiesMap,
+ );
+ } else if ("fields" in value) {
+ for (const fieldNode of value.fields as any[]) {
+ const type = fieldNode.type?.toString() || "";
const fieldName = fieldNode.name?.toString() || key;
- const finalKey = parentKey ? `${parentKey}.${fieldName}` : fieldName;
+ const finalKey = parentKey
+ ? `${parentKey}.${fieldName}`
+ : fieldName;
propertiesMap.set(finalKey, type);
}
- } else if ('type' in value) {
- const type = value.type?.toString() || '';
- const finalKey = parentKey ? `${parentKey}.${key}` : key;
+ } else if ("type" in value) {
+ const type = value.type?.toString() || "";
+ const finalKey = parentKey
+ ? `${parentKey}.${key}`
+ : key;
propertiesMap.set(finalKey, type);
}
}
@@ -44,14 +62,17 @@ export class SearchIndexParser {
return rootNode?.params?.mapping?.index_dynamic || false;
}
- static isCollectionDynamicallyIndexed(index: any, collection: string): boolean {
+ static isCollectionDynamicallyIndexed(
+ index: any,
+ collection: string,
+ ): boolean {
const rootNode = index;
return rootNode?.params?.mapping?.types?.[collection]?.dynamic || false;
}
static getDefaultField(index: any): string {
const rootNode = index;
- return rootNode?.params?.mapping?.default_field || '';
+ return rootNode?.params?.mapping?.default_field || "";
}
static listCollections(index: any): string[] {
@@ -59,4 +80,4 @@ export class SearchIndexParser {
const typesNode = rootNode?.params?.mapping?.types;
return typesNode ? Object.keys(typesNode) : [];
}
-}
\ No newline at end of file
+}
diff --git a/src/commands/fts/SearchWorkbench/openSearchIndex.ts b/src/commands/fts/SearchWorkbench/openSearchIndex.ts
index 546ca4da..67b1071b 100644
--- a/src/commands/fts/SearchWorkbench/openSearchIndex.ts
+++ b/src/commands/fts/SearchWorkbench/openSearchIndex.ts
@@ -7,21 +7,35 @@ import ClusterConnectionTreeProvider from "../../../tree/ClusterConnectionTreePr
import { getActiveConnection } from "../../../util/connections";
import { CouchbaseRestAPI } from "../../../util/apis/CouchbaseRestAPI";
-export const openSearchIndex = async (searchIndexNode: SearchIndexNode, clusterConnectionTreeProvider: ClusterConnectionTreeProvider, uriToCasMap: Map, memFs: MemFS) => {
+export const openSearchIndex = async (
+ searchIndexNode: SearchIndexNode,
+ clusterConnectionTreeProvider: ClusterConnectionTreeProvider,
+ uriToCasMap: Map,
+ memFs: MemFS,
+) => {
try {
const connection = getActiveConnection();
if (!connection) {
return false;
}
const api = new CouchbaseRestAPI(connection);
- const result = await api.fetchSearchIndexDefinition(searchIndexNode.indexName);
+ const result = await api.fetchSearchIndexDefinition(
+ searchIndexNode.indexName,
+ );
- if (result?.indexDef instanceof Uint8Array || result?.indexDef instanceof Uint16Array || result?.indexDef instanceof Uint32Array) {
- vscode.window.showInformationMessage("Unable to open Index definition: It is not a valid JSON", { modal: true });
+ if (
+ result?.indexDef instanceof Uint8Array ||
+ result?.indexDef instanceof Uint16Array ||
+ result?.indexDef instanceof Uint32Array
+ ) {
+ vscode.window.showInformationMessage(
+ "Unable to open Index definition: It is not a valid JSON",
+ { modal: true },
+ );
return false;
}
const uri = vscode.Uri.parse(
- `couchbase:/${searchIndexNode.bucketName}/${searchIndexNode.scopeName}/Search/${searchIndexNode.indexName}.json`
+ `couchbase:/${searchIndexNode.bucketName}/${searchIndexNode.scopeName}/Search/${searchIndexNode.indexName}.json`,
);
if (result) {
uriToCasMap.set(uri.toString(), result.indexDef.toString());
@@ -30,23 +44,30 @@ export const openSearchIndex = async (searchIndexNode: SearchIndexNode, clusterC
memFs.writeFile(
uri,
Buffer.from(JSON.stringify(result?.indexDef, null, 2)),
- { create: true, overwrite: true }
+ { create: true, overwrite: true },
);
} catch (error) {
- logger.error("Failed to open Index definition, as it is not a valid JSON");
- vscode.window.showInformationMessage("Unable to open Index definition: It is not a valid JSON ", { modal: true });
+ logger.error(
+ "Failed to open Index definition, as it is not a valid JSON",
+ );
+ vscode.window.showInformationMessage(
+ "Unable to open Index definition: It is not a valid JSON ",
+ { modal: true },
+ );
return false;
}
const document = await vscode.workspace.openTextDocument(uri);
await vscode.window.showTextDocument(document, { preview: false });
return true;
} catch (err: any) {
- if (err instanceof vscode.FileSystemError && err.name === 'EntryNotFound (FileSystemError)' || err instanceof DocumentNotFoundError) {
+ if (
+ (err instanceof vscode.FileSystemError &&
+ err.name === "EntryNotFound (FileSystemError)") ||
+ err instanceof DocumentNotFoundError
+ ) {
clusterConnectionTreeProvider.refresh();
}
logger.error("Failed to open Document");
logger.debug(err);
}
-
-
-}
\ No newline at end of file
+};
diff --git a/src/commands/fts/SearchWorkbench/searchWorkbench.ts b/src/commands/fts/SearchWorkbench/searchWorkbench.ts
index f9f4bc5e..4cd2dcc9 100644
--- a/src/commands/fts/SearchWorkbench/searchWorkbench.ts
+++ b/src/commands/fts/SearchWorkbench/searchWorkbench.ts
@@ -1,13 +1,13 @@
-import * as vscode from 'vscode';
-import { getActiveConnection } from '../../../util/connections';
-import { WorkbenchWebviewProvider } from '../../../workbench/workbenchWebviewProvider';
+import * as vscode from "vscode";
+import { getActiveConnection } from "../../../util/connections";
+import { WorkbenchWebviewProvider } from "../../../workbench/workbenchWebviewProvider";
import { QueryStatus } from "couchbase";
-import { ISearchQueryContext } from '../../../types/ISearchQueryContext';
-import { CouchbaseRestAPI } from '../../../util/apis/CouchbaseRestAPI';
+import { ISearchQueryContext } from "../../../types/ISearchQueryContext";
+import { CouchbaseRestAPI } from "../../../util/apis/CouchbaseRestAPI";
import { MemFS } from "../../../util/fileSystemProvider";
-import UntitledSearchJsonDocumentService from './controller';
-import SearchIndexNode from '../../../model/SearchIndexNode';
-import { logger } from '../../../logger/logger';
+import UntitledSearchJsonDocumentService from "./controller";
+import SearchIndexNode from "../../../model/SearchIndexNode";
+import { logger } from "../../../logger/logger";
export class SearchWorkbench {
private _untitledSearchJsonDocumentService: UntitledSearchJsonDocumentService;
@@ -19,27 +19,29 @@ export class SearchWorkbench {
this.editorToContext = new Map();
}
-
runCouchbaseSearchQuery = async (
- workbenchWebviewProvider: WorkbenchWebviewProvider
+ workbenchWebviewProvider: WorkbenchWebviewProvider,
) => {
const connection = getActiveConnection();
if (!connection) {
vscode.window.showInformationMessage(
- "Kindly establish a connection with the cluster before running an index query."
+ "Kindly establish a connection with the cluster before running an index query.",
);
return false;
}
// Get the active text editor
const activeTextEditor = vscode.window.activeTextEditor;
- if (activeTextEditor && activeTextEditor.document.languageId === "json" && activeTextEditor.document.fileName.endsWith(".cbs.json")) {
+ if (
+ activeTextEditor &&
+ activeTextEditor.document.languageId === "json" &&
+ activeTextEditor.document.fileName.endsWith(".cbs.json")
+ ) {
try {
- JSON.parse(activeTextEditor.document.getText())
- }
- catch (err) {
+ JSON.parse(activeTextEditor.document.getText());
+ } catch (err) {
// Invalid JSON case
- let errorArray = []
+ let errorArray = [];
errorArray.push({
code: 0,
msg: "The query is not a valid JSON",
@@ -57,26 +59,39 @@ export class SearchWorkbench {
JSON.stringify(errorArray),
queryStatusProps,
null,
- true
+ true,
);
return;
}
activeTextEditor.document.save();
- const indexQueryPayload = activeTextEditor.selection.isEmpty ? activeTextEditor.document.getText() : activeTextEditor.document.getText(activeTextEditor.selection);
- const queryContext = this.editorToContext.get(activeTextEditor.document.uri.toString());
+ const indexQueryPayload = activeTextEditor.selection.isEmpty
+ ? activeTextEditor.document.getText()
+ : activeTextEditor.document.getText(activeTextEditor.selection);
+ const queryContext = this.editorToContext.get(
+ activeTextEditor.document.uri.toString(),
+ );
try {
// Reveal the webview when the extension is activated
- vscode.commands.executeCommand('workbench.view.extension.couchbase-workbench-panel');
+ vscode.commands.executeCommand(
+ "workbench.view.extension.couchbase-workbench-panel",
+ );
vscode.commands.executeCommand("workbench.action.focusPanel");
await new Promise((resolve) => setTimeout(resolve, 500));
- await workbenchWebviewProvider.sendQueryResult(JSON.stringify([{ "status": "Executing statement" }]), { queryStatus: QueryStatus.Running }, null);
+ await workbenchWebviewProvider.sendQueryResult(
+ JSON.stringify([{ status: "Executing statement" }]),
+ { queryStatus: QueryStatus.Running },
+ null,
+ );
const explainPlan = JSON.stringify("");
const couchbbaseRestAPI = new CouchbaseRestAPI(connection);
- const searchIndexesManager = connection?.cluster?.searchIndexes();
+ const searchIndexesManager =
+ connection?.cluster?.searchIndexes();
const ftsIndexes = await searchIndexesManager?.getAllIndexes();
- const bucketIndexes = ftsIndexes?.filter(index => index.name === queryContext?.indexName);
+ const bucketIndexes = ftsIndexes?.filter(
+ (index) => index.name === queryContext?.indexName,
+ );
if (bucketIndexes?.length == 0) {
// Index was deleted/ Not found
let editorId = activeTextEditor.document.uri.toString();
@@ -87,23 +102,35 @@ export class SearchWorkbench {
}
}
const start = Date.now();
- const searchQueryResult = await couchbbaseRestAPI.runSearchIndexes(queryContext?.indexName, indexQueryPayload);
- const end = Date.now()
- const rtt = end - start
+ const searchQueryResult =
+ await couchbbaseRestAPI.runSearchIndexes(
+ queryContext?.indexName,
+ indexQueryPayload,
+ );
+ const end = Date.now();
+ const rtt = end - start;
const resultJson = JSON.stringify(searchQueryResult);
const resultSize = new TextEncoder().encode(resultJson).length;
const queryStatusProps = {
- queryStatus: searchQueryResult?.status.successful === 1 ? "success" : "fatal",
+ queryStatus:
+ searchQueryResult?.status.successful === 1
+ ? "success"
+ : "fatal",
rtt: rtt.toString() + " MS",
- elapsed: (searchQueryResult?.took / 1000).toString() + " MS",
+ elapsed:
+ (searchQueryResult?.took / 1000).toString() + " MS",
numDocs: searchQueryResult?.total_hits.toString() + " docs",
- size: resultSize ? (resultSize > 1000 ? (resultSize / 1000).toFixed(2) + " KB" : resultSize + " Bytes") : ""
+ size: resultSize
+ ? resultSize > 1000
+ ? (resultSize / 1000).toFixed(2) + " KB"
+ : resultSize + " Bytes"
+ : "",
};
workbenchWebviewProvider.setQueryResult(
JSON.stringify(searchQueryResult?.hits),
queryStatusProps,
explainPlan,
- true
+ true,
);
} catch (err: any) {
const errorArray = [];
@@ -111,14 +138,17 @@ export class SearchWorkbench {
if (err.response.status === 400) {
errorArray.push({
code: err.response.status,
- msg: err.response.data.error || 'Bad request',
- query: (err.config && err.config.url) ? err.config.url : 'No URL',
+ msg: err.response.data.error || "Bad request",
+ query:
+ err.config && err.config.url
+ ? err.config.url
+ : "No URL",
});
} else {
errorArray.push({
code: err.response.status,
msg: err.message,
- query: err.config && err.config.url
+ query: err.config && err.config.url,
});
}
} else {
@@ -136,20 +166,20 @@ export class SearchWorkbench {
JSON.stringify(errorArray),
queryStatusProps,
null,
- true
+ true,
);
}
-
}
-
- }
+ };
openSearchWorkbench(searchIndexNode: SearchIndexNode, memFs: MemFS) {
try {
- return this._untitledSearchJsonDocumentService.newQuery(searchIndexNode, memFs);
+ return this._untitledSearchJsonDocumentService.newQuery(
+ searchIndexNode,
+ memFs,
+ );
} catch (error) {
logger.error("Error while opening Search WorkBench:" + error);
throw error;
}
}
-
-}
\ No newline at end of file
+}
diff --git a/src/commands/fts/SearchWorkbench/test/booleanObject.test.ts b/src/commands/fts/SearchWorkbench/test/booleanObject.test.ts
index c2169386..f274f485 100644
--- a/src/commands/fts/SearchWorkbench/test/booleanObject.test.ts
+++ b/src/commands/fts/SearchWorkbench/test/booleanObject.test.ts
@@ -1,20 +1,24 @@
-import * as vscode from 'vscode';
-import { validateDocument } from '../validators/validationUtil';
-import { ValidationHelper } from '../validators/validationHelper';
+import * as vscode from "vscode";
+import { validateDocument } from "../validators/validationUtil";
+import { ValidationHelper } from "../validators/validationHelper";
let mockText = "";
-jest.mock('vscode', () => ({
+jest.mock("vscode", () => ({
languages: {
createDiagnosticCollection: jest.fn().mockImplementation(() => {
const diagnosticsMap = new Map();
return {
clear: jest.fn(() => diagnosticsMap.clear()),
dispose: jest.fn(),
- get: jest.fn(uri => diagnosticsMap.get(uri.toString())),
- set: jest.fn((uri, diagnostics) => diagnosticsMap.set(uri.toString(), diagnostics)),
- delete: jest.fn(uri => diagnosticsMap.delete(uri.toString())),
- forEach: jest.fn(callback => diagnosticsMap.forEach(callback)),
+ get: jest.fn((uri) => diagnosticsMap.get(uri.toString())),
+ set: jest.fn((uri, diagnostics) =>
+ diagnosticsMap.set(uri.toString(), diagnostics),
+ ),
+ delete: jest.fn((uri) => diagnosticsMap.delete(uri.toString())),
+ forEach: jest.fn((callback) =>
+ diagnosticsMap.forEach(callback),
+ ),
};
}),
},
@@ -25,40 +29,41 @@ jest.mock('vscode', () => ({
},
workspace: {
openTextDocument: jest.fn().mockImplementation((uri) => ({
- getText: jest.fn(() => mockText),
+ getText: jest.fn(() => mockText),
uri: uri,
positionAt: jest.fn().mockImplementation((index) => {
- return new vscode.Position(Math.floor(index / 100), index % 100);
+ return new vscode.Position(
+ Math.floor(index / 100),
+ index % 100,
+ );
}),
})),
fs: {
writeFile: jest.fn(),
- }
+ },
},
Range: jest.fn().mockImplementation((start, end) => ({
start: start,
- end: end
+ end: end,
})),
Position: jest.fn().mockImplementation((line, character) => ({
line: line,
- character: character
+ character: character,
})),
Diagnostic: jest.fn().mockImplementation((range, message, severity) => ({
range: range,
message: message,
- severity: severity
+ severity: severity,
})),
DiagnosticSeverity: {
- Error: 0,
+ Error: 0,
Warning: 1,
Information: 2,
- Hint: 3
- }
+ Hint: 3,
+ },
}));
-
-
-const setMockText = (text:any) => {
+const setMockText = (text: any) => {
mockText = text;
};
@@ -66,7 +71,8 @@ describe("CBSBooleanInspection Tests", () => {
let diagnosticsCollection: vscode.DiagnosticCollection;
beforeEach(() => {
- diagnosticsCollection = vscode.languages.createDiagnosticCollection('testCollection');
+ diagnosticsCollection =
+ vscode.languages.createDiagnosticCollection("testCollection");
});
afterEach(() => {
@@ -94,7 +100,7 @@ describe("CBSBooleanInspection Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
expect(diagnosticsCollection.get(uri)?.length).toBe(0);
});
@@ -119,9 +125,15 @@ describe("CBSBooleanInspection Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getMustConjunctsErrorMessage()))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getMustConjunctsErrorMessage(),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Valid Should", async () => {
@@ -146,7 +158,7 @@ describe("CBSBooleanInspection Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
expect(diagnosticsCollection.get(uri)?.length).toBe(0);
});
@@ -172,9 +184,15 @@ describe("CBSBooleanInspection Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getShouldErrorMessage()))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getShouldErrorMessage(),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Must", async () => {
@@ -199,9 +217,15 @@ describe("CBSBooleanInspection Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getMustConjunctsErrorMessage()))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getMustConjunctsErrorMessage(),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Valid Must not", async () => {
@@ -226,7 +250,7 @@ describe("CBSBooleanInspection Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
expect(diagnosticsCollection.get(uri)?.length).toBe(0);
});
@@ -251,9 +275,15 @@ describe("CBSBooleanInspection Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getMustNotDisjunctsErrorMessage()))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getMustNotDisjunctsErrorMessage(),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Must Not Min", async () => {
@@ -279,14 +309,20 @@ describe("CBSBooleanInspection Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getMustNotDisjunctsErrorMessage()))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getMustNotDisjunctsErrorMessage(),
+ ),
+ ),
+ ).toBeTruthy();
});
async function getDiagnosticsForJson(jsonText: string) {
try {
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
await vscode.workspace.fs.writeFile(uri, Buffer.from(jsonText));
const document = await vscode.workspace.openTextDocument(uri);
validateDocument(document, diagnosticsCollection);
@@ -294,4 +330,4 @@ describe("CBSBooleanInspection Tests", () => {
console.error("Error during testing:", error);
}
}
-});
\ No newline at end of file
+});
diff --git a/src/commands/fts/SearchWorkbench/test/ctlConsistencyObject.test.ts b/src/commands/fts/SearchWorkbench/test/ctlConsistencyObject.test.ts
index 11790c03..427a77d0 100644
--- a/src/commands/fts/SearchWorkbench/test/ctlConsistencyObject.test.ts
+++ b/src/commands/fts/SearchWorkbench/test/ctlConsistencyObject.test.ts
@@ -1,21 +1,25 @@
-import * as vscode from 'vscode';
-import { validateDocument } from '../validators/validationUtil';
-import { mock } from 'node:test';
-import { ValidationHelper } from '../validators/validationHelper';
+import * as vscode from "vscode";
+import { validateDocument } from "../validators/validationUtil";
+import { mock } from "node:test";
+import { ValidationHelper } from "../validators/validationHelper";
let mockText = "";
-jest.mock('vscode', () => ({
+jest.mock("vscode", () => ({
languages: {
createDiagnosticCollection: jest.fn().mockImplementation(() => {
const diagnosticsMap = new Map();
return {
clear: jest.fn(() => diagnosticsMap.clear()),
dispose: jest.fn(),
- get: jest.fn(uri => diagnosticsMap.get(uri.toString())),
- set: jest.fn((uri, diagnostics) => diagnosticsMap.set(uri.toString(), diagnostics)),
- delete: jest.fn(uri => diagnosticsMap.delete(uri.toString())),
- forEach: jest.fn(callback => diagnosticsMap.forEach(callback)),
+ get: jest.fn((uri) => diagnosticsMap.get(uri.toString())),
+ set: jest.fn((uri, diagnostics) =>
+ diagnosticsMap.set(uri.toString(), diagnostics),
+ ),
+ delete: jest.fn((uri) => diagnosticsMap.delete(uri.toString())),
+ forEach: jest.fn((callback) =>
+ diagnosticsMap.forEach(callback),
+ ),
};
}),
},
@@ -26,40 +30,41 @@ jest.mock('vscode', () => ({
},
workspace: {
openTextDocument: jest.fn().mockImplementation((uri) => ({
- getText: jest.fn(() => mockText),
+ getText: jest.fn(() => mockText),
uri: uri,
positionAt: jest.fn().mockImplementation((index) => {
- return new vscode.Position(Math.floor(index / 100), index % 100);
+ return new vscode.Position(
+ Math.floor(index / 100),
+ index % 100,
+ );
}),
})),
fs: {
writeFile: jest.fn(),
- }
+ },
},
Range: jest.fn().mockImplementation((start, end) => ({
start: start,
- end: end
+ end: end,
})),
Position: jest.fn().mockImplementation((line, character) => ({
line: line,
- character: character
+ character: character,
})),
Diagnostic: jest.fn().mockImplementation((range, message, severity) => ({
range: range,
message: message,
- severity: severity
+ severity: severity,
})),
DiagnosticSeverity: {
- Error: 0,
+ Error: 0,
Warning: 1,
Information: 2,
- Hint: 3
- }
+ Hint: 3,
+ },
}));
-
-
-const setMockText = (text:any) => {
+const setMockText = (text: any) => {
mockText = text;
};
@@ -67,7 +72,8 @@ describe("Ctl Consistency Object Tests", () => {
let diagnosticsCollection: vscode.DiagnosticCollection;
beforeEach(() => {
- diagnosticsCollection = vscode.languages.createDiagnosticCollection('testCollection');
+ diagnosticsCollection =
+ vscode.languages.createDiagnosticCollection("testCollection");
});
afterEach(() => {
@@ -97,7 +103,7 @@ describe("Ctl Consistency Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
expect(diagnosticsCollection.get(uri)?.length).toBe(0);
});
@@ -123,7 +129,7 @@ describe("Ctl Consistency Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
expect(diagnosticsCollection.get(uri)?.length).toBe(0);
});
@@ -140,9 +146,18 @@ describe("Ctl Consistency Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getSingleOccurrenceMessage("consistency", "ctl")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getSingleOccurrenceMessage(
+ "consistency",
+ "ctl",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Consistency Types", async () => {
@@ -164,14 +179,40 @@ describe("Ctl Consistency Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("json", "vectors")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("string", "level")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("string", "results")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "json",
+ "vectors",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "string",
+ "level",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "string",
+ "results",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
-
test("Invalid CTL Object Types", async () => {
const json = `
{
@@ -188,10 +229,28 @@ describe("Ctl Consistency Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("number", "timeout")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("json", "consistency")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "number",
+ "timeout",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "json",
+ "consistency",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Valid Consistency", async () => {
@@ -219,7 +278,7 @@ describe("Ctl Consistency Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(0);
});
@@ -248,9 +307,18 @@ describe("Ctl Consistency Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getMissingAttributeMessage("level", "consistency")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getMissingAttributeMessage(
+ "level",
+ "consistency",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Level Not Bounded", async () => {
@@ -272,7 +340,7 @@ describe("Ctl Consistency Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(0);
});
@@ -295,9 +363,18 @@ describe("Ctl Consistency Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getMissingAttributeMessage("vectors", "consistency")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getMissingAttributeMessage(
+ "vectors",
+ "consistency",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Result", async () => {
@@ -325,16 +402,20 @@ describe("Ctl Consistency Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getResultErrorMessage()))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getResultErrorMessage(),
+ ),
+ ),
+ ).toBeTruthy();
});
-
-
async function getDiagnosticsForJson(jsonText: string) {
try {
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
await vscode.workspace.fs.writeFile(uri, Buffer.from(jsonText));
const document = await vscode.workspace.openTextDocument(uri);
validateDocument(document, diagnosticsCollection);
@@ -342,5 +423,4 @@ describe("Ctl Consistency Object Tests", () => {
console.error("Error during testing:", error);
}
}
-
-});
\ No newline at end of file
+});
diff --git a/src/commands/fts/SearchWorkbench/test/geometryObject.test.ts b/src/commands/fts/SearchWorkbench/test/geometryObject.test.ts
index 224212a7..2d2dfc8f 100644
--- a/src/commands/fts/SearchWorkbench/test/geometryObject.test.ts
+++ b/src/commands/fts/SearchWorkbench/test/geometryObject.test.ts
@@ -1,21 +1,25 @@
-import * as vscode from 'vscode';
-import { validateDocument } from '../validators/validationUtil';
-import { mock } from 'node:test';
-import { ValidationHelper } from '../validators/validationHelper';
+import * as vscode from "vscode";
+import { validateDocument } from "../validators/validationUtil";
+import { mock } from "node:test";
+import { ValidationHelper } from "../validators/validationHelper";
let mockText = "";
-jest.mock('vscode', () => ({
+jest.mock("vscode", () => ({
languages: {
createDiagnosticCollection: jest.fn().mockImplementation(() => {
const diagnosticsMap = new Map();
return {
clear: jest.fn(() => diagnosticsMap.clear()),
dispose: jest.fn(),
- get: jest.fn(uri => diagnosticsMap.get(uri.toString())),
- set: jest.fn((uri, diagnostics) => diagnosticsMap.set(uri.toString(), diagnostics)),
- delete: jest.fn(uri => diagnosticsMap.delete(uri.toString())),
- forEach: jest.fn(callback => diagnosticsMap.forEach(callback)),
+ get: jest.fn((uri) => diagnosticsMap.get(uri.toString())),
+ set: jest.fn((uri, diagnostics) =>
+ diagnosticsMap.set(uri.toString(), diagnostics),
+ ),
+ delete: jest.fn((uri) => diagnosticsMap.delete(uri.toString())),
+ forEach: jest.fn((callback) =>
+ diagnosticsMap.forEach(callback),
+ ),
};
}),
},
@@ -26,40 +30,41 @@ jest.mock('vscode', () => ({
},
workspace: {
openTextDocument: jest.fn().mockImplementation((uri) => ({
- getText: jest.fn(() => mockText),
+ getText: jest.fn(() => mockText),
uri: uri,
positionAt: jest.fn().mockImplementation((index) => {
- return new vscode.Position(Math.floor(index / 100), index % 100);
+ return new vscode.Position(
+ Math.floor(index / 100),
+ index % 100,
+ );
}),
})),
fs: {
writeFile: jest.fn(),
- }
+ },
},
Range: jest.fn().mockImplementation((start, end) => ({
start: start,
- end: end
+ end: end,
})),
Position: jest.fn().mockImplementation((line, character) => ({
line: line,
- character: character
+ character: character,
})),
Diagnostic: jest.fn().mockImplementation((range, message, severity) => ({
range: range,
message: message,
- severity: severity
+ severity: severity,
})),
DiagnosticSeverity: {
- Error: 0,
+ Error: 0,
Warning: 1,
Information: 2,
- Hint: 3
- }
+ Hint: 3,
+ },
}));
-
-
-const setMockText = (text:any) => {
+const setMockText = (text: any) => {
mockText = text;
};
@@ -67,7 +72,8 @@ describe("Geometry Object Tests", () => {
let diagnosticsCollection: vscode.DiagnosticCollection;
beforeEach(() => {
- diagnosticsCollection = vscode.languages.createDiagnosticCollection('testCollection');
+ diagnosticsCollection =
+ vscode.languages.createDiagnosticCollection("testCollection");
});
afterEach(() => {
@@ -93,7 +99,7 @@ describe("Geometry Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(0);
});
@@ -116,9 +122,18 @@ describe("Geometry Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.missingRequiredAttributeQuery("coordinates", "shape")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.missingRequiredAttributeQuery(
+ "coordinates",
+ "shape",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Shape Missing Type", async () => {
@@ -139,9 +154,18 @@ describe("Geometry Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.missingRequiredAttributeQuery("type", "shape")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.missingRequiredAttributeQuery(
+ "type",
+ "shape",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Shape Missing Geometries", async () => {
@@ -162,9 +186,18 @@ describe("Geometry Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.missingRequiredAttributeQuery("geometries", "shape")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.missingRequiredAttributeQuery(
+ "geometries",
+ "shape",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Shape Missing Radius", async () => {
@@ -186,9 +219,18 @@ describe("Geometry Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.missingRequiredAttributeQuery("radius", "shape")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.missingRequiredAttributeQuery(
+ "radius",
+ "shape",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Valid Circle", async () => {
@@ -211,7 +253,7 @@ describe("Geometry Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(0);
});
@@ -236,10 +278,29 @@ describe("Geometry Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- const validUnits = ["mm", "cm", "in", "yd", "ft", "km", "mi", "nm", "m"];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getInvalidDistanceUnitErrorMessage("radius", validUnits)))).toBeTruthy();
+ const validUnits = [
+ "mm",
+ "cm",
+ "in",
+ "yd",
+ "ft",
+ "km",
+ "mi",
+ "nm",
+ "m",
+ ];
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getInvalidDistanceUnitErrorMessage(
+ "radius",
+ validUnits,
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Relation Value", async () => {
@@ -261,17 +322,20 @@ describe("Geometry Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getRelationErrorMessage()))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getRelationErrorMessage(),
+ ),
+ ),
+ ).toBeTruthy();
});
-
-
-
async function getDiagnosticsForJson(jsonText: string) {
try {
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
await vscode.workspace.fs.writeFile(uri, Buffer.from(jsonText));
const document = await vscode.workspace.openTextDocument(uri);
validateDocument(document, diagnosticsCollection);
@@ -279,5 +343,4 @@ describe("Geometry Object Tests", () => {
console.error("Error during testing:", error);
}
}
-
-});
\ No newline at end of file
+});
diff --git a/src/commands/fts/SearchWorkbench/test/highlightObject.test.ts b/src/commands/fts/SearchWorkbench/test/highlightObject.test.ts
index dd2fd82b..889b166c 100644
--- a/src/commands/fts/SearchWorkbench/test/highlightObject.test.ts
+++ b/src/commands/fts/SearchWorkbench/test/highlightObject.test.ts
@@ -1,20 +1,24 @@
-import * as vscode from 'vscode';
-import { validateDocument } from '../validators/validationUtil';
-import { ValidationHelper } from '../validators/validationHelper';
+import * as vscode from "vscode";
+import { validateDocument } from "../validators/validationUtil";
+import { ValidationHelper } from "../validators/validationHelper";
let mockText = "";
-jest.mock('vscode', () => ({
+jest.mock("vscode", () => ({
languages: {
createDiagnosticCollection: jest.fn().mockImplementation(() => {
const diagnosticsMap = new Map();
return {
clear: jest.fn(() => diagnosticsMap.clear()),
dispose: jest.fn(),
- get: jest.fn(uri => diagnosticsMap.get(uri.toString())),
- set: jest.fn((uri, diagnostics) => diagnosticsMap.set(uri.toString(), diagnostics)),
- delete: jest.fn(uri => diagnosticsMap.delete(uri.toString())),
- forEach: jest.fn(callback => diagnosticsMap.forEach(callback)),
+ get: jest.fn((uri) => diagnosticsMap.get(uri.toString())),
+ set: jest.fn((uri, diagnostics) =>
+ diagnosticsMap.set(uri.toString(), diagnostics),
+ ),
+ delete: jest.fn((uri) => diagnosticsMap.delete(uri.toString())),
+ forEach: jest.fn((callback) =>
+ diagnosticsMap.forEach(callback),
+ ),
};
}),
},
@@ -25,38 +29,41 @@ jest.mock('vscode', () => ({
},
workspace: {
openTextDocument: jest.fn().mockImplementation((uri) => ({
- getText: jest.fn(() => mockText),
+ getText: jest.fn(() => mockText),
uri: uri,
positionAt: jest.fn().mockImplementation((index) => {
- return new vscode.Position(Math.floor(index / 100), index % 100);
+ return new vscode.Position(
+ Math.floor(index / 100),
+ index % 100,
+ );
}),
})),
fs: {
writeFile: jest.fn(),
- }
+ },
},
Range: jest.fn().mockImplementation((start, end) => ({
start: start,
- end: end
+ end: end,
})),
Position: jest.fn().mockImplementation((line, character) => ({
line: line,
- character: character
+ character: character,
})),
Diagnostic: jest.fn().mockImplementation((range, message, severity) => ({
range: range,
message: message,
- severity: severity
+ severity: severity,
})),
DiagnosticSeverity: {
- Error: 0,
+ Error: 0,
Warning: 1,
Information: 2,
- Hint: 3
- }
+ Hint: 3,
+ },
}));
-const setMockText = (text:any) => {
+const setMockText = (text: any) => {
mockText = text;
};
@@ -64,7 +71,8 @@ describe("Highlight Object Tests", () => {
let diagnosticsCollection: vscode.DiagnosticCollection;
beforeEach(() => {
- diagnosticsCollection = vscode.languages.createDiagnosticCollection('testCollection');
+ diagnosticsCollection =
+ vscode.languages.createDiagnosticCollection("testCollection");
});
afterEach(() => {
@@ -87,7 +95,7 @@ describe("Highlight Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(0);
});
@@ -105,7 +113,7 @@ describe("Highlight Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(0);
});
@@ -152,9 +160,18 @@ describe("Highlight Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getUnexpectedAttributeMessage("fielsd", "highlight")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getUnexpectedAttributeMessage(
+ "fielsd",
+ "highlight",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Attribute Types", async () => {
@@ -173,10 +190,28 @@ describe("Highlight Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("string", "style")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("array", "fields")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "string",
+ "style",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "array",
+ "fields",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Style Value", async () => {
@@ -195,21 +230,25 @@ describe("Highlight Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getStyleValuesErrorMessage()))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getStyleValuesErrorMessage(),
+ ),
+ ),
+ ).toBeTruthy();
});
-
-async function getDiagnosticsForJson(jsonText: string) {
- try {
- const uri = vscode.Uri.parse('untitled:test.json');
- await vscode.workspace.fs.writeFile(uri, Buffer.from(jsonText));
- const document = await vscode.workspace.openTextDocument(uri);
- validateDocument(document, diagnosticsCollection);
- } catch (error) {
- console.error("Error during testing:", error);
+ async function getDiagnosticsForJson(jsonText: string) {
+ try {
+ const uri = vscode.Uri.parse("untitled:test.json");
+ await vscode.workspace.fs.writeFile(uri, Buffer.from(jsonText));
+ const document = await vscode.workspace.openTextDocument(uri);
+ validateDocument(document, diagnosticsCollection);
+ } catch (error) {
+ console.error("Error during testing:", error);
+ }
}
-}
-
-});
\ No newline at end of file
+});
diff --git a/src/commands/fts/SearchWorkbench/test/knnObject.test.ts b/src/commands/fts/SearchWorkbench/test/knnObject.test.ts
index dc6c9bfa..854480aa 100644
--- a/src/commands/fts/SearchWorkbench/test/knnObject.test.ts
+++ b/src/commands/fts/SearchWorkbench/test/knnObject.test.ts
@@ -1,20 +1,24 @@
-import * as vscode from 'vscode';
-import { validateDocument } from '../validators/validationUtil';
-import { ValidationHelper } from '../validators/validationHelper';
+import * as vscode from "vscode";
+import { validateDocument } from "../validators/validationUtil";
+import { ValidationHelper } from "../validators/validationHelper";
let mockText = "";
-jest.mock('vscode', () => ({
+jest.mock("vscode", () => ({
languages: {
createDiagnosticCollection: jest.fn().mockImplementation(() => {
const diagnosticsMap = new Map();
return {
clear: jest.fn(() => diagnosticsMap.clear()),
dispose: jest.fn(),
- get: jest.fn(uri => diagnosticsMap.get(uri.toString())),
- set: jest.fn((uri, diagnostics) => diagnosticsMap.set(uri.toString(), diagnostics)),
- delete: jest.fn(uri => diagnosticsMap.delete(uri.toString())),
- forEach: jest.fn(callback => diagnosticsMap.forEach(callback)),
+ get: jest.fn((uri) => diagnosticsMap.get(uri.toString())),
+ set: jest.fn((uri, diagnostics) =>
+ diagnosticsMap.set(uri.toString(), diagnostics),
+ ),
+ delete: jest.fn((uri) => diagnosticsMap.delete(uri.toString())),
+ forEach: jest.fn((callback) =>
+ diagnosticsMap.forEach(callback),
+ ),
};
}),
},
@@ -25,38 +29,41 @@ jest.mock('vscode', () => ({
},
workspace: {
openTextDocument: jest.fn().mockImplementation((uri) => ({
- getText: jest.fn(() => mockText),
+ getText: jest.fn(() => mockText),
uri: uri,
positionAt: jest.fn().mockImplementation((index) => {
- return new vscode.Position(Math.floor(index / 100), index % 100);
+ return new vscode.Position(
+ Math.floor(index / 100),
+ index % 100,
+ );
}),
})),
fs: {
writeFile: jest.fn(),
- }
+ },
},
Range: jest.fn().mockImplementation((start, end) => ({
start: start,
- end: end
+ end: end,
})),
Position: jest.fn().mockImplementation((line, character) => ({
line: line,
- character: character
+ character: character,
})),
Diagnostic: jest.fn().mockImplementation((range, message, severity) => ({
range: range,
message: message,
- severity: severity
+ severity: severity,
})),
DiagnosticSeverity: {
- Error: 0,
+ Error: 0,
Warning: 1,
Information: 2,
- Hint: 3
- }
+ Hint: 3,
+ },
}));
-const setMockText = (text:any) => {
+const setMockText = (text: any) => {
mockText = text;
};
@@ -64,7 +71,8 @@ describe("Knn Object Tests", () => {
let diagnosticsCollection: vscode.DiagnosticCollection;
beforeEach(() => {
- diagnosticsCollection = vscode.languages.createDiagnosticCollection('testCollection');
+ diagnosticsCollection =
+ vscode.languages.createDiagnosticCollection("testCollection");
});
afterEach(() => {
@@ -87,7 +95,7 @@ describe("Knn Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(0);
});
@@ -137,15 +145,24 @@ describe("Knn Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(1);
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getUnexpectedAttributeMessage("query", "knn")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getUnexpectedAttributeMessage(
+ "query",
+ "knn",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
async function getDiagnosticsForJson(jsonText: string) {
try {
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
await vscode.workspace.fs.writeFile(uri, Buffer.from(jsonText));
const document = await vscode.workspace.openTextDocument(uri);
validateDocument(document, diagnosticsCollection);
@@ -153,5 +170,4 @@ describe("Knn Object Tests", () => {
console.error("Error during testing:", error);
}
}
-
- });
\ No newline at end of file
+});
diff --git a/src/commands/fts/SearchWorkbench/test/matchAllNoneObject.test.ts b/src/commands/fts/SearchWorkbench/test/matchAllNoneObject.test.ts
index 042d8e94..8a2aad2a 100644
--- a/src/commands/fts/SearchWorkbench/test/matchAllNoneObject.test.ts
+++ b/src/commands/fts/SearchWorkbench/test/matchAllNoneObject.test.ts
@@ -1,20 +1,24 @@
-import * as vscode from 'vscode';
-import { validateDocument } from '../validators/validationUtil';
-import { ValidationHelper } from '../validators/validationHelper';
+import * as vscode from "vscode";
+import { validateDocument } from "../validators/validationUtil";
+import { ValidationHelper } from "../validators/validationHelper";
let mockText = "";
-jest.mock('vscode', () => ({
+jest.mock("vscode", () => ({
languages: {
createDiagnosticCollection: jest.fn().mockImplementation(() => {
const diagnosticsMap = new Map();
return {
clear: jest.fn(() => diagnosticsMap.clear()),
dispose: jest.fn(),
- get: jest.fn(uri => diagnosticsMap.get(uri.toString())),
- set: jest.fn((uri, diagnostics) => diagnosticsMap.set(uri.toString(), diagnostics)),
- delete: jest.fn(uri => diagnosticsMap.delete(uri.toString())),
- forEach: jest.fn(callback => diagnosticsMap.forEach(callback)),
+ get: jest.fn((uri) => diagnosticsMap.get(uri.toString())),
+ set: jest.fn((uri, diagnostics) =>
+ diagnosticsMap.set(uri.toString(), diagnostics),
+ ),
+ delete: jest.fn((uri) => diagnosticsMap.delete(uri.toString())),
+ forEach: jest.fn((callback) =>
+ diagnosticsMap.forEach(callback),
+ ),
};
}),
},
@@ -25,38 +29,41 @@ jest.mock('vscode', () => ({
},
workspace: {
openTextDocument: jest.fn().mockImplementation((uri) => ({
- getText: jest.fn(() => mockText),
+ getText: jest.fn(() => mockText),
uri: uri,
positionAt: jest.fn().mockImplementation((index) => {
- return new vscode.Position(Math.floor(index / 100), index % 100);
+ return new vscode.Position(
+ Math.floor(index / 100),
+ index % 100,
+ );
}),
})),
fs: {
writeFile: jest.fn(),
- }
+ },
},
Range: jest.fn().mockImplementation((start, end) => ({
start: start,
- end: end
+ end: end,
})),
Position: jest.fn().mockImplementation((line, character) => ({
line: line,
- character: character
+ character: character,
})),
Diagnostic: jest.fn().mockImplementation((range, message, severity) => ({
range: range,
message: message,
- severity: severity
+ severity: severity,
})),
DiagnosticSeverity: {
- Error: 0,
+ Error: 0,
Warning: 1,
Information: 2,
- Hint: 3
- }
+ Hint: 3,
+ },
}));
-const setMockText = (text:any) => {
+const setMockText = (text: any) => {
mockText = text;
};
@@ -64,7 +71,8 @@ describe("MatchAllNone Object Tests", () => {
let diagnosticsCollection: vscode.DiagnosticCollection;
beforeEach(() => {
- diagnosticsCollection = vscode.languages.createDiagnosticCollection('testCollection');
+ diagnosticsCollection =
+ vscode.languages.createDiagnosticCollection("testCollection");
});
afterEach(() => {
@@ -83,7 +91,7 @@ describe("MatchAllNone Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(0);
});
@@ -102,10 +110,17 @@ describe("MatchAllNone Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getMatchAllNoneNoAttributeErrorMessage("match_all")))).toBeTruthy();
-
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getMatchAllNoneNoAttributeErrorMessage(
+ "match_all",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Valid Match None", async () => {
@@ -120,7 +135,7 @@ describe("MatchAllNone Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(0);
});
@@ -139,14 +154,22 @@ describe("MatchAllNone Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getMatchAllNoneNoAttributeErrorMessage("match_none")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getMatchAllNoneNoAttributeErrorMessage(
+ "match_none",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
async function getDiagnosticsForJson(jsonText: string) {
try {
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
await vscode.workspace.fs.writeFile(uri, Buffer.from(jsonText));
const document = await vscode.workspace.openTextDocument(uri);
validateDocument(document, diagnosticsCollection);
@@ -154,5 +177,4 @@ describe("MatchAllNone Object Tests", () => {
console.error("Error during testing:", error);
}
}
-
- });
\ No newline at end of file
+});
diff --git a/src/commands/fts/SearchWorkbench/test/queryObject.test.ts b/src/commands/fts/SearchWorkbench/test/queryObject.test.ts
index 1355805a..a272b98c 100644
--- a/src/commands/fts/SearchWorkbench/test/queryObject.test.ts
+++ b/src/commands/fts/SearchWorkbench/test/queryObject.test.ts
@@ -1,21 +1,25 @@
-import * as vscode from 'vscode';
-import { validateDocument } from '../validators/validationUtil';
-import { ValidationHelper } from '../validators/validationHelper';
-import { QueryTypeObjectValidator } from '../validators/queryTypeObjectValidator';
+import * as vscode from "vscode";
+import { validateDocument } from "../validators/validationUtil";
+import { ValidationHelper } from "../validators/validationHelper";
+import { QueryTypeObjectValidator } from "../validators/queryTypeObjectValidator";
let mockText = "";
-jest.mock('vscode', () => ({
+jest.mock("vscode", () => ({
languages: {
createDiagnosticCollection: jest.fn().mockImplementation(() => {
const diagnosticsMap = new Map();
return {
clear: jest.fn(() => diagnosticsMap.clear()),
dispose: jest.fn(),
- get: jest.fn(uri => diagnosticsMap.get(uri.toString())),
- set: jest.fn((uri, diagnostics) => diagnosticsMap.set(uri.toString(), diagnostics)),
- delete: jest.fn(uri => diagnosticsMap.delete(uri.toString())),
- forEach: jest.fn(callback => diagnosticsMap.forEach(callback)),
+ get: jest.fn((uri) => diagnosticsMap.get(uri.toString())),
+ set: jest.fn((uri, diagnostics) =>
+ diagnosticsMap.set(uri.toString(), diagnostics),
+ ),
+ delete: jest.fn((uri) => diagnosticsMap.delete(uri.toString())),
+ forEach: jest.fn((callback) =>
+ diagnosticsMap.forEach(callback),
+ ),
};
}),
},
@@ -26,38 +30,41 @@ jest.mock('vscode', () => ({
},
workspace: {
openTextDocument: jest.fn().mockImplementation((uri) => ({
- getText: jest.fn(() => mockText),
+ getText: jest.fn(() => mockText),
uri: uri,
positionAt: jest.fn().mockImplementation((index) => {
- return new vscode.Position(Math.floor(index / 100), index % 100);
+ return new vscode.Position(
+ Math.floor(index / 100),
+ index % 100,
+ );
}),
})),
fs: {
writeFile: jest.fn(),
- }
+ },
},
Range: jest.fn().mockImplementation((start, end) => ({
start: start,
- end: end
+ end: end,
})),
Position: jest.fn().mockImplementation((line, character) => ({
line: line,
- character: character
+ character: character,
})),
Diagnostic: jest.fn().mockImplementation((range, message, severity) => ({
range: range,
message: message,
- severity: severity
+ severity: severity,
})),
DiagnosticSeverity: {
- Error: 0,
+ Error: 0,
Warning: 1,
Information: 2,
- Hint: 3
- }
+ Hint: 3,
+ },
}));
-const setMockText = (text:any) => {
+const setMockText = (text: any) => {
mockText = text;
};
@@ -65,7 +72,8 @@ describe("Query Object Tests", () => {
let diagnosticsCollection: vscode.DiagnosticCollection;
beforeEach(() => {
- diagnosticsCollection = vscode.languages.createDiagnosticCollection('testCollection');
+ diagnosticsCollection =
+ vscode.languages.createDiagnosticCollection("testCollection");
});
afterEach(() => {
@@ -82,9 +90,17 @@ describe("Query Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getUnexecptedAttributeAtTopLevel("invalidKey")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getUnexecptedAttributeAtTopLevel(
+ "invalidKey",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Top Level Object Key", async () => {
@@ -97,9 +113,17 @@ describe("Query Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getUnexecptedAttributeAtTopLevel("invalidKey")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getUnexecptedAttributeAtTopLevel(
+ "invalidKey",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Valid Query", async () => {
@@ -114,7 +138,7 @@ describe("Query Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(0);
});
@@ -132,9 +156,15 @@ describe("Query Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(QueryTypeObjectValidator.getInvalidFieldWithQueryMessage()))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ QueryTypeObjectValidator.getInvalidFieldWithQueryMessage(),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Query Type Top Level", async () => {
@@ -147,9 +177,18 @@ describe("Query Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("json", "query")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "json",
+ "query",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Query Type Nested Level", async () => {
@@ -164,9 +203,18 @@ describe("Query Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("string", "query")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "string",
+ "query",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Nested Query Attribute", async () => {
@@ -181,9 +229,18 @@ describe("Query Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getUnexpectedAttributeMessage("vector", "query")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getUnexpectedAttributeMessage(
+ "vector",
+ "query",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
// test("Invalid Empty Query", async () => {
@@ -203,7 +260,7 @@ describe("Query Object Tests", () => {
async function getDiagnosticsForJson(jsonText: string) {
try {
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
await vscode.workspace.fs.writeFile(uri, Buffer.from(jsonText));
const document = await vscode.workspace.openTextDocument(uri);
validateDocument(document, diagnosticsCollection);
@@ -211,5 +268,4 @@ describe("Query Object Tests", () => {
console.error("Error during testing:", error);
}
}
-
- });
\ No newline at end of file
+});
diff --git a/src/commands/fts/SearchWorkbench/test/queryTypeObject.test.ts b/src/commands/fts/SearchWorkbench/test/queryTypeObject.test.ts
index 59e90c74..f2e65d2a 100644
--- a/src/commands/fts/SearchWorkbench/test/queryTypeObject.test.ts
+++ b/src/commands/fts/SearchWorkbench/test/queryTypeObject.test.ts
@@ -1,21 +1,25 @@
-import * as vscode from 'vscode';
-import { validateDocument } from '../validators/validationUtil';
-import { ValidationHelper } from '../validators/validationHelper';
-import { QueryTypeObjectValidator } from '../validators/queryTypeObjectValidator';
+import * as vscode from "vscode";
+import { validateDocument } from "../validators/validationUtil";
+import { ValidationHelper } from "../validators/validationHelper";
+import { QueryTypeObjectValidator } from "../validators/queryTypeObjectValidator";
let mockText = "";
-jest.mock('vscode', () => ({
+jest.mock("vscode", () => ({
languages: {
createDiagnosticCollection: jest.fn().mockImplementation(() => {
const diagnosticsMap = new Map();
return {
clear: jest.fn(() => diagnosticsMap.clear()),
dispose: jest.fn(),
- get: jest.fn(uri => diagnosticsMap.get(uri.toString())),
- set: jest.fn((uri, diagnostics) => diagnosticsMap.set(uri.toString(), diagnostics)),
- delete: jest.fn(uri => diagnosticsMap.delete(uri.toString())),
- forEach: jest.fn(callback => diagnosticsMap.forEach(callback)),
+ get: jest.fn((uri) => diagnosticsMap.get(uri.toString())),
+ set: jest.fn((uri, diagnostics) =>
+ diagnosticsMap.set(uri.toString(), diagnostics),
+ ),
+ delete: jest.fn((uri) => diagnosticsMap.delete(uri.toString())),
+ forEach: jest.fn((callback) =>
+ diagnosticsMap.forEach(callback),
+ ),
};
}),
},
@@ -26,38 +30,41 @@ jest.mock('vscode', () => ({
},
workspace: {
openTextDocument: jest.fn().mockImplementation((uri) => ({
- getText: jest.fn(() => mockText),
+ getText: jest.fn(() => mockText),
uri: uri,
positionAt: jest.fn().mockImplementation((index) => {
- return new vscode.Position(Math.floor(index / 100), index % 100);
+ return new vscode.Position(
+ Math.floor(index / 100),
+ index % 100,
+ );
}),
})),
fs: {
writeFile: jest.fn(),
- }
+ },
},
Range: jest.fn().mockImplementation((start, end) => ({
start: start,
- end: end
+ end: end,
})),
Position: jest.fn().mockImplementation((line, character) => ({
line: line,
- character: character
+ character: character,
})),
Diagnostic: jest.fn().mockImplementation((range, message, severity) => ({
range: range,
message: message,
- severity: severity
+ severity: severity,
})),
DiagnosticSeverity: {
- Error: 0,
+ Error: 0,
Warning: 1,
Information: 2,
- Hint: 3
- }
+ Hint: 3,
+ },
}));
-const setMockText = (text:any) => {
+const setMockText = (text: any) => {
mockText = text;
};
@@ -65,7 +72,8 @@ describe("Query Type Object Tests", () => {
let diagnosticsCollection: vscode.DiagnosticCollection;
beforeEach(() => {
- diagnosticsCollection = vscode.languages.createDiagnosticCollection('testCollection');
+ diagnosticsCollection =
+ vscode.languages.createDiagnosticCollection("testCollection");
});
afterEach(() => {
@@ -87,7 +95,7 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(0);
});
@@ -109,14 +117,68 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("string", "match")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("string", "field")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("string", "analyzer")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("string", "operator")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("number", "fuzziness")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("number", "prefix_length")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "string",
+ "match",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "string",
+ "field",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "string",
+ "analyzer",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "string",
+ "operator",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "number",
+ "fuzziness",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "number",
+ "prefix_length",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Valid Match Operator", async () => {
@@ -134,9 +196,15 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(QueryTypeObjectValidator.invalidOperatorMessage()))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ QueryTypeObjectValidator.invalidOperatorMessage(),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Match Without Operator", async () => {
@@ -153,9 +221,15 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(QueryTypeObjectValidator.matchWithSpaceMessage()))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ QueryTypeObjectValidator.matchWithSpaceMessage(),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Match", async () => {
@@ -173,9 +247,18 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getUnexpectedAttributeMessageForQuery("min", "match")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getUnexpectedAttributeMessageForQuery(
+ "min",
+ "match",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Valid Numeric Range", async () => {
@@ -192,9 +275,18 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getUnexpectedAttributeMessageForQuery("match", "numeric range")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getUnexpectedAttributeMessageForQuery(
+ "match",
+ "numeric range",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Valid Match Phrase", async () => {
@@ -213,7 +305,7 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(0);
});
@@ -234,9 +326,18 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("string", "match_phrase")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "string",
+ "match_phrase",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Valid Boolean", async () => {
@@ -252,7 +353,7 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(0);
});
@@ -270,10 +371,19 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(1);
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("boolean", "bool")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "boolean",
+ "bool",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Valid Prefix", async () => {
@@ -289,7 +399,7 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(0);
});
@@ -307,9 +417,18 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("string", "prefix")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "string",
+ "prefix",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Prefix With Fuzziness", async () => {
@@ -326,9 +445,18 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getUnexpectedAttributeMessageForQuery("fuzziness", "prefix")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getUnexpectedAttributeMessageForQuery(
+ "fuzziness",
+ "prefix",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Valid Regex", async () => {
@@ -344,7 +472,7 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(0);
});
@@ -362,9 +490,18 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("string", "regexp")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "string",
+ "regexp",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Valid Term", async () => {
@@ -381,7 +518,7 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(0);
});
@@ -401,9 +538,18 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getUnexpectedAttributeMessageForQuery("analyzer", "term")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getUnexpectedAttributeMessageForQuery(
+ "analyzer",
+ "term",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Term", async () => {
@@ -420,9 +566,18 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("string", "term")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "string",
+ "term",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Valid Terms", async () => {
@@ -438,7 +593,7 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(0);
});
@@ -457,9 +612,18 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getUnexpectedAttributeMessageForQuery("analyzer", "terms")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getUnexpectedAttributeMessageForQuery(
+ "analyzer",
+ "terms",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Terms", async () => {
@@ -475,10 +639,19 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(1);
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("array", "terms")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "array",
+ "terms",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Valid Wildcard", async () => {
@@ -494,7 +667,7 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(0);
});
@@ -512,10 +685,19 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(1);
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("string", "wildcard")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "string",
+ "wildcard",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Valid CIDR", async () => {
@@ -531,7 +713,7 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(0);
});
@@ -549,10 +731,19 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(1);
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("string", "cidr")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "string",
+ "cidr",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Valid Numeric Range", async () => {
@@ -571,7 +762,7 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(0);
});
@@ -590,9 +781,15 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(QueryTypeObjectValidator.minOrMaxRequiredMessage()))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ QueryTypeObjectValidator.minOrMaxRequiredMessage(),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Range", async () => {
@@ -611,10 +808,28 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("boolean", "inclusive_min")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("boolean", "inclusive_max")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "boolean",
+ "inclusive_min",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "boolean",
+ "inclusive_max",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Valid Date Range", async () => {
@@ -633,7 +848,7 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(0);
});
@@ -654,15 +869,50 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("string", "start")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("string", "end")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("boolean", "inclusive_start")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("boolean", "inclusive_end")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "string",
+ "start",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "string",
+ "end",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "boolean",
+ "inclusive_start",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "boolean",
+ "inclusive_end",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
-
test("Valid Conjuncts", async () => {
const json = `
{
@@ -687,7 +937,7 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(0);
});
@@ -710,13 +960,21 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(1);
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("array", "conjuncts")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "array",
+ "conjuncts",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
-
test("Invalid Disjuncts Type", async () => {
const json = `
{
@@ -735,9 +993,18 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("array", "disjuncts")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "array",
+ "disjuncts",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Valid Disjuncts", async () => {
@@ -762,7 +1029,7 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(0);
});
@@ -791,9 +1058,15 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(QueryTypeObjectValidator.getFieldNotAllowedOnCompound()))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ QueryTypeObjectValidator.getFieldNotAllowedOnCompound(),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Valid Distance Object", async () => {
@@ -813,7 +1086,7 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(0);
});
@@ -834,9 +1107,18 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.missingRequiredAttributeQuery("distance", "distance radius")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.missingRequiredAttributeQuery(
+ "distance",
+ "distance radius",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Missing Location", async () => {
@@ -852,9 +1134,18 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.missingRequiredAttributeQuery("location", "distance radius")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.missingRequiredAttributeQuery(
+ "location",
+ "distance radius",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Valid Distance Array Location", async () => {
@@ -871,7 +1162,7 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(0);
});
@@ -892,9 +1183,17 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedObjectPropertiesMessage("location")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedObjectPropertiesMessage(
+ "location",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Distance Attribute", async () => {
@@ -915,9 +1214,18 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getUnexpectedAttributeMessageForQuery("fuzziness", "distance radius")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getUnexpectedAttributeMessageForQuery(
+ "fuzziness",
+ "distance radius",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Distance Value", async () => {
@@ -937,9 +1245,18 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("string", "distance")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "string",
+ "distance",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Distance Unit", async () => {
@@ -959,10 +1276,29 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- const validUnits = ["mm", "cm", "in", "yd", "ft", "km", "mi", "nm", "m"];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getInvalidDistanceUnitErrorMessage("distance", validUnits)))).toBeTruthy();
+ const validUnits = [
+ "mm",
+ "cm",
+ "in",
+ "yd",
+ "ft",
+ "km",
+ "mi",
+ "nm",
+ "m",
+ ];
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getInvalidDistanceUnitErrorMessage(
+ "distance",
+ validUnits,
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Valid Rectangle", async () => {
@@ -982,7 +1318,7 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(0);
});
@@ -1003,9 +1339,18 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.missingRequiredAttributeQuery("top_left", "rectangle based")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.missingRequiredAttributeQuery(
+ "top_left",
+ "rectangle based",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Rectangle Missing Bottom Right", async () => {
@@ -1021,9 +1366,18 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.missingRequiredAttributeQuery("bottom_right", "rectangle based")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.missingRequiredAttributeQuery(
+ "bottom_right",
+ "rectangle based",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Valid Polygon", async () => {
@@ -1046,7 +1400,7 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(0);
});
@@ -1064,9 +1418,18 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("array", "polygon_points")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "array",
+ "polygon_points",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Polygon Array", async () => {
@@ -1086,16 +1449,40 @@ describe("Query Type Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedLatLonMessage("polygon_points[0]")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedLatLonMessage("polygon_points[1]")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedLatLonMessage("polygon_points[2]")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedLatLonMessage(
+ "polygon_points[0]",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedLatLonMessage(
+ "polygon_points[1]",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedLatLonMessage(
+ "polygon_points[2]",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
async function getDiagnosticsForJson(jsonText: string) {
try {
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
await vscode.workspace.fs.writeFile(uri, Buffer.from(jsonText));
const document = await vscode.workspace.openTextDocument(uri);
validateDocument(document, diagnosticsCollection);
@@ -1103,5 +1490,4 @@ describe("Query Type Object Tests", () => {
console.error("Error during testing:", error);
}
}
-
- });
\ No newline at end of file
+});
diff --git a/src/commands/fts/SearchWorkbench/test/rootObject.test.ts b/src/commands/fts/SearchWorkbench/test/rootObject.test.ts
index 1c3289dd..3322028a 100644
--- a/src/commands/fts/SearchWorkbench/test/rootObject.test.ts
+++ b/src/commands/fts/SearchWorkbench/test/rootObject.test.ts
@@ -1,20 +1,24 @@
-import * as vscode from 'vscode';
-import { validateDocument } from '../validators/validationUtil';
-import { ValidationHelper } from '../validators/validationHelper';
+import * as vscode from "vscode";
+import { validateDocument } from "../validators/validationUtil";
+import { ValidationHelper } from "../validators/validationHelper";
let mockText = "";
-jest.mock('vscode', () => ({
+jest.mock("vscode", () => ({
languages: {
createDiagnosticCollection: jest.fn().mockImplementation(() => {
const diagnosticsMap = new Map();
return {
clear: jest.fn(() => diagnosticsMap.clear()),
dispose: jest.fn(),
- get: jest.fn(uri => diagnosticsMap.get(uri.toString())),
- set: jest.fn((uri, diagnostics) => diagnosticsMap.set(uri.toString(), diagnostics)),
- delete: jest.fn(uri => diagnosticsMap.delete(uri.toString())),
- forEach: jest.fn(callback => diagnosticsMap.forEach(callback)),
+ get: jest.fn((uri) => diagnosticsMap.get(uri.toString())),
+ set: jest.fn((uri, diagnostics) =>
+ diagnosticsMap.set(uri.toString(), diagnostics),
+ ),
+ delete: jest.fn((uri) => diagnosticsMap.delete(uri.toString())),
+ forEach: jest.fn((callback) =>
+ diagnosticsMap.forEach(callback),
+ ),
};
}),
},
@@ -25,38 +29,41 @@ jest.mock('vscode', () => ({
},
workspace: {
openTextDocument: jest.fn().mockImplementation((uri) => ({
- getText: jest.fn(() => mockText),
+ getText: jest.fn(() => mockText),
uri: uri,
positionAt: jest.fn().mockImplementation((index) => {
- return new vscode.Position(Math.floor(index / 100), index % 100);
+ return new vscode.Position(
+ Math.floor(index / 100),
+ index % 100,
+ );
}),
})),
fs: {
writeFile: jest.fn(),
- }
+ },
},
Range: jest.fn().mockImplementation((start, end) => ({
start: start,
- end: end
+ end: end,
})),
Position: jest.fn().mockImplementation((line, character) => ({
line: line,
- character: character
+ character: character,
})),
Diagnostic: jest.fn().mockImplementation((range, message, severity) => ({
range: range,
message: message,
- severity: severity
+ severity: severity,
})),
DiagnosticSeverity: {
- Error: 0,
+ Error: 0,
Warning: 1,
Information: 2,
- Hint: 3
- }
+ Hint: 3,
+ },
}));
-const setMockText = (text:any) => {
+const setMockText = (text: any) => {
mockText = text;
};
@@ -64,7 +71,8 @@ describe("Root Object Tests", () => {
let diagnosticsCollection: vscode.DiagnosticCollection;
beforeEach(() => {
- diagnosticsCollection = vscode.languages.createDiagnosticCollection('testCollection');
+ diagnosticsCollection =
+ vscode.languages.createDiagnosticCollection("testCollection");
});
afterEach(() => {
@@ -102,7 +110,7 @@ describe("Root Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(0);
});
@@ -128,9 +136,15 @@ describe("Root Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getRequiredQueryKnnErrorMessage()))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getRequiredQueryKnnErrorMessage(),
+ ),
+ ),
+ ).toBeTruthy();
});
test("Invalid Key", async () => {
@@ -157,10 +171,18 @@ describe("Root Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
expect(diagnostics.length).toBe(1);
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getUnexecptedAttributeAtTopLevel("offsets")))).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getUnexecptedAttributeAtTopLevel(
+ "offsets",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
// TODO: add duplicate
@@ -220,31 +242,183 @@ describe("Root Object Tests", () => {
setMockText(json);
await getDiagnosticsForJson(json);
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
const diagnostics = diagnosticsCollection.get(uri) ?? [];
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("json", "query")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("array", "knn")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("json", "ctl")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("number", "size")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("number", "limit")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("number", "from")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("number", "offset")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("json", "highlight")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("array", "fields")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("json", "facets")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("boolean", "explain")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("array", "sort")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("boolean", "includeLocations")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("string", "score")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("array", "search_after")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("array", "search_before")))).toBeTruthy();
- expect(diagnostics.some(diagnostic => diagnostic.message.includes(ValidationHelper.getExpectedDataTypeErrorMessage("array", "collections")))).toBeTruthy();
-
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "json",
+ "query",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "array",
+ "knn",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "json",
+ "ctl",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "number",
+ "size",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "number",
+ "limit",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "number",
+ "from",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "number",
+ "offset",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "json",
+ "highlight",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "array",
+ "fields",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "json",
+ "facets",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "boolean",
+ "explain",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "array",
+ "sort",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "boolean",
+ "includeLocations",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "string",
+ "score",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "array",
+ "search_after",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "array",
+ "search_before",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
+ expect(
+ diagnostics.some((diagnostic) =>
+ diagnostic.message.includes(
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "array",
+ "collections",
+ ),
+ ),
+ ),
+ ).toBeTruthy();
});
async function getDiagnosticsForJson(jsonText: string) {
try {
- const uri = vscode.Uri.parse('untitled:test.json');
+ const uri = vscode.Uri.parse("untitled:test.json");
await vscode.workspace.fs.writeFile(uri, Buffer.from(jsonText));
const document = await vscode.workspace.openTextDocument(uri);
validateDocument(document, diagnosticsCollection);
@@ -252,5 +426,4 @@ describe("Root Object Tests", () => {
console.error("Error during testing:", error);
}
}
-
- });
\ No newline at end of file
+});
diff --git a/src/commands/fts/SearchWorkbench/validators/JsonNodes.ts b/src/commands/fts/SearchWorkbench/validators/JsonNodes.ts
index e663d1c4..25aac0bc 100644
--- a/src/commands/fts/SearchWorkbench/validators/JsonNodes.ts
+++ b/src/commands/fts/SearchWorkbench/validators/JsonNodes.ts
@@ -16,7 +16,6 @@ export class JsonArray implements JsonNode {
parent?: JsonNode | null;
children: JsonNode[] = [];
-
constructor(parent?: JsonNode | null) {
this.parent = parent;
}
@@ -24,8 +23,8 @@ export class JsonArray implements JsonNode {
export class JsonProperty implements JsonNode {
parent?: JsonNode | null;
- key: string;
- value: any;
+ key: string;
+ value: any;
constructor(key: string, value: any, parent?: JsonNode | null) {
this.key = key;
@@ -33,4 +32,3 @@ export class JsonProperty implements JsonNode {
this.parent = parent;
}
}
-
diff --git a/src/commands/fts/SearchWorkbench/validators/booleanObjectValidator.ts b/src/commands/fts/SearchWorkbench/validators/booleanObjectValidator.ts
index 7332c47a..41beb5f7 100644
--- a/src/commands/fts/SearchWorkbench/validators/booleanObjectValidator.ts
+++ b/src/commands/fts/SearchWorkbench/validators/booleanObjectValidator.ts
@@ -1,25 +1,37 @@
-import * as vscode from 'vscode';
-import { SearchObjectValidator } from './searchValidator';
-import { JsonObject, JsonProperty } from './JsonNodes';
-import { ValidationHelper } from './validationHelper';
+import * as vscode from "vscode";
+import { SearchObjectValidator } from "./searchValidator";
+import { JsonObject, JsonProperty } from "./JsonNodes";
+import { ValidationHelper } from "./validationHelper";
export class BooleanObjectValidator implements SearchObjectValidator {
accept(key: string | null): boolean {
return key === "must" || key === "must_not" || key === "should";
}
- validate(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument, key: string): void {
- const attrs = jsonObject.children.map(child => child instanceof JsonProperty ? child.key : null).filter(key => key !== null);
+ validate(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ key: string,
+ ): void {
+ const attrs = jsonObject.children
+ .map((child) => (child instanceof JsonProperty ? child.key : null))
+ .filter((key) => key !== null);
const positionMap = ValidationHelper.getPositionMap(document);
-
+
if (key === "must") {
if (attrs.length !== 1 || !attrs.includes("conjuncts")) {
const newDiagnostic = new vscode.Diagnostic(
positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
ValidationHelper.getMustConjunctsErrorMessage(),
- vscode.DiagnosticSeverity.Error
+ vscode.DiagnosticSeverity.Error,
);
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
@@ -28,27 +40,40 @@ export class BooleanObjectValidator implements SearchObjectValidator {
const newDiagnostic = new vscode.Diagnostic(
positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
ValidationHelper.getMustNotDisjunctsErrorMessage(),
- vscode.DiagnosticSeverity.Error
+ vscode.DiagnosticSeverity.Error,
);
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
} else if (key === "should") {
- if (!(attrs.length === 1 && attrs.includes("disjuncts")) &&
- !(attrs.length === 2 && attrs.includes("disjuncts") && attrs.includes("min"))) {
+ if (
+ !(attrs.length === 1 && attrs.includes("disjuncts")) &&
+ !(
+ attrs.length === 2 &&
+ attrs.includes("disjuncts") &&
+ attrs.includes("min")
+ )
+ ) {
const newDiagnostic = new vscode.Diagnostic(
positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
ValidationHelper.getShouldErrorMessage(),
- vscode.DiagnosticSeverity.Error
+ vscode.DiagnosticSeverity.Error,
);
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
}
}
-
-
-
-}
\ No newline at end of file
+}
diff --git a/src/commands/fts/SearchWorkbench/validators/ctlConsistencyObjectValidator.ts b/src/commands/fts/SearchWorkbench/validators/ctlConsistencyObjectValidator.ts
index 9444fb79..6246a30f 100644
--- a/src/commands/fts/SearchWorkbench/validators/ctlConsistencyObjectValidator.ts
+++ b/src/commands/fts/SearchWorkbench/validators/ctlConsistencyObjectValidator.ts
@@ -1,101 +1,146 @@
-import * as vscode from 'vscode';
-import { SearchObjectValidator } from './searchValidator';
-import { JsonObject, JsonProperty } from './JsonNodes';
-import { ValidationHelper } from './validationHelper';
+import * as vscode from "vscode";
+import { SearchObjectValidator } from "./searchValidator";
+import { JsonObject, JsonProperty } from "./JsonNodes";
+import { ValidationHelper } from "./validationHelper";
export class CtlConsistencyObjectValidator implements SearchObjectValidator {
accept(key: string | null): boolean {
return key === "consistency";
}
- validate(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument, key: string): void {
+ validate(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ key: string,
+ ): void {
const counter: Map = new Map();
let level: string | null = null;
let results: string | null = null;
const positionMap = ValidationHelper.getPositionMap(document);
-
- jsonObject.children.forEach(child => {
+
+ jsonObject.children.forEach((child) => {
if (child instanceof JsonProperty) {
const propertyKey = child.key;
const propertyValue = child.value;
if (!["vectors", "level", "results"].includes(propertyKey)) {
const newDiagnostic = new vscode.Diagnostic(
- positionMap.get(propertyKey) || new vscode.Range(0, 0, 0, 1),
- ValidationHelper.getUnexpectedAttributeMessage(propertyKey, "consistency"),
- vscode.DiagnosticSeverity.Error
+ positionMap.get(propertyKey) ||
+ new vscode.Range(0, 0, 0, 1),
+ ValidationHelper.getUnexpectedAttributeMessage(
+ propertyKey,
+ "consistency",
+ ),
+ vscode.DiagnosticSeverity.Error,
);
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
} else {
- counter.set(propertyKey, (counter.get(propertyKey) || 0) + 1);
+ counter.set(
+ propertyKey,
+ (counter.get(propertyKey) || 0) + 1,
+ );
}
if (propertyKey === "level") {
- if (!["at_plus", "not_bounded"].includes(propertyValue.value)) {
+ if (
+ !["at_plus", "not_bounded"].includes(
+ propertyValue.value,
+ )
+ ) {
const newDiagnostic = new vscode.Diagnostic(
- positionMap.get("level") || new vscode.Range(0, 0, 0, 1),
+ positionMap.get("level") ||
+ new vscode.Range(0, 0, 0, 1),
ValidationHelper.getLevelValuesErrorMessage(),
- vscode.DiagnosticSeverity.Error
+ vscode.DiagnosticSeverity.Error,
);
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
} else {
level = propertyValue.value;
}
}
-
+
if (propertyKey === "results") {
results = propertyValue.value;
}
}
});
-
+
if ((counter.get("level") || 0) === 0) {
const newDiagnostic = new vscode.Diagnostic(
positionMap.get("consistency") || new vscode.Range(0, 0, 0, 1),
- ValidationHelper.getMissingAttributeMessage("level", "consistency"),
- vscode.DiagnosticSeverity.Error
+ ValidationHelper.getMissingAttributeMessage(
+ "level",
+ "consistency",
+ ),
+ vscode.DiagnosticSeverity.Error,
);
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
-
+
if (level === "at_plus" && (counter.get("vectors") || 0) === 0) {
const newDiagnostic = new vscode.Diagnostic(
positionMap.get("consistency") || new vscode.Range(0, 0, 0, 1),
- ValidationHelper.getMissingAttributeMessage("vectors", "consistency"),
- vscode.DiagnosticSeverity.Error
+ ValidationHelper.getMissingAttributeMessage(
+ "vectors",
+ "consistency",
+ ),
+ vscode.DiagnosticSeverity.Error,
);
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
-
+
if (results !== null && results !== "complete") {
const newDiagnostic = new vscode.Diagnostic(
positionMap.get("results") || new vscode.Range(0, 0, 0, 1),
ValidationHelper.getResultErrorMessage(),
- vscode.DiagnosticSeverity.Error
+ vscode.DiagnosticSeverity.Error,
);
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
}
-
-
}
-
- // TODO: Check for multiple occurrences of optional keys
- // counter.forEach((count, propertyKey) => {
- // if (count > 1) {
- // diagnosticsList.push(new vscode.Diagnostic(
- // positionMap.get(propertyKey) || new vscode.Range(0, 0, 0, 1),
- // CtlConsistencyObjectValidator.singleOptionalKeyOccurrenceMessage(propertyKey, "consistency"),
- // vscode.DiagnosticSeverity.Error
- // ));
- // }
- // });
\ No newline at end of file
+// TODO: Check for multiple occurrences of optional keys
+// counter.forEach((count, propertyKey) => {
+// if (count > 1) {
+// diagnosticsList.push(new vscode.Diagnostic(
+// positionMap.get(propertyKey) || new vscode.Range(0, 0, 0, 1),
+// CtlConsistencyObjectValidator.singleOptionalKeyOccurrenceMessage(propertyKey, "consistency"),
+// vscode.DiagnosticSeverity.Error
+// ));
+// }
+// });
diff --git a/src/commands/fts/SearchWorkbench/validators/ctlObjectValidator.ts b/src/commands/fts/SearchWorkbench/validators/ctlObjectValidator.ts
index 3b069538..044447e2 100644
--- a/src/commands/fts/SearchWorkbench/validators/ctlObjectValidator.ts
+++ b/src/commands/fts/SearchWorkbench/validators/ctlObjectValidator.ts
@@ -1,61 +1,84 @@
-import * as vscode from 'vscode';
-import { SearchObjectValidator } from './searchValidator';
-import { JsonObject, JsonProperty } from './JsonNodes';
-import { ValidationHelper } from './validationHelper';
+import * as vscode from "vscode";
+import { SearchObjectValidator } from "./searchValidator";
+import { JsonObject, JsonProperty } from "./JsonNodes";
+import { ValidationHelper } from "./validationHelper";
export class CTLObjectValidator implements SearchObjectValidator {
accept(key: string | null): boolean {
return key === "ctl";
}
- validate(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument, key: string): void {
+ validate(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ key: string,
+ ): void {
if (!jsonObject || !(jsonObject instanceof JsonObject)) {
return;
}
const counter: Map = new Map();
const positionMap = ValidationHelper.getPositionMap(document);
-
- jsonObject.children.forEach(child => {
+
+ jsonObject.children.forEach((child) => {
if (child instanceof JsonProperty) {
const propertyKey = child.key;
if (!["consistency", "timeout"].includes(propertyKey)) {
const newDiagnostic = new vscode.Diagnostic(
- positionMap.get(propertyKey) || new vscode.Range(0, 0, 0, 1),
- ValidationHelper.getUnexpectedAttributeMessage(propertyKey, "ctl"),
- vscode.DiagnosticSeverity.Error
+ positionMap.get(propertyKey) ||
+ new vscode.Range(0, 0, 0, 1),
+ ValidationHelper.getUnexpectedAttributeMessage(
+ propertyKey,
+ "ctl",
+ ),
+ vscode.DiagnosticSeverity.Error,
);
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
} else {
- counter.set(propertyKey, (counter.get(propertyKey) || 0) + 1);
+ counter.set(
+ propertyKey,
+ (counter.get(propertyKey) || 0) + 1,
+ );
}
}
});
-
+
// Check for required 'consistency' key
if ((counter.get("consistency") || 0) === 0) {
const newDiagnostic = new vscode.Diagnostic(
positionMap.get("ctl") || new vscode.Range(0, 0, 0, 1),
- ValidationHelper.getSingleOccurrenceMessage("consistency", "ctl"),
- vscode.DiagnosticSeverity.Error
+ ValidationHelper.getSingleOccurrenceMessage(
+ "consistency",
+ "ctl",
+ ),
+ vscode.DiagnosticSeverity.Error,
);
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
}
-
-
}
- // TODO: Check for multiple occurrences of optional keys
- // counter.forEach((count, propertyKey) => {
- // if (count > 1) {
- // diagnosticsList.push(new vscode.Diagnostic(
- // positionMap.get(propertyKey) || new vscode.Range(0, 0, 0, 1),
- // CTLObjectValidator.singleOptionalKeyOccurrenceMessage(propertyKey, "ctl"),
- // vscode.DiagnosticSeverity.Error
- // ));
- // }
- // });
\ No newline at end of file
+// TODO: Check for multiple occurrences of optional keys
+// counter.forEach((count, propertyKey) => {
+// if (count > 1) {
+// diagnosticsList.push(new vscode.Diagnostic(
+// positionMap.get(propertyKey) || new vscode.Range(0, 0, 0, 1),
+// CTLObjectValidator.singleOptionalKeyOccurrenceMessage(propertyKey, "ctl"),
+// vscode.DiagnosticSeverity.Error
+// ));
+// }
+// });
diff --git a/src/commands/fts/SearchWorkbench/validators/geometryObjectValidator.ts b/src/commands/fts/SearchWorkbench/validators/geometryObjectValidator.ts
index 397af1ee..dcfb1497 100644
--- a/src/commands/fts/SearchWorkbench/validators/geometryObjectValidator.ts
+++ b/src/commands/fts/SearchWorkbench/validators/geometryObjectValidator.ts
@@ -1,76 +1,123 @@
-import * as vscode from 'vscode';
-import { SearchObjectValidator } from './searchValidator';
-import { JsonArray,JsonObject,JsonProperty } from './JsonNodes';
-import { ValidationHelper } from './validationHelper';
+import * as vscode from "vscode";
+import { SearchObjectValidator } from "./searchValidator";
+import { JsonArray, JsonObject, JsonProperty } from "./JsonNodes";
+import { ValidationHelper } from "./validationHelper";
export class GeometryObjectValidator implements SearchObjectValidator {
accept(key: string | null): boolean {
return key === "geometry";
}
-
- validate(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument, key: string): void {
+ validate(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ key: string,
+ ): void {
const target = "geometry";
const requiredFields = ["shape", "relation"];
const counter: Map = new Map();
const currentAttributes: string[] = [];
const positionMap = ValidationHelper.getPositionMap(document);
-
- jsonObject.children.forEach(child => {
+
+ jsonObject.children.forEach((child) => {
if (!(child instanceof JsonProperty)) {
return;
}
-
+
const propertyKey = child.key;
const propertyValue = child.value;
currentAttributes.push(propertyKey);
-
+
if (!["shape", "relation", "boost"].includes(propertyKey)) {
const newDiagnostic = new vscode.Diagnostic(
- positionMap.get(propertyKey) || new vscode.Range(0, 0, 0, 1),
+ positionMap.get(propertyKey) ||
+ new vscode.Range(0, 0, 0, 1),
`Unexpected attribute '${propertyKey}' for query '${target}'`,
- vscode.DiagnosticSeverity.Error
+ vscode.DiagnosticSeverity.Error,
);
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
} else {
counter.set(propertyKey, (counter.get(propertyKey) || 0) + 1);
if (propertyKey === "relation") {
- this.validateRelation(propertyValue, child, diagnosticsList, document);
+ this.validateRelation(
+ propertyValue,
+ child,
+ diagnosticsList,
+ document,
+ );
}
}
});
-
- this.checkMissingFields(requiredFields, currentAttributes, diagnosticsList, document, positionMap);
+
+ this.checkMissingFields(
+ requiredFields,
+ currentAttributes,
+ diagnosticsList,
+ document,
+ positionMap,
+ );
// this.validateMultipleOccurrences(counter, diagnosticsList, document); // Consider enabling if needed
}
- private validateRelation(propertyValue: any, property: JsonProperty, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument): void {
- if (!["intersects", "contains", "within"].includes(propertyValue.value)) {
+ private validateRelation(
+ propertyValue: any,
+ property: JsonProperty,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ ): void {
+ if (
+ !["intersects", "contains", "within"].includes(propertyValue.value)
+ ) {
const positionMap = ValidationHelper.getPositionMap(document);
const newDiagnostic = new vscode.Diagnostic(
positionMap.get("relation") || new vscode.Range(0, 0, 0, 1),
ValidationHelper.getRelationErrorMessage(),
- vscode.DiagnosticSeverity.Error
+ vscode.DiagnosticSeverity.Error,
);
-
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
}
- private checkMissingFields(requiredFields: string[], currentAttributes: string[], diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument, positionMap: any): void {
- requiredFields.forEach(field => {
+ private checkMissingFields(
+ requiredFields: string[],
+ currentAttributes: string[],
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ positionMap: any,
+ ): void {
+ requiredFields.forEach((field) => {
if (!currentAttributes.includes(field)) {
const newDiagnostic = new vscode.Diagnostic(
positionMap.get("geometry") || new vscode.Range(0, 0, 0, 1),
- ValidationHelper.missingRequiredAttributeQuery(field, "geometry"),
- vscode.DiagnosticSeverity.Error
+ ValidationHelper.missingRequiredAttributeQuery(
+ field,
+ "geometry",
+ ),
+ vscode.DiagnosticSeverity.Error,
);
-
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
@@ -90,5 +137,4 @@ export class GeometryObjectValidator implements SearchObjectValidator {
// }
// }
// }
-
}
diff --git a/src/commands/fts/SearchWorkbench/validators/highlightObjectValidator.ts b/src/commands/fts/SearchWorkbench/validators/highlightObjectValidator.ts
index 04142a5f..7700e045 100644
--- a/src/commands/fts/SearchWorkbench/validators/highlightObjectValidator.ts
+++ b/src/commands/fts/SearchWorkbench/validators/highlightObjectValidator.ts
@@ -1,41 +1,66 @@
-import * as vscode from 'vscode';
-import { SearchObjectValidator } from './searchValidator';
-import { JsonObject, JsonProperty } from './JsonNodes';
-import { ValidationHelper } from './validationHelper';
+import * as vscode from "vscode";
+import { SearchObjectValidator } from "./searchValidator";
+import { JsonObject, JsonProperty } from "./JsonNodes";
+import { ValidationHelper } from "./validationHelper";
export class HighlightObjectValidator implements SearchObjectValidator {
accept(key: string | null): boolean {
return key === "highlight";
}
- validate(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument, key: string): void {
+ validate(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ key: string,
+ ): void {
const counter: Map = new Map();
const positionMap = ValidationHelper.getPositionMap(document);
- jsonObject.children.forEach(child => {
+ jsonObject.children.forEach((child) => {
if (child instanceof JsonProperty) {
const propertyKey = child.key;
const propertyValue = child.value.value;
if (!["style", "fields"].includes(propertyKey)) {
const newDiagnostic = new vscode.Diagnostic(
- positionMap.get(propertyKey) || new vscode.Range(0, 0, 0, 1),
- HighlightObjectValidator.getUnexpectedAttUnderHighlight(propertyKey),
- vscode.DiagnosticSeverity.Error
- )
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ positionMap.get(propertyKey) ||
+ new vscode.Range(0, 0, 0, 1),
+ HighlightObjectValidator.getUnexpectedAttUnderHighlight(
+ propertyKey,
+ ),
+ vscode.DiagnosticSeverity.Error,
+ );
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
} else {
- counter.set(propertyKey, (counter.get(propertyKey) || 0) + 1);
+ counter.set(
+ propertyKey,
+ (counter.get(propertyKey) || 0) + 1,
+ );
}
- if (propertyKey === "style" && !["html", "ansi"].includes(propertyValue)) {
+ if (
+ propertyKey === "style" &&
+ !["html", "ansi"].includes(propertyValue)
+ ) {
const newDiagnostic = new vscode.Diagnostic(
- positionMap.get(propertyKey) || new vscode.Range(0, 0, 0, 1),
+ positionMap.get(propertyKey) ||
+ new vscode.Range(0, 0, 0, 1),
ValidationHelper.getStyleValuesErrorMessage(),
- vscode.DiagnosticSeverity.Error
- )
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ vscode.DiagnosticSeverity.Error,
+ );
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
@@ -61,5 +86,4 @@ export class HighlightObjectValidator implements SearchObjectValidator {
private static singleKeyOccurrenceMessage(key: string): string {
return `The attribute '${key}' must not appear more than once under 'highlight'`;
}
-
-}
\ No newline at end of file
+}
diff --git a/src/commands/fts/SearchWorkbench/validators/knnObjectValidator.ts b/src/commands/fts/SearchWorkbench/validators/knnObjectValidator.ts
index 199376cb..639d39f0 100644
--- a/src/commands/fts/SearchWorkbench/validators/knnObjectValidator.ts
+++ b/src/commands/fts/SearchWorkbench/validators/knnObjectValidator.ts
@@ -1,67 +1,85 @@
-
-import * as vscode from 'vscode';
-import { SearchObjectValidator } from './searchValidator';
-import { JsonObject, JsonProperty } from './JsonNodes';
-import { ValidationHelper } from './validationHelper';
+import * as vscode from "vscode";
+import { SearchObjectValidator } from "./searchValidator";
+import { JsonObject, JsonProperty } from "./JsonNodes";
+import { ValidationHelper } from "./validationHelper";
export class KnnObjectValidator implements SearchObjectValidator {
private validKnnKeys: Set;
constructor() {
- this.validKnnKeys = new Set([
- "k", "field", "vector"
- ]);
+ this.validKnnKeys = new Set(["k", "field", "vector"]);
}
accept(key: string | null): boolean {
return key === "knn";
}
- validate(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument): void {
+ validate(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ ): void {
if (!jsonObject || !(jsonObject instanceof JsonObject)) {
return;
}
-
+
const counter: Map = new Map();
const positionMap = ValidationHelper.getPositionMap(document);
-
- jsonObject.children.forEach(child => {
+
+ jsonObject.children.forEach((child) => {
if (child instanceof JsonProperty) {
- this.validateProperty(child, counter, diagnosticsList, document, positionMap);
+ this.validateProperty(
+ child,
+ counter,
+ diagnosticsList,
+ document,
+ positionMap,
+ );
}
});
-
- ['k', 'field', 'vector'].forEach(key => {
+
+ ["k", "field", "vector"].forEach((key) => {
const count = counter.get(key) || 0;
if (count !== 1) {
const message = `The key '${key}' must appear exactly once under 'knn', found ${count} occurrences`;
const newDiagnostic = new vscode.Diagnostic(
positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
message,
- vscode.DiagnosticSeverity.Error
+ vscode.DiagnosticSeverity.Error,
);
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
});
}
- private validateProperty(property: JsonProperty, counter: Map, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument, positionMap: Map): void {
+ private validateProperty(
+ property: JsonProperty,
+ counter: Map,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ positionMap: Map,
+ ): void {
const key = property.key;
if (!this.validKnnKeys.has(key)) {
- diagnosticsList.push(new vscode.Diagnostic(
- positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
- `Unexpected attribute '${key}' under 'knn' object`,
- vscode.DiagnosticSeverity.Error
- ));
+ diagnosticsList.push(
+ new vscode.Diagnostic(
+ positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
+ `Unexpected attribute '${key}' under 'knn' object`,
+ vscode.DiagnosticSeverity.Error,
+ ),
+ );
} else {
counter.set(key, (counter.get(key) || 0) + 1);
}
}
-
-
// TODO: add countcheck
// private countOccurrencesFromText(jsonText: string): Map {
// const occurrencesMap = new Map();
@@ -75,5 +93,4 @@ export class KnnObjectValidator implements SearchObjectValidator {
// return occurrencesMap;
// }
-
}
diff --git a/src/commands/fts/SearchWorkbench/validators/matchAllNoneObjectValidator.ts b/src/commands/fts/SearchWorkbench/validators/matchAllNoneObjectValidator.ts
index 437290f6..deb23f9e 100644
--- a/src/commands/fts/SearchWorkbench/validators/matchAllNoneObjectValidator.ts
+++ b/src/commands/fts/SearchWorkbench/validators/matchAllNoneObjectValidator.ts
@@ -1,31 +1,41 @@
-import * as vscode from 'vscode';
-import { SearchObjectValidator } from './searchValidator';
-import { JsonObject } from './JsonNodes';
-import { ValidationHelper } from './validationHelper';
+import * as vscode from "vscode";
+import { SearchObjectValidator } from "./searchValidator";
+import { JsonObject } from "./JsonNodes";
+import { ValidationHelper } from "./validationHelper";
export class MatchAllNoneObjectValidator implements SearchObjectValidator {
accept(key: string | null): boolean {
return key === "match_none" || key === "match_all";
}
- validate(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument, contextKey: string): void {
+ validate(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ contextKey: string,
+ ): void {
if (jsonObject.children.length > 0) {
const positionMap = ValidationHelper.getPositionMap(document);
- const range = positionMap.get(contextKey) || new vscode.Range(0, 0, 0, 1);
- const message = ValidationHelper.getMatchAllNoneNoAttributeErrorMessage(contextKey);
+ const range =
+ positionMap.get(contextKey) || new vscode.Range(0, 0, 0, 1);
+ const message =
+ ValidationHelper.getMatchAllNoneNoAttributeErrorMessage(
+ contextKey,
+ );
const newDiagnostic = new vscode.Diagnostic(
range,
message,
- vscode.DiagnosticSeverity.Error
+ vscode.DiagnosticSeverity.Error,
);
-
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
}
-
}
-
-
-
diff --git a/src/commands/fts/SearchWorkbench/validators/queryObjectValidator.ts b/src/commands/fts/SearchWorkbench/validators/queryObjectValidator.ts
index 51d05aa1..384dcfff 100644
--- a/src/commands/fts/SearchWorkbench/validators/queryObjectValidator.ts
+++ b/src/commands/fts/SearchWorkbench/validators/queryObjectValidator.ts
@@ -1,19 +1,51 @@
-import * as vscode from 'vscode';
-import { SearchObjectValidator } from './searchValidator';
-import { JsonObject, JsonProperty } from './JsonNodes';
-import { ValidationHelper } from './validationHelper';
+import * as vscode from "vscode";
+import { SearchObjectValidator } from "./searchValidator";
+import { JsonObject, JsonProperty } from "./JsonNodes";
+import { ValidationHelper } from "./validationHelper";
export class QueryObjectValidator implements SearchObjectValidator {
private validQueryKeys: Set;
constructor() {
this.validQueryKeys = new Set([
- "must", "query", "must_not", "should", "disjuncts", "conjuncts",
- "match", "field", "analyzer", "operator", "match_phrase", "bool",
- "prefix", "regexp", "term", "fuzziness", "terms", "wildcard", "min",
- "max", "inclusive_min", "inclusive_max", "start", "prefix_length",
- "end", "inclusive_start", "inclusive_end", "cidr", "location", "distance",
- "top_left", "bottom_right", "polygon_points", "geometry", "match_all", "match_none", "analyzer", "boost"
+ "must",
+ "query",
+ "must_not",
+ "should",
+ "disjuncts",
+ "conjuncts",
+ "match",
+ "field",
+ "analyzer",
+ "operator",
+ "match_phrase",
+ "bool",
+ "prefix",
+ "regexp",
+ "term",
+ "fuzziness",
+ "terms",
+ "wildcard",
+ "min",
+ "max",
+ "inclusive_min",
+ "inclusive_max",
+ "start",
+ "prefix_length",
+ "end",
+ "inclusive_start",
+ "inclusive_end",
+ "cidr",
+ "location",
+ "distance",
+ "top_left",
+ "bottom_right",
+ "polygon_points",
+ "geometry",
+ "match_all",
+ "match_none",
+ "analyzer",
+ "boost",
]);
}
@@ -21,34 +53,49 @@ export class QueryObjectValidator implements SearchObjectValidator {
return key === "query";
}
- validate(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument): void {
+ validate(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ ): void {
if (!jsonObject || !(jsonObject instanceof JsonObject)) {
return;
}
- jsonObject.children.forEach(child => {
+ jsonObject.children.forEach((child) => {
if (child instanceof JsonProperty) {
this.validateProperty(child, diagnosticsList, document);
}
});
}
- private validateProperty(property: JsonProperty, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument): void {
+ private validateProperty(
+ property: JsonProperty,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ ): void {
const key = property.key;
const positionMap = ValidationHelper.getPositionMap(document);
-
+
if (!this.validQueryKeys.has(key)) {
- const message = ValidationHelper.getUnexpectedAttributeMessage(key, "query");
+ const message = ValidationHelper.getUnexpectedAttributeMessage(
+ key,
+ "query",
+ );
const newDiagnostic = new vscode.Diagnostic(
positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
message,
- vscode.DiagnosticSeverity.Error
+ vscode.DiagnosticSeverity.Error,
);
-
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
}
-
-}
\ No newline at end of file
+}
diff --git a/src/commands/fts/SearchWorkbench/validators/queryTypeObjectValidator.ts b/src/commands/fts/SearchWorkbench/validators/queryTypeObjectValidator.ts
index bf655995..38a2c469 100644
--- a/src/commands/fts/SearchWorkbench/validators/queryTypeObjectValidator.ts
+++ b/src/commands/fts/SearchWorkbench/validators/queryTypeObjectValidator.ts
@@ -1,60 +1,102 @@
-import * as vscode from 'vscode';
-import { SearchObjectValidator } from './searchValidator';
-import { ValidationHelper } from './validationHelper';
-import { JsonObject, JsonProperty } from './JsonNodes';
-
+import * as vscode from "vscode";
+import { SearchObjectValidator } from "./searchValidator";
+import { ValidationHelper } from "./validationHelper";
+import { JsonObject, JsonProperty } from "./JsonNodes";
export class QueryTypeObjectValidator implements SearchObjectValidator {
accept(key: string): boolean {
return key === "conjuncts" || key === "disjuncts" || key === "query";
}
- validate(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument, key: string): void {
-
+ validate(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ key: string,
+ ): void {
if (!jsonObject || !(jsonObject instanceof JsonObject)) {
return;
}
const containsQuery = this.containsQuery(jsonObject);
- const properties = jsonObject.children.map(child => (child as JsonProperty).key);
+ const properties = jsonObject.children.map(
+ (child) => (child as JsonProperty).key,
+ );
const isFieldMissing = !properties.includes("field");
- const containsMatchAllNone = properties.includes("match_all") || properties.includes("match_none");
- const isBooleanQuery = properties.includes("must") || properties.includes("must_not") || properties.includes("should");
- const isCompound = this.validateCompound(jsonObject, properties, diagnosticsList, document);
+ const containsMatchAllNone =
+ properties.includes("match_all") ||
+ properties.includes("match_none");
+ const isBooleanQuery =
+ properties.includes("must") ||
+ properties.includes("must_not") ||
+ properties.includes("should");
+ const isCompound = this.validateCompound(
+ jsonObject,
+ properties,
+ diagnosticsList,
+ document,
+ );
- if (!containsMatchAllNone && !isCompound && !isBooleanQuery && !properties.includes("geometry")) {
+ if (
+ !containsMatchAllNone &&
+ !isCompound &&
+ !isBooleanQuery &&
+ !properties.includes("geometry")
+ ) {
let newDiagnostic: vscode.Diagnostic;
if (isFieldMissing && !containsQuery) {
newDiagnostic = new vscode.Diagnostic(
- ValidationHelper.getPositionMap(document).get(key) || new vscode.Range(0, 0, 0, 1),
+ ValidationHelper.getPositionMap(document).get(key) ||
+ new vscode.Range(0, 0, 0, 1),
QueryTypeObjectValidator.getMissingFieldOrQueryMessage(),
- vscode.DiagnosticSeverity.Error
+ vscode.DiagnosticSeverity.Error,
);
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
} else if (!isFieldMissing && !containsQuery) {
if (jsonObject.children.length === 1) {
newDiagnostic = new vscode.Diagnostic(
- ValidationHelper.getPositionMap(document).get(key) || new vscode.Range(0, 0, 0, 1),
+ ValidationHelper.getPositionMap(document).get(key) ||
+ new vscode.Range(0, 0, 0, 1),
QueryTypeObjectValidator.getMissingFieldOperationMessage(),
- vscode.DiagnosticSeverity.Error
+ vscode.DiagnosticSeverity.Error,
);
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
} else {
- this.validateQueryType(jsonObject, diagnosticsList, document);
+ this.validateQueryType(
+ jsonObject,
+ diagnosticsList,
+ document,
+ );
}
} else {
if (jsonObject.children.length > 1) {
newDiagnostic = new vscode.Diagnostic(
- ValidationHelper.getPositionMap(document).get(key) || new vscode.Range(0, 0, 0, 1),
+ ValidationHelper.getPositionMap(document).get(key) ||
+ new vscode.Range(0, 0, 0, 1),
QueryTypeObjectValidator.getInvalidFieldWithQueryMessage(),
- vscode.DiagnosticSeverity.Error
+ vscode.DiagnosticSeverity.Error,
);
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
@@ -66,20 +108,37 @@ export class QueryTypeObjectValidator implements SearchObjectValidator {
return "'query' doesn't support additional attributes";
}
- private validateCompound(jsonObject: JsonObject, properties: string[], diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument): boolean {
- const hasCompound = properties.includes("conjuncts") || properties.includes("disjuncts");
+ private validateCompound(
+ jsonObject: JsonObject,
+ properties: string[],
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ ): boolean {
+ const hasCompound =
+ properties.includes("conjuncts") ||
+ properties.includes("disjuncts");
const allowedCompoundAttrs = ["disjuncts", "conjuncts", "min"];
if (hasCompound) {
- jsonObject.children.forEach(child => {
- if (!(child instanceof JsonProperty) || !allowedCompoundAttrs.includes((child as JsonProperty).key)) {
+ jsonObject.children.forEach((child) => {
+ if (
+ !(child instanceof JsonProperty) ||
+ !allowedCompoundAttrs.includes((child as JsonProperty).key)
+ ) {
const newDiagnostic = new vscode.Diagnostic(
- ValidationHelper.getPositionMap(document).get((child as JsonProperty).key) || new vscode.Range(0, 0, 0, 1),
+ ValidationHelper.getPositionMap(document).get(
+ (child as JsonProperty).key,
+ ) || new vscode.Range(0, 0, 0, 1),
QueryTypeObjectValidator.getFieldNotAllowedOnCompound(),
- vscode.DiagnosticSeverity.Error
+ vscode.DiagnosticSeverity.Error,
);
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
@@ -121,7 +180,11 @@ export class QueryTypeObjectValidator implements SearchObjectValidator {
return false;
}
- private validateQueryType(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument): void {
+ private validateQueryType(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ ): void {
for (let i = 0; i < jsonObject.children.length; i++) {
const child = jsonObject.children[i];
if (!(child instanceof JsonProperty)) {
@@ -131,13 +194,16 @@ export class QueryTypeObjectValidator implements SearchObjectValidator {
const property = child as JsonProperty;
const propertyKey = property.key;
-
switch (propertyKey) {
case "match":
this.validateMatch(jsonObject, diagnosticsList, document);
return;
case "match_phrase":
- this.validateMatchPhrase(jsonObject, diagnosticsList, document);
+ this.validateMatchPhrase(
+ jsonObject,
+ diagnosticsList,
+ document,
+ );
return;
case "bool":
this.validateBoolean(jsonObject, diagnosticsList, document);
@@ -155,32 +221,55 @@ export class QueryTypeObjectValidator implements SearchObjectValidator {
this.validateTerms(jsonObject, diagnosticsList, document);
return;
case "wildcard":
- this.validateWildcard(jsonObject, diagnosticsList, document);
+ this.validateWildcard(
+ jsonObject,
+ diagnosticsList,
+ document,
+ );
return;
case "cidr":
this.validateCidr(jsonObject, diagnosticsList, document);
return;
case "inclusive_min":
case "inclusive_max":
- this.validateGenericRange(jsonObject, diagnosticsList, document);
+ this.validateGenericRange(
+ jsonObject,
+ diagnosticsList,
+ document,
+ );
return;
case "min":
case "max":
- const type = typeof property.value.value
+ const type = typeof property.value.value;
if (type === "number") {
- this.validateNumericRange(jsonObject, diagnosticsList, document);
+ this.validateNumericRange(
+ jsonObject,
+ diagnosticsList,
+ document,
+ );
return;
} else if (type === "string") {
- this.validateTermRange(jsonObject, diagnosticsList, document);
+ this.validateTermRange(
+ jsonObject,
+ diagnosticsList,
+ document,
+ );
return;
} else {
const newDiagnostic = new vscode.Diagnostic(
- ValidationHelper.getPositionMap(document).get(propertyKey) || new vscode.Range(0, 0, 0, 1),
+ ValidationHelper.getPositionMap(document).get(
+ propertyKey,
+ ) || new vscode.Range(0, 0, 0, 1),
QueryTypeObjectValidator.invalidQueryFormatMessage(),
- vscode.DiagnosticSeverity.Error
+ vscode.DiagnosticSeverity.Error,
);
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
return;
@@ -189,39 +278,58 @@ export class QueryTypeObjectValidator implements SearchObjectValidator {
case "inclusive_end":
case "start":
case "end":
- this.validateDateRange(jsonObject, diagnosticsList, document);
+ this.validateDateRange(
+ jsonObject,
+ diagnosticsList,
+ document,
+ );
return;
case "distance":
case "location":
- this.validateDistanceRadius(jsonObject, diagnosticsList, document);
+ this.validateDistanceRadius(
+ jsonObject,
+ diagnosticsList,
+ document,
+ );
return;
case "top_left":
case "bottom_right":
- this.validateRectangle(jsonObject, diagnosticsList, document);
+ this.validateRectangle(
+ jsonObject,
+ diagnosticsList,
+ document,
+ );
return;
case "polygon_points":
return;
-
}
-
}
const newDiagnostic = new vscode.Diagnostic(
- ValidationHelper.getPositionMap(document).get("query") || new vscode.Range(0, 0, 0, 1),
+ ValidationHelper.getPositionMap(document).get("query") ||
+ new vscode.Range(0, 0, 0, 1),
QueryTypeObjectValidator.invalidQueryFormatMessage(),
- vscode.DiagnosticSeverity.Error
+ vscode.DiagnosticSeverity.Error,
);
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ if (
+ !ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
-
- validateAttribute(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument, target: string, allowedFields: string[], requiredFields: string[]): void {
+ validateAttribute(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ target: string,
+ allowedFields: string[],
+ requiredFields: string[],
+ ): void {
const counter: Map = new Map();
const currentAttributes: string[] = [];
- jsonObject.children.forEach(child => {
+ jsonObject.children.forEach((child) => {
if (!(child instanceof JsonProperty)) {
return;
}
@@ -232,12 +340,22 @@ export class QueryTypeObjectValidator implements SearchObjectValidator {
if (!allowedFields.includes(propertyKey)) {
const newDiagnostic = new vscode.Diagnostic(
- ValidationHelper.getPositionMap(document).get(propertyKey) || new vscode.Range(0, 0, 0, 1),
- ValidationHelper.getUnexpectedAttributeMessageForQuery(propertyKey, target),
- vscode.DiagnosticSeverity.Error
+ ValidationHelper.getPositionMap(document).get(
+ propertyKey,
+ ) || new vscode.Range(0, 0, 0, 1),
+ ValidationHelper.getUnexpectedAttributeMessageForQuery(
+ propertyKey,
+ target,
+ ),
+ vscode.DiagnosticSeverity.Error,
);
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
} else {
@@ -247,103 +365,292 @@ export class QueryTypeObjectValidator implements SearchObjectValidator {
// this.validateMultipleOccurrences(counter, jsonObject, diagnosticsList, document);
});
- const missingFields = requiredFields.filter(field => !currentAttributes.includes(field));
+ const missingFields = requiredFields.filter(
+ (field) => !currentAttributes.includes(field),
+ );
if (currentAttributes.length > 0 && missingFields.length > 0) {
const newDiagnostic = new vscode.Diagnostic(
- ValidationHelper.getPositionMap(document).get(target) || new vscode.Range(0, 0, 0, 1),
- ValidationHelper.missingRequiredAttributeQuery(missingFields.join(", "), target),
- vscode.DiagnosticSeverity.Error
+ ValidationHelper.getPositionMap(document).get(target) ||
+ new vscode.Range(0, 0, 0, 1),
+ ValidationHelper.missingRequiredAttributeQuery(
+ missingFields.join(", "),
+ target,
+ ),
+ vscode.DiagnosticSeverity.Error,
);
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
}
- validateBoolean(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument): void {
- this.validateAttribute(jsonObject, diagnosticsList, document, "boolean", ["field", "bool", "boost"], ["field", "bool"]);
+ validateBoolean(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ ): void {
+ this.validateAttribute(
+ jsonObject,
+ diagnosticsList,
+ document,
+ "boolean",
+ ["field", "bool", "boost"],
+ ["field", "bool"],
+ );
}
- validatePrefix(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument): void {
- this.validateAttribute(jsonObject, diagnosticsList, document, "prefix", ["field", "prefix", "boost"], ["field", "prefix"]);
+ validatePrefix(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ ): void {
+ this.validateAttribute(
+ jsonObject,
+ diagnosticsList,
+ document,
+ "prefix",
+ ["field", "prefix", "boost"],
+ ["field", "prefix"],
+ );
}
- validateRegex(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument): void {
- this.validateAttribute(jsonObject, diagnosticsList, document, "regex", ["field", "regexp", "boost"], ["field", "regexp"]);
+ validateRegex(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ ): void {
+ this.validateAttribute(
+ jsonObject,
+ diagnosticsList,
+ document,
+ "regex",
+ ["field", "regexp", "boost"],
+ ["field", "regexp"],
+ );
}
- validateTerm(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument): void {
- this.validateAttribute(jsonObject, diagnosticsList, document, "term", ["field", "term", "boost", "fuzziness"], ["field", "term"]);
+ validateTerm(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ ): void {
+ this.validateAttribute(
+ jsonObject,
+ diagnosticsList,
+ document,
+ "term",
+ ["field", "term", "boost", "fuzziness"],
+ ["field", "term"],
+ );
}
- validateTerms(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument): void {
- this.validateAttribute(jsonObject, diagnosticsList, document, "terms", ["field", "terms", "boost"], ["field", "terms"]);
+ validateTerms(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ ): void {
+ this.validateAttribute(
+ jsonObject,
+ diagnosticsList,
+ document,
+ "terms",
+ ["field", "terms", "boost"],
+ ["field", "terms"],
+ );
}
- validateWildcard(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument): void {
- this.validateAttribute(jsonObject, diagnosticsList, document, "wildcard", ["field", "wildcard", "boost"], ["field", "wildcard"]);
+ validateWildcard(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ ): void {
+ this.validateAttribute(
+ jsonObject,
+ diagnosticsList,
+ document,
+ "wildcard",
+ ["field", "wildcard", "boost"],
+ ["field", "wildcard"],
+ );
}
- validateCidr(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument): void {
- this.validateAttribute(jsonObject, diagnosticsList, document, "cidr", ["field", "cidr", "boost"], ["field", "cidr"]);
+ validateCidr(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ ): void {
+ this.validateAttribute(
+ jsonObject,
+ diagnosticsList,
+ document,
+ "cidr",
+ ["field", "cidr", "boost"],
+ ["field", "cidr"],
+ );
}
- validateGenericRange(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument): void {
- const properties = jsonObject.children.map(child => (child as JsonProperty).key);
+ validateGenericRange(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ ): void {
+ const properties = jsonObject.children.map(
+ (child) => (child as JsonProperty).key,
+ );
if (!properties.includes("min") && !properties.includes("max")) {
const newDiagnostic = new vscode.Diagnostic(
- ValidationHelper.getPositionMap(document).get("min") || new vscode.Range(0, 0, 0, 1),
+ ValidationHelper.getPositionMap(document).get("min") ||
+ new vscode.Range(0, 0, 0, 1),
QueryTypeObjectValidator.minOrMaxRequiredMessage(),
- vscode.DiagnosticSeverity.Error
+ vscode.DiagnosticSeverity.Error,
);
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
}
- validateNumericRange(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument): void {
- this.validateAttribute(jsonObject, diagnosticsList, document, "numeric range", ["field", "min", "max", "inclusive_min", "inclusive_max", "boost"], ["field"]);
+ validateNumericRange(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ ): void {
+ this.validateAttribute(
+ jsonObject,
+ diagnosticsList,
+ document,
+ "numeric range",
+ ["field", "min", "max", "inclusive_min", "inclusive_max", "boost"],
+ ["field"],
+ );
}
- validateTermRange(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument): void {
- this.validateAttribute(jsonObject, diagnosticsList, document, "term range", ["field", "min", "max", "inclusive_min", "inclusive_max", "boost"], ["field"]);
+ validateTermRange(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ ): void {
+ this.validateAttribute(
+ jsonObject,
+ diagnosticsList,
+ document,
+ "term range",
+ ["field", "min", "max", "inclusive_min", "inclusive_max", "boost"],
+ ["field"],
+ );
}
- validateDistanceRadius(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument): void {
- this.validateAttribute(jsonObject, diagnosticsList, document, "distance radius", ["field", "location", "distance", "boost"], ["field", "location", "distance"]);
+ validateDistanceRadius(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ ): void {
+ this.validateAttribute(
+ jsonObject,
+ diagnosticsList,
+ document,
+ "distance radius",
+ ["field", "location", "distance", "boost"],
+ ["field", "location", "distance"],
+ );
}
- validateRectangle(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument): void {
- this.validateAttribute(jsonObject, diagnosticsList, document, "rectangle based", ["field", "top_left", "bottom_right", "boost"], ["field", "top_left", "bottom_right"]);
+ validateRectangle(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ ): void {
+ this.validateAttribute(
+ jsonObject,
+ diagnosticsList,
+ document,
+ "rectangle based",
+ ["field", "top_left", "bottom_right", "boost"],
+ ["field", "top_left", "bottom_right"],
+ );
}
- validateDateRange(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument): void {
- this.validateAttribute(jsonObject, diagnosticsList, document, "date range", ["field", "start", "end", "inclusive_start", "inclusive_end", "boost"], ["field"]);
+ validateDateRange(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ ): void {
+ this.validateAttribute(
+ jsonObject,
+ diagnosticsList,
+ document,
+ "date range",
+ [
+ "field",
+ "start",
+ "end",
+ "inclusive_start",
+ "inclusive_end",
+ "boost",
+ ],
+ ["field"],
+ );
- const properties = jsonObject.children.map(child => (child as JsonProperty).key);
+ const properties = jsonObject.children.map(
+ (child) => (child as JsonProperty).key,
+ );
if (!properties.includes("start") && !properties.includes("end")) {
const newDiagnostic = new vscode.Diagnostic(
- ValidationHelper.getPositionMap(document).get("start") || new vscode.Range(0, 0, 0, 1),
+ ValidationHelper.getPositionMap(document).get("start") ||
+ new vscode.Range(0, 0, 0, 1),
QueryTypeObjectValidator.startOrEndRequiredMessage(),
- vscode.DiagnosticSeverity.Error
+ vscode.DiagnosticSeverity.Error,
);
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
}
- validateMatch(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument): void {
- this.validateAttribute(jsonObject, diagnosticsList, document, "match", ["field", "match", "analyzer", "operator", "fuzziness", "boost", "prefix_length"], ["field", "match"]);
+ validateMatch(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ ): void {
+ this.validateAttribute(
+ jsonObject,
+ diagnosticsList,
+ document,
+ "match",
+ [
+ "field",
+ "match",
+ "analyzer",
+ "operator",
+ "fuzziness",
+ "boost",
+ "prefix_length",
+ ],
+ ["field", "match"],
+ );
let matchValue: string | null = null;
let isOperatorPresent = false;
- jsonObject.children.forEach(child => {
+ jsonObject.children.forEach((child) => {
if (!(child instanceof JsonProperty)) {
return;
}
@@ -351,31 +658,61 @@ export class QueryTypeObjectValidator implements SearchObjectValidator {
const property = child as JsonProperty;
const propertyKey = property.key;
- if (propertyKey === "match" && typeof property.value.value == "string") {
+ if (
+ propertyKey === "match" &&
+ typeof property.value.value == "string"
+ ) {
matchValue = property.value.value;
} else if (propertyKey === "operator") {
isOperatorPresent = true;
this.validateOperatorValue(diagnosticsList, property, document);
}
});
- if (matchValue !== null && (matchValue as string).includes(" ") && !isOperatorPresent) {
+ if (
+ matchValue !== null &&
+ (matchValue as string).includes(" ") &&
+ !isOperatorPresent
+ ) {
const newDiagnostic = new vscode.Diagnostic(
- ValidationHelper.getPositionMap(document).get("match") || new vscode.Range(0, 0, 0, 1),
+ ValidationHelper.getPositionMap(document).get("match") ||
+ new vscode.Range(0, 0, 0, 1),
QueryTypeObjectValidator.matchWithSpaceMessage(),
- vscode.DiagnosticSeverity.Error
+ vscode.DiagnosticSeverity.Error,
);
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
}
+ validateMatchPhrase(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ ): void {
+ this.validateAttribute(
+ jsonObject,
+ diagnosticsList,
+ document,
+ "match phrase",
+ [
+ "field",
+ "match_phrase",
+ "analyzer",
+ "operator",
+ "fuzziness",
+ "boost",
+ ],
+ ["field", "match_phrase"],
+ );
- validateMatchPhrase(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument): void {
- this.validateAttribute(jsonObject, diagnosticsList, document, "match phrase", ["field", "match_phrase", "analyzer", "operator", "fuzziness", "boost"], ["field", "match_phrase"]);
-
- jsonObject.children.forEach(child => {
+ jsonObject.children.forEach((child) => {
if (!(child instanceof JsonProperty)) {
return;
}
@@ -387,15 +724,25 @@ export class QueryTypeObjectValidator implements SearchObjectValidator {
});
}
- private validateOperatorValue(diagnosticsList: vscode.Diagnostic[], property: JsonProperty, document: vscode.TextDocument): void {
+ private validateOperatorValue(
+ diagnosticsList: vscode.Diagnostic[],
+ property: JsonProperty,
+ document: vscode.TextDocument,
+ ): void {
if (property.value.value !== "or" && property.value.value !== "and") {
const newDiagnostic = new vscode.Diagnostic(
- ValidationHelper.getPositionMap(document).get(property.key) || new vscode.Range(0, 0, 0, 1),
+ ValidationHelper.getPositionMap(document).get(property.key) ||
+ new vscode.Range(0, 0, 0, 1),
QueryTypeObjectValidator.invalidOperatorMessage(),
- vscode.DiagnosticSeverity.Error
+ vscode.DiagnosticSeverity.Error,
);
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
@@ -420,7 +767,6 @@ export class QueryTypeObjectValidator implements SearchObjectValidator {
return "'start' or 'end' is required for this query type";
}
-
// TODO: add duplicate check
// private validateMultipleOccurrences(counter: Map, jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument): void {
// counter.forEach((value, key) => {
@@ -433,4 +779,4 @@ export class QueryTypeObjectValidator implements SearchObjectValidator {
// }
// });
// }
-}
\ No newline at end of file
+}
diff --git a/src/commands/fts/SearchWorkbench/validators/rootObjectValidator.ts b/src/commands/fts/SearchWorkbench/validators/rootObjectValidator.ts
index 393a8f9e..4494c358 100644
--- a/src/commands/fts/SearchWorkbench/validators/rootObjectValidator.ts
+++ b/src/commands/fts/SearchWorkbench/validators/rootObjectValidator.ts
@@ -1,77 +1,117 @@
-import * as vscode from 'vscode';
-import { SearchObjectValidator } from './searchValidator';
-import { JsonObject,JsonProperty } from './JsonNodes';
-import { ValidationHelper } from './validationHelper';
+import * as vscode from "vscode";
+import { SearchObjectValidator } from "./searchValidator";
+import { JsonObject, JsonProperty } from "./JsonNodes";
+import { ValidationHelper } from "./validationHelper";
export class RootObjectValidator implements SearchObjectValidator {
private readonly validRootKeys: Set = new Set([
- "query", "knn", "ctl", "size", "limit", "from", "offset",
- "highlight", "fields", "facets", "explain", "sort",
- "includeLocations", "score", "search_after", "search_before", "collections"
+ "query",
+ "knn",
+ "ctl",
+ "size",
+ "limit",
+ "from",
+ "offset",
+ "highlight",
+ "fields",
+ "facets",
+ "explain",
+ "sort",
+ "includeLocations",
+ "score",
+ "search_after",
+ "search_before",
+ "collections",
]);
accept(key: string | null): boolean {
return key === null;
}
- validate(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument): void {
+ validate(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ ): void {
if (!jsonObject || !jsonObject.children) {
const emptyError = new vscode.Diagnostic(
new vscode.Range(0, 0, 0, 1),
"Your search query can't be empty",
- vscode.DiagnosticSeverity.Error
+ vscode.DiagnosticSeverity.Error,
);
- if (!ValidationHelper.diagnosticExists(diagnosticsList, emptyError)) {
+ if (
+ !ValidationHelper.diagnosticExists(diagnosticsList, emptyError)
+ ) {
diagnosticsList.push(emptyError);
}
return;
}
-
+
const counter: Map = new Map();
const positionMap = ValidationHelper.getPositionMap(document);
-
- jsonObject.children.forEach(child => {
- if (child instanceof JsonProperty && this.validRootKeys.has(child.key)) {
+
+ jsonObject.children.forEach((child) => {
+ if (
+ child instanceof JsonProperty &&
+ this.validRootKeys.has(child.key)
+ ) {
counter.set(child.key, (counter.get(child.key) || 0) + 1);
} else if (child instanceof JsonProperty) {
const newDiagnostic = new vscode.Diagnostic(
positionMap.get(child.key) || new vscode.Range(0, 0, 0, 1),
- ValidationHelper.getUnexecptedAttributeAtTopLevel(child.key),
- vscode.DiagnosticSeverity.Error
+ ValidationHelper.getUnexecptedAttributeAtTopLevel(
+ child.key,
+ ),
+ vscode.DiagnosticSeverity.Error,
);
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
});
-
+
// Ensure `query` or `knn` are present
- if ((counter.get("query") || 0) === 0 && (counter.get("knn") || 0) === 0) {
+ if (
+ (counter.get("query") || 0) === 0 &&
+ (counter.get("knn") || 0) === 0
+ ) {
const requiredKeyError = new vscode.Diagnostic(
new vscode.Range(0, 0, 0, 1),
ValidationHelper.getRequiredQueryKnnErrorMessage(),
- vscode.DiagnosticSeverity.Error
+ vscode.DiagnosticSeverity.Error,
);
- if (!ValidationHelper.diagnosticExists(diagnosticsList, requiredKeyError)) {
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ requiredKeyError,
+ )
+ ) {
diagnosticsList.push(requiredKeyError);
}
}
-
+
//TODO: Ensure only a single occurrence of each root key
for (const [key, count] of counter.entries()) {
if (count > 1) {
const multipleOccurrenceError = new vscode.Diagnostic(
positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
`The attribute '${key}' must appear once at the top level, found ${count} occurrences`,
- vscode.DiagnosticSeverity.Error
+ vscode.DiagnosticSeverity.Error,
);
- if (!ValidationHelper.diagnosticExists(diagnosticsList, multipleOccurrenceError)) {
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ multipleOccurrenceError,
+ )
+ ) {
diagnosticsList.push(multipleOccurrenceError);
}
}
}
}
-
-
}
-
diff --git a/src/commands/fts/SearchWorkbench/validators/searchValidator.ts b/src/commands/fts/SearchWorkbench/validators/searchValidator.ts
index 2a352731..8be564f5 100644
--- a/src/commands/fts/SearchWorkbench/validators/searchValidator.ts
+++ b/src/commands/fts/SearchWorkbench/validators/searchValidator.ts
@@ -1,7 +1,12 @@
-import * as vscode from 'vscode';
-import { JsonObject } from './JsonNodes';
+import * as vscode from "vscode";
+import { JsonObject } from "./JsonNodes";
export interface SearchObjectValidator {
accept(key: string | null): boolean;
- validate(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument, key:string | null): void;
+ validate(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ key: string | null,
+ ): void;
}
diff --git a/src/commands/fts/SearchWorkbench/validators/shapeObjectValidator.ts b/src/commands/fts/SearchWorkbench/validators/shapeObjectValidator.ts
index 84e6a6e7..4489fc06 100644
--- a/src/commands/fts/SearchWorkbench/validators/shapeObjectValidator.ts
+++ b/src/commands/fts/SearchWorkbench/validators/shapeObjectValidator.ts
@@ -1,24 +1,28 @@
-import * as vscode from 'vscode';
-import { SearchObjectValidator } from './searchValidator';
-import { JsonArray, JsonObject, JsonProperty } from './JsonNodes';
-import { ValidationHelper } from './validationHelper';
-
+import * as vscode from "vscode";
+import { SearchObjectValidator } from "./searchValidator";
+import { JsonArray, JsonObject, JsonProperty } from "./JsonNodes";
+import { ValidationHelper } from "./validationHelper";
export class ShapeObjectValidator implements SearchObjectValidator {
accept(key: string | null): boolean {
return key === "shape" || key === "geometries";
}
- validate(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument, key: string): void {
+ validate(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ key: string,
+ ): void {
const target = "shape";
- let requiredFields = ['type'];
+ let requiredFields = ["type"];
const counter: Map = new Map();
const currentAttributes: string[] = [];
const positionMap = ValidationHelper.getPositionMap(document);
let typeValue: string | null = null;
let coordinates: JsonProperty | null = null;
- jsonObject.children.forEach(child => {
+ jsonObject.children.forEach((child) => {
if (!(child instanceof JsonProperty)) {
return;
}
@@ -27,19 +31,28 @@ export class ShapeObjectValidator implements SearchObjectValidator {
const propertyValue = child.value;
currentAttributes.push(propertyKey);
-
if (propertyKey === "coordinates") {
coordinates = child;
}
- if (!["type", "coordinates", "geometries", "radius"].includes(propertyKey)) {
+ if (
+ !["type", "coordinates", "geometries", "radius"].includes(
+ propertyKey,
+ )
+ ) {
const newDiagnostic = new vscode.Diagnostic(
- positionMap.get(propertyKey) || new vscode.Range(0, 0, 0, 1),
+ positionMap.get(propertyKey) ||
+ new vscode.Range(0, 0, 0, 1),
`Unexpected attribute '${propertyKey}' for query '${target}'`,
- vscode.DiagnosticSeverity.Error
+ vscode.DiagnosticSeverity.Error,
);
-
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
} else {
@@ -47,128 +60,255 @@ export class ShapeObjectValidator implements SearchObjectValidator {
if (propertyKey === "type") {
typeValue = propertyValue.value;
- this.validateType(typeValue, propertyValue, diagnosticsList, positionMap);
+ this.validateType(
+ typeValue,
+ propertyValue,
+ diagnosticsList,
+ positionMap,
+ );
}
}
// this.validateMultipleOccurrences(counter, jsonObject, diagnosticsList, positionMap);
});
- requiredFields = requiredFields.filter(item => !currentAttributes.includes(item));
- requiredFields.forEach(field => {
- if (!currentAttributes.includes(field) && currentAttributes.length !== 0 && requiredFields.length !== 0) {
+ requiredFields = requiredFields.filter(
+ (item) => !currentAttributes.includes(item),
+ );
+ requiredFields.forEach((field) => {
+ if (
+ !currentAttributes.includes(field) &&
+ currentAttributes.length !== 0 &&
+ requiredFields.length !== 0
+ ) {
const newDiagnostic = new vscode.Diagnostic(
positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
ValidationHelper.missingRequiredAttributeQuery(field, key),
- vscode.DiagnosticSeverity.Error
+ vscode.DiagnosticSeverity.Error,
);
-
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
});
if (typeValue === "Circle") {
- this.validateCircle(currentAttributes, diagnosticsList, positionMap, key);
+ this.validateCircle(
+ currentAttributes,
+ diagnosticsList,
+ positionMap,
+ key,
+ );
} else if (typeValue === "GeometryCollection") {
- this.validateGeometryCollection(currentAttributes, diagnosticsList, positionMap, key);
+ this.validateGeometryCollection(
+ currentAttributes,
+ diagnosticsList,
+ positionMap,
+ key,
+ );
} else {
if (typeValue) {
- this.validateCoordinates(typeValue, currentAttributes, coordinates, diagnosticsList, positionMap);
+ this.validateCoordinates(
+ typeValue,
+ currentAttributes,
+ coordinates,
+ diagnosticsList,
+ positionMap,
+ );
}
}
- if (typeValue && coordinates != null && (["LineString", "Polygon", "MultiLineString", "MultiPolygon", "Envelope", "MultiPoint"].includes(typeValue))) {
- this.validateCoordinatesStructure(coordinates, typeValue, diagnosticsList, document, key)
+ if (
+ typeValue &&
+ coordinates != null &&
+ [
+ "LineString",
+ "Polygon",
+ "MultiLineString",
+ "MultiPolygon",
+ "Envelope",
+ "MultiPoint",
+ ].includes(typeValue)
+ ) {
+ this.validateCoordinatesStructure(
+ coordinates,
+ typeValue,
+ diagnosticsList,
+ document,
+ key,
+ );
}
}
- private validateType(typeValue: string | null, property: JsonProperty, diagnosticsList: vscode.Diagnostic[], positionMap: any): void {
+ private validateType(
+ typeValue: string | null,
+ property: JsonProperty,
+ diagnosticsList: vscode.Diagnostic[],
+ positionMap: any,
+ ): void {
if (typeValue !== null) {
const validTypes = [
- "Point", "Circle", "Envelope", "LineString", "MultiPoint",
- "MultiLineString", "MultiPolygon", "GeometryCollection", "Polygon"
+ "Point",
+ "Circle",
+ "Envelope",
+ "LineString",
+ "MultiPoint",
+ "MultiLineString",
+ "MultiPolygon",
+ "GeometryCollection",
+ "Polygon",
];
-
+
if (!validTypes.includes(typeValue)) {
const newDiagnostic = new vscode.Diagnostic(
- positionMap.get(property.key) || new vscode.Range(0, 0, 0, 1),
+ positionMap.get(property.key) ||
+ new vscode.Range(0, 0, 0, 1),
`Invalid type '${typeValue}'`,
- vscode.DiagnosticSeverity.Error
+ vscode.DiagnosticSeverity.Error,
);
-
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
}
}
- private validateCoordinatesStructure(coordinates: JsonArray, type: string, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument, key: string): void {
+ private validateCoordinatesStructure(
+ coordinates: JsonArray,
+ type: string,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ key: string,
+ ): void {
if (type && coordinates instanceof JsonArray) {
- if (!coordinates.children.every(child => child instanceof JsonArray)) {
+ if (
+ !coordinates.children.every(
+ (child) => child instanceof JsonArray,
+ )
+ ) {
const positionMap = ValidationHelper.getPositionMap(document);
const newDiagnostic = new vscode.Diagnostic(
positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
`'${type}' in '${key}' requires 'coordinates' to be an array of arrays.`,
- vscode.DiagnosticSeverity.Error
+ vscode.DiagnosticSeverity.Error,
);
-
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
}
}
- private validateCircle(currentAttributes: string[], diagnosticsList: vscode.Diagnostic[], positionMap: any, key: string): void {
+ private validateCircle(
+ currentAttributes: string[],
+ diagnosticsList: vscode.Diagnostic[],
+ positionMap: any,
+ key: string,
+ ): void {
if (!currentAttributes.includes("radius")) {
const newDiagnostic = new vscode.Diagnostic(
positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
ValidationHelper.missingRequiredAttributeQuery("radius", key),
- vscode.DiagnosticSeverity.Error
+ vscode.DiagnosticSeverity.Error,
);
-
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
if (!currentAttributes.includes("coordinates")) {
const newDiagnostic = new vscode.Diagnostic(
positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
- ValidationHelper.missingRequiredAttributeQuery("coordinates", key),
- vscode.DiagnosticSeverity.Error
+ ValidationHelper.missingRequiredAttributeQuery(
+ "coordinates",
+ key,
+ ),
+ vscode.DiagnosticSeverity.Error,
);
-
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
}
- private validateGeometryCollection(currentAttributes: string[], diagnosticsList: vscode.Diagnostic[], positionMap: any, key: string): void {
+ private validateGeometryCollection(
+ currentAttributes: string[],
+ diagnosticsList: vscode.Diagnostic[],
+ positionMap: any,
+ key: string,
+ ): void {
if (!currentAttributes.includes("geometries")) {
const newDiagnostic = new vscode.Diagnostic(
positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
- ValidationHelper.missingRequiredAttributeQuery("geometries", key),
- vscode.DiagnosticSeverity.Error
+ ValidationHelper.missingRequiredAttributeQuery(
+ "geometries",
+ key,
+ ),
+ vscode.DiagnosticSeverity.Error,
);
-
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
}
- private validateCoordinates(typeValue: string | null, currentAttributes: string[], coordinates: JsonProperty | null, diagnosticsList: vscode.Diagnostic[], positionMap: any): void {
+ private validateCoordinates(
+ typeValue: string | null,
+ currentAttributes: string[],
+ coordinates: JsonProperty | null,
+ diagnosticsList: vscode.Diagnostic[],
+ positionMap: any,
+ ): void {
if (!currentAttributes.includes("coordinates")) {
const newDiagnostic = new vscode.Diagnostic(
positionMap.get("type") || new vscode.Range(0, 0, 0, 1),
- ValidationHelper.missingRequiredAttributeQuery("coordinates", "shape"),
- vscode.DiagnosticSeverity.Error
+ ValidationHelper.missingRequiredAttributeQuery(
+ "coordinates",
+ "shape",
+ ),
+ vscode.DiagnosticSeverity.Error,
);
-
- if (!ValidationHelper.diagnosticExists(diagnosticsList, newDiagnostic)) {
+
+ if (
+ !ValidationHelper.diagnosticExists(
+ diagnosticsList,
+ newDiagnostic,
+ )
+ ) {
diagnosticsList.push(newDiagnostic);
}
}
@@ -186,5 +326,4 @@ export class ShapeObjectValidator implements SearchObjectValidator {
// }
// });
// }
-
}
diff --git a/src/commands/fts/SearchWorkbench/validators/validationHelper.ts b/src/commands/fts/SearchWorkbench/validators/validationHelper.ts
index 8c0b54dd..1133db80 100644
--- a/src/commands/fts/SearchWorkbench/validators/validationHelper.ts
+++ b/src/commands/fts/SearchWorkbench/validators/validationHelper.ts
@@ -1,8 +1,10 @@
-import * as vscode from 'vscode';
+import * as vscode from "vscode";
export class ValidationHelper {
// Generates a map of JSON keys to their positions in the document
- static getPositionMap(document: vscode.TextDocument): Map {
+ static getPositionMap(
+ document: vscode.TextDocument,
+ ): Map {
const positionMap = new Map();
const regex = /"(\w+)"\s*:/g;
const text = document.getText();
@@ -16,26 +18,41 @@ export class ValidationHelper {
return positionMap;
}
- static diagnosticExists(diagnosticsList: vscode.Diagnostic[], newDiagnostic: any) {
- return diagnosticsList.some(diagnostic =>
- diagnostic.message === newDiagnostic.message
+ static diagnosticExists(
+ diagnosticsList: vscode.Diagnostic[],
+ newDiagnostic: any,
+ ) {
+ return diagnosticsList.some(
+ (diagnostic) => diagnostic.message === newDiagnostic.message,
);
}
-
- static getUnexpectedAttributeMessage(attribute: string, context: string): string {
+ static getUnexpectedAttributeMessage(
+ attribute: string,
+ context: string,
+ ): string {
return `Unexpected attribute '${attribute}' under '${context}' object`;
}
- static getUnexpectedAttributeMessageForQuery(attribute: string, context: string): string {
+ static getUnexpectedAttributeMessageForQuery(
+ attribute: string,
+ context: string,
+ ): string {
return `Unexpected attribute '${attribute}' for a '${context}' query`;
}
- static missingRequiredAttributeQuery(missingField: string, target: string): string {
- return `Missing required attribute(s) '${missingField}' for query ${target}`
+ static missingRequiredAttributeQuery(
+ missingField: string,
+ target: string,
+ ): string {
+ return `Missing required attribute(s) '${missingField}' for query ${target}`;
}
- static getExpectedArrayLengthMessage(key: string, expectedLength: number, actualLength: number): string {
+ static getExpectedArrayLengthMessage(
+ key: string,
+ expectedLength: number,
+ actualLength: number,
+ ): string {
return `Expected an array of length ${expectedLength} for '${key}', got length ${actualLength}`;
}
@@ -44,22 +61,36 @@ export class ValidationHelper {
}
static getExpectedLatLonMessage(target: string): string {
- return `Each item of the array must be in the format 'lat,lon' for '${target}]'`
+ return `Each item of the array must be in the format 'lat,lon' for '${target}]'`;
}
- static getExpectedArrayOrObjectMessage(key: string, actualType: string): string {
+ static getExpectedArrayOrObjectMessage(
+ key: string,
+ actualType: string,
+ ): string {
return `Expected an array or object for '${key}', found type ${actualType}`;
}
- static getInvalidDistanceUnitErrorMessage(key: string, validUnits: string[]): string {
- return `Invalid distance unit for '${key}'. Expected units: ${validUnits.join(", ")}`;
+ static getInvalidDistanceUnitErrorMessage(
+ key: string,
+ validUnits: string[],
+ ): string {
+ return `Invalid distance unit for '${key}'. Expected units: ${validUnits.join(
+ ", ",
+ )}`;
}
- static getMissingAttributeMessage(attribute: string, context: string): string {
+ static getMissingAttributeMessage(
+ attribute: string,
+ context: string,
+ ): string {
return `The attribute '${attribute}' is required under '${context}' object and must occur exactly once`;
}
- static getSingleOccurrenceMessage(attribute: string, context: string): string {
+ static getSingleOccurrenceMessage(
+ attribute: string,
+ context: string,
+ ): string {
return `The attribute '${attribute}' must not appear more than once under '${context}'`;
}
@@ -83,7 +114,10 @@ export class ValidationHelper {
return "The value of the 'level' attribute must be 'at_plus' or 'not_bounded'";
}
- static getExpectedDataTypeErrorMessage(expectedType: string, key: string): string {
+ static getExpectedDataTypeErrorMessage(
+ expectedType: string,
+ key: string,
+ ): string {
return `Expected ${expectedType} for property '${key}`;
}
@@ -100,11 +134,10 @@ export class ValidationHelper {
}
static getUnexecptedAttributeAtTopLevel(attribute: string): string {
- return `Unexpected attribute ${attribute} at the top level`
+ return `Unexpected attribute ${attribute} at the top level`;
}
static getRequiredQueryKnnErrorMessage(): string {
- return "'query' and/or 'knn' attributes are expected at the top level"
+ return "'query' and/or 'knn' attributes are expected at the top level";
}
}
-
diff --git a/src/commands/fts/SearchWorkbench/validators/validationUtil.ts b/src/commands/fts/SearchWorkbench/validators/validationUtil.ts
index fb4fd4df..e3d850b7 100644
--- a/src/commands/fts/SearchWorkbench/validators/validationUtil.ts
+++ b/src/commands/fts/SearchWorkbench/validators/validationUtil.ts
@@ -1,181 +1,240 @@
-import * as vscode from 'vscode';
-import { SearchObjectValidator } from './searchValidator';
-import { RootObjectValidator } from './rootObjectValidator';
-import { QueryObjectValidator } from './queryObjectValidator';
-import { QueryTypeObjectValidator } from './queryTypeObjectValidator';
-import { MatchAllNoneObjectValidator } from './matchAllNoneObjectValidator'
-import { KnnObjectValidator } from './knnObjectValidator'
-import { BooleanObjectValidator } from './booleanObjectValidator'
-import { CtlConsistencyObjectValidator } from './ctlConsistencyObjectValidator'
-import { CTLObjectValidator } from './ctlObjectValidator'
-import { HighlightObjectValidator } from './highlightObjectValidator'
-import { GeometryObjectValidator } from './geometryObjectValidator'
-import { ShapeObjectValidator } from './shapeObjectValidator'
-import { JsonObject, JsonArray, JsonProperty, JsonNode } from './JsonNodes';
-import { ValidationHelper } from './validationHelper';
-import { logger } from '../../../../logger/logger';
-
-
+import * as vscode from "vscode";
+import { SearchObjectValidator } from "./searchValidator";
+import { RootObjectValidator } from "./rootObjectValidator";
+import { QueryObjectValidator } from "./queryObjectValidator";
+import { QueryTypeObjectValidator } from "./queryTypeObjectValidator";
+import { MatchAllNoneObjectValidator } from "./matchAllNoneObjectValidator";
+import { KnnObjectValidator } from "./knnObjectValidator";
+import { BooleanObjectValidator } from "./booleanObjectValidator";
+import { CtlConsistencyObjectValidator } from "./ctlConsistencyObjectValidator";
+import { CTLObjectValidator } from "./ctlObjectValidator";
+import { HighlightObjectValidator } from "./highlightObjectValidator";
+import { GeometryObjectValidator } from "./geometryObjectValidator";
+import { ShapeObjectValidator } from "./shapeObjectValidator";
+import { JsonObject, JsonArray, JsonProperty, JsonNode } from "./JsonNodes";
+import { ValidationHelper } from "./validationHelper";
+import { logger } from "../../../../logger/logger";
interface ValidationRule {
type: string;
isTopLevel?: boolean;
}
-
const PROPERTY_RULES: Record = {
- "ctl":{type:"json"},
- "highlight":{type:"json"},
- "facets":{type:"json"},
- "knn": { type: "array" },
- "size": { type: "number" },
- "from": { type: "number" },
- "fields": { type: "array" },
- "explain": { type: "boolean" },
- "sort": { type: "array" },
- "includeLocations": { type: "boolean" },
- "score": { type: "string" },
- "search_after": { type: "array" },
- "search_before": { type: "array" },
- "limit": { type: "number" },
- "offset": { type: "number" },
- "collections": { type: "array" },
- "consistency": { type: "json" },
- "vectors": { type: "json" },
- "match_all": { type: "json" },
- "match_none": { type: "json" },
- "must": { type: "json" },
- "must_not": { type: "json" },
- "should": { type: "json" },
- "shape": { type: "json" },
- "field": { type: "string" },
- "vector": { type: "array" },
- "timeout": { type: "number" },
- "k": { type: "number" },
- "style": { type: "string" },
- "results": { type: "string" },
- "level": { type: "string" },
- "match": { type: "string" },
- "analyzer": { type: "string" },
- "operator": { type: "string" },
- "boost": { type: "number" },
- "fuzziness": { type: "number" },
- "prefix_length": { type: "number" },
- "match_phrase": { type: "string" },
- "bool": { type: "boolean" },
- "prefix": { type: "string" },
- "term": { type: "string" },
- "regexp": { type: "string" },
- "terms": { type: "array" },
- "wildcard": { type: "string" },
- "cidr": { type: "string" },
- "inclusive_min": { type: "boolean" },
- "inclusive_max": { type: "boolean" },
- "inclusive_start": { type: "boolean" },
- "inclusive_end": { type: "boolean" },
- "start": { type: "string" },
- "end": { type: "string" },
- "conjuncts": { type: "array" },
- "disjuncts": { type: "array" },
- "relation": { type: "string" },
- "type": { type: "string" },
- "coordinates": { type: "array" },
- "radius": { type: "string" },
- "geometries": { type: "array" },
- "geometry": { type: "json" }
+ ctl: { type: "json" },
+ highlight: { type: "json" },
+ facets: { type: "json" },
+ knn: { type: "array" },
+ size: { type: "number" },
+ from: { type: "number" },
+ fields: { type: "array" },
+ explain: { type: "boolean" },
+ sort: { type: "array" },
+ includeLocations: { type: "boolean" },
+ score: { type: "string" },
+ search_after: { type: "array" },
+ search_before: { type: "array" },
+ limit: { type: "number" },
+ offset: { type: "number" },
+ collections: { type: "array" },
+ consistency: { type: "json" },
+ vectors: { type: "json" },
+ match_all: { type: "json" },
+ match_none: { type: "json" },
+ must: { type: "json" },
+ must_not: { type: "json" },
+ should: { type: "json" },
+ shape: { type: "json" },
+ field: { type: "string" },
+ vector: { type: "array" },
+ timeout: { type: "number" },
+ k: { type: "number" },
+ style: { type: "string" },
+ results: { type: "string" },
+ level: { type: "string" },
+ match: { type: "string" },
+ analyzer: { type: "string" },
+ operator: { type: "string" },
+ boost: { type: "number" },
+ fuzziness: { type: "number" },
+ prefix_length: { type: "number" },
+ match_phrase: { type: "string" },
+ bool: { type: "boolean" },
+ prefix: { type: "string" },
+ term: { type: "string" },
+ regexp: { type: "string" },
+ terms: { type: "array" },
+ wildcard: { type: "string" },
+ cidr: { type: "string" },
+ inclusive_min: { type: "boolean" },
+ inclusive_max: { type: "boolean" },
+ inclusive_start: { type: "boolean" },
+ inclusive_end: { type: "boolean" },
+ start: { type: "string" },
+ end: { type: "string" },
+ conjuncts: { type: "array" },
+ disjuncts: { type: "array" },
+ relation: { type: "string" },
+ type: { type: "string" },
+ coordinates: { type: "array" },
+ radius: { type: "string" },
+ geometries: { type: "array" },
+ geometry: { type: "json" },
};
-
-const validators: SearchObjectValidator[] = [new RootObjectValidator, new QueryObjectValidator(), new GeometryObjectValidator(), new ShapeObjectValidator(), new KnnObjectValidator(), new BooleanObjectValidator(), new CtlConsistencyObjectValidator(), new CTLObjectValidator(), new HighlightObjectValidator(), new MatchAllNoneObjectValidator(), new QueryTypeObjectValidator()];
-
-export function validateDocument(document: vscode.TextDocument | undefined, diagnostics: vscode.DiagnosticCollection) {
- if (!document){
- return
+const validators: SearchObjectValidator[] = [
+ new RootObjectValidator(),
+ new QueryObjectValidator(),
+ new GeometryObjectValidator(),
+ new ShapeObjectValidator(),
+ new KnnObjectValidator(),
+ new BooleanObjectValidator(),
+ new CtlConsistencyObjectValidator(),
+ new CTLObjectValidator(),
+ new HighlightObjectValidator(),
+ new MatchAllNoneObjectValidator(),
+ new QueryTypeObjectValidator(),
+];
+
+export function validateDocument(
+ document: vscode.TextDocument | undefined,
+ diagnostics: vscode.DiagnosticCollection,
+) {
+ if (!document) {
+ return;
}
const diagnosticsList: vscode.Diagnostic[] = [];
const jsonContent = document.getText();
try {
-
const rawJsonObject = JSON.parse(jsonContent);
- const jsonObject = buildJsonStructure(rawJsonObject, null) as JsonObject;
+ const jsonObject = buildJsonStructure(
+ rawJsonObject,
+ null,
+ ) as JsonObject;
// Visit the Json Object
visitJsonObject(jsonObject, diagnosticsList, document);
-
} catch (error) {
- logger.error("Invalid Json Error: "+ error)
- diagnosticsList.push(new vscode.Diagnostic(new vscode.Range(0, 0, 0, 1), `Invalid JSON: ${error}`,vscode.DiagnosticSeverity.Error));
+ logger.error("Invalid Json Error: " + error);
+ diagnosticsList.push(
+ new vscode.Diagnostic(
+ new vscode.Range(0, 0, 0, 1),
+ `Invalid JSON: ${error}`,
+ vscode.DiagnosticSeverity.Error,
+ ),
+ );
}
diagnostics.set(document.uri, diagnosticsList);
}
-
-function buildJsonStructure(data: any, parent: JsonNode | null = null): JsonNode {
+function buildJsonStructure(
+ data: any,
+ parent: JsonNode | null = null,
+): JsonNode {
if (Array.isArray(data)) {
const jsonArray = new JsonArray(parent);
- data.forEach(item => {
+ data.forEach((item) => {
jsonArray.children.push(buildJsonStructure(item, jsonArray));
});
return jsonArray;
- } else if (typeof data === 'object' && data !== null) {
+ } else if (typeof data === "object" && data !== null) {
const jsonObject = new JsonObject(parent);
Object.entries(data).forEach(([key, value]) => {
const childNode = buildJsonStructure(value, jsonObject);
// Only create JsonProperty for each key-value pair
- jsonObject.children.push(new JsonProperty(key, childNode, jsonObject));
+ jsonObject.children.push(
+ new JsonProperty(key, childNode, jsonObject),
+ );
});
return jsonObject;
} else {
- return new JsonProperty('leaf', data, parent);
+ return new JsonProperty("leaf", data, parent);
}
}
-
-
// Visitor function for JsonObject
-function visitJsonObject(jsonObject: JsonObject, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument, inheritedKey: string | null = null): void {
+function visitJsonObject(
+ jsonObject: JsonObject,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ inheritedKey: string | null = null,
+): void {
let contextKey = inheritedKey || determineContextKey(jsonObject);
-
- validators.forEach(validator => {
+ validators.forEach((validator) => {
if (validator.accept(contextKey)) {
- validator.validate(jsonObject, diagnosticsList, document, contextKey);
+ validator.validate(
+ jsonObject,
+ diagnosticsList,
+ document,
+ contextKey,
+ );
}
});
- jsonObject.children.forEach(child => {
+ jsonObject.children.forEach((child) => {
visitNode(child, diagnosticsList, document, contextKey);
});
}
-function visitJsonArray(jsonArray: JsonArray, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument, inheritedKey: string | null = null): void {
- jsonArray.children.forEach(child => {
+function visitJsonArray(
+ jsonArray: JsonArray,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ inheritedKey: string | null = null,
+): void {
+ jsonArray.children.forEach((child) => {
visitNode(child, diagnosticsList, document, inheritedKey);
});
}
-function visitJsonProperty(jsonProperty: JsonProperty, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument, inheritedKey: string | null = null): void {
- const contextKey = jsonProperty.key;
+function visitJsonProperty(
+ jsonProperty: JsonProperty,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ inheritedKey: string | null = null,
+): void {
+ const contextKey = jsonProperty.key;
validateProperty(jsonProperty, contextKey, diagnosticsList, document);
- validators.forEach(validator => {
+ validators.forEach((validator) => {
if (validator.accept(contextKey)) {
- validator.validate(jsonProperty.value, diagnosticsList, document, contextKey);
+ validator.validate(
+ jsonProperty.value,
+ diagnosticsList,
+ document,
+ contextKey,
+ );
}
});
if (jsonProperty.value instanceof JsonObject) {
- visitJsonObject(jsonProperty.value, diagnosticsList, document, contextKey);
+ visitJsonObject(
+ jsonProperty.value,
+ diagnosticsList,
+ document,
+ contextKey,
+ );
} else if (jsonProperty.value instanceof JsonArray) {
- visitJsonArray(jsonProperty.value, diagnosticsList, document, contextKey);
+ visitJsonArray(
+ jsonProperty.value,
+ diagnosticsList,
+ document,
+ contextKey,
+ );
}
}
-function visitNode(node: JsonNode, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument, contextKey: string | null): void {
+function visitNode(
+ node: JsonNode,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ contextKey: string | null,
+): void {
if (node instanceof JsonObject) {
visitJsonObject(node, diagnosticsList, document, contextKey);
} else if (node instanceof JsonArray) {
@@ -188,16 +247,24 @@ function visitNode(node: JsonNode, diagnosticsList: vscode.Diagnostic[], documen
function determineContextKey(jsonObject: JsonObject): string | null {
if (jsonObject.parent instanceof JsonProperty) {
return jsonObject.parent.key;
- } else if (jsonObject.parent instanceof JsonArray && jsonObject.parent.parent instanceof JsonProperty) {
+ } else if (
+ jsonObject.parent instanceof JsonArray &&
+ jsonObject.parent.parent instanceof JsonProperty
+ ) {
return jsonObject.parent.parent.key;
} else {
return null;
}
}
-function validateProperty(property: JsonProperty, contextKey:string, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument){
+function validateProperty(
+ property: JsonProperty,
+ contextKey: string,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+) {
const key = property.key;
- const value = property.value;
+ const value = property.value;
const positionMap = ValidationHelper.getPositionMap(document);
if (key === "query") {
@@ -209,13 +276,19 @@ function validateProperty(property: JsonProperty, contextKey:string, diagnostics
} else if (["location", "top_left", "bottom_right"].includes(key)) {
validateLocation(property, diagnosticsList, document);
} else if (["min", "max"].includes(key)) {
- if (typeof value.value !== "string" && typeof value.value !== "number") {
+ if (
+ typeof value.value !== "string" &&
+ typeof value.value !== "number"
+ ) {
const message = `'${key}' should be an integer for a numeric range query or a string for term range query`;
- diagnosticsList.push(new vscode.Diagnostic(
- positionMap.get(property.key) || new vscode.Range(0, 0, 0, 1),
- message,
- vscode.DiagnosticSeverity.Error
- ));
+ diagnosticsList.push(
+ new vscode.Diagnostic(
+ positionMap.get(property.key) ||
+ new vscode.Range(0, 0, 0, 1),
+ message,
+ vscode.DiagnosticSeverity.Error,
+ ),
+ );
}
} else if (["distance", "radius"].includes(key)) {
validateDistance(property, diagnosticsList, document);
@@ -223,18 +296,28 @@ function validateProperty(property: JsonProperty, contextKey:string, diagnostics
validatePolygonPoints(property, diagnosticsList, document);
} else {
if (key in PROPERTY_RULES) {
- validateType(value, PROPERTY_RULES[key].type, diagnosticsList, document, property);
+ validateType(
+ value,
+ PROPERTY_RULES[key].type,
+ diagnosticsList,
+ document,
+ property,
+ );
}
}
- }
-
-
+}
function isTopLevel(property: JsonProperty): boolean {
return !property.parent || property.parent.parent === null;
}
-function validateType(value: any, expectedType: string, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument, property: JsonProperty): void {
+function validateType(
+ value: any,
+ expectedType: string,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+ property: JsonProperty,
+): void {
let isValid = false;
let type;
@@ -253,25 +336,29 @@ function validateType(value: any, expectedType: string, diagnosticsList: vscode.
}
} else if (value instanceof JsonObject) {
isValid = expectedType === "json";
- type = 'json';
+ type = "json";
} else if (value instanceof JsonArray) {
isValid = expectedType === "array";
- type = 'array';
+ type = "array";
}
if (!isValid) {
const positionMap = ValidationHelper.getPositionMap(document);
- diagnosticsList.push(new vscode.Diagnostic(
- positionMap.get(property.key) || new vscode.Range(0, 0, 0, 1),
- `Expected ${expectedType} for property '${property.key}' `,
- vscode.DiagnosticSeverity.Error
- ));
+ diagnosticsList.push(
+ new vscode.Diagnostic(
+ positionMap.get(property.key) || new vscode.Range(0, 0, 0, 1),
+ `Expected ${expectedType} for property '${property.key}' `,
+ vscode.DiagnosticSeverity.Error,
+ ),
+ );
}
}
-
-export function findRange(document: vscode.TextDocument, searchTerm: string): vscode.Range {
- const regex = new RegExp(`"${searchTerm}"\\s*:\\s*`, 'g');
+export function findRange(
+ document: vscode.TextDocument,
+ searchTerm: string,
+): vscode.Range {
+ const regex = new RegExp(`"${searchTerm}"\\s*:\\s*`, "g");
const match = regex.exec(document.getText());
if (match) {
const startPos = document.positionAt(match.index);
@@ -281,76 +368,113 @@ export function findRange(document: vscode.TextDocument, searchTerm: string): vs
return new vscode.Range(0, 0, 0, 1);
}
-
-function validateLocation(property: JsonProperty, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument) {
+function validateLocation(
+ property: JsonProperty,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+) {
const key = property.key;
const value = property.value;
const positionMap = ValidationHelper.getPositionMap(document);
-
if (value instanceof JsonArray) {
if (value.children.length !== 2) {
- diagnosticsList.push(new vscode.Diagnostic(
- positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
- ValidationHelper.getExpectedArrayLengthMessage(key, 2, value.children.length),
- vscode.DiagnosticSeverity.Error
- ));
+ diagnosticsList.push(
+ new vscode.Diagnostic(
+ positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
+ ValidationHelper.getExpectedArrayLengthMessage(
+ key,
+ 2,
+ value.children.length,
+ ),
+ vscode.DiagnosticSeverity.Error,
+ ),
+ );
}
} else if (value instanceof JsonObject) {
- const attrs = value.children.map(child => (child as JsonProperty).key);
- if (attrs.length !== 2 || !attrs.includes("lat") || !attrs.includes("lon")) {
- diagnosticsList.push(new vscode.Diagnostic(
- positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
- ValidationHelper.getExpectedObjectPropertiesMessage(key),
- vscode.DiagnosticSeverity.Error
- ));
+ const attrs = value.children.map(
+ (child) => (child as JsonProperty).key,
+ );
+ if (
+ attrs.length !== 2 ||
+ !attrs.includes("lat") ||
+ !attrs.includes("lon")
+ ) {
+ diagnosticsList.push(
+ new vscode.Diagnostic(
+ positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
+ ValidationHelper.getExpectedObjectPropertiesMessage(key),
+ vscode.DiagnosticSeverity.Error,
+ ),
+ );
}
} else {
- diagnosticsList.push(new vscode.Diagnostic(
- positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
- ValidationHelper.getExpectedArrayOrObjectMessage(key, typeof value),
- vscode.DiagnosticSeverity.Error
- ));
+ diagnosticsList.push(
+ new vscode.Diagnostic(
+ positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
+ ValidationHelper.getExpectedArrayOrObjectMessage(
+ key,
+ typeof value,
+ ),
+ vscode.DiagnosticSeverity.Error,
+ ),
+ );
}
}
-function validateDistance(property: JsonProperty, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument) {
+function validateDistance(
+ property: JsonProperty,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+) {
const key = property.key;
- const value = property.value.value;
+ const value = property.value.value;
const positionMap = ValidationHelper.getPositionMap(document);
if (typeof value !== "string") {
- diagnosticsList.push(new vscode.Diagnostic(
- positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
- ValidationHelper.getExpectedDataTypeErrorMessage("string",key),
- vscode.DiagnosticSeverity.Error
- ));
+ diagnosticsList.push(
+ new vscode.Diagnostic(
+ positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
+ ValidationHelper.getExpectedDataTypeErrorMessage("string", key),
+ vscode.DiagnosticSeverity.Error,
+ ),
+ );
return;
}
const validUnits = ["mm", "cm", "in", "yd", "ft", "km", "mi", "nm", "m"];
- const hasValidUnit = validUnits.some(unit => value.endsWith(unit));
+ const hasValidUnit = validUnits.some((unit) => value.endsWith(unit));
if (!hasValidUnit) {
- diagnosticsList.push(new vscode.Diagnostic(
- positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
- ValidationHelper.getInvalidDistanceUnitErrorMessage(key, validUnits),
- vscode.DiagnosticSeverity.Error
- ));
+ diagnosticsList.push(
+ new vscode.Diagnostic(
+ positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
+ ValidationHelper.getInvalidDistanceUnitErrorMessage(
+ key,
+ validUnits,
+ ),
+ vscode.DiagnosticSeverity.Error,
+ ),
+ );
}
}
-
-function validatePolygonPoints(property: JsonProperty, diagnosticsList: vscode.Diagnostic[], document: vscode.TextDocument) {
+function validatePolygonPoints(
+ property: JsonProperty,
+ diagnosticsList: vscode.Diagnostic[],
+ document: vscode.TextDocument,
+) {
const key = property.key;
- const value = property.value as JsonArray;
+ const value = property.value as JsonArray;
const positionMap = ValidationHelper.getPositionMap(document);
- if (!(value instanceof JsonArray)) {
- diagnosticsList.push(new vscode.Diagnostic(
- positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
- ValidationHelper.getExpectedDataTypeErrorMessage("array", key),
- vscode.DiagnosticSeverity.Error
- ));
+ if (!(value instanceof JsonArray)) {
+ diagnosticsList.push(
+ new vscode.Diagnostic(
+ positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
+ ValidationHelper.getExpectedDataTypeErrorMessage("array", key),
+ vscode.DiagnosticSeverity.Error,
+ ),
+ );
return;
}
@@ -358,22 +482,28 @@ function validatePolygonPoints(property: JsonProperty, diagnosticsList: vscode.D
const type = item as JsonProperty;
if (typeof type.value === "string") {
if (!type.value.includes(",")) {
- diagnosticsList.push(new vscode.Diagnostic(
- positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
- ValidationHelper.getExpectedLatLonMessage(`${key}[${index}]`),
- vscode.DiagnosticSeverity.Error
- ));
+ diagnosticsList.push(
+ new vscode.Diagnostic(
+ positionMap.get(key) || new vscode.Range(0, 0, 0, 1),
+ ValidationHelper.getExpectedLatLonMessage(
+ `${key}[${index}]`,
+ ),
+ vscode.DiagnosticSeverity.Error,
+ ),
+ );
}
} else {
- diagnosticsList.push(new vscode.Diagnostic(
- positionMap.get(`${key}[${index}]`) || new vscode.Range(0, 0, 0, 1),
- ValidationHelper.getExpectedDataTypeErrorMessage("string", `${key}[${index}]`),
- vscode.DiagnosticSeverity.Error
- ));
+ diagnosticsList.push(
+ new vscode.Diagnostic(
+ positionMap.get(`${key}[${index}]`) ||
+ new vscode.Range(0, 0, 0, 1),
+ ValidationHelper.getExpectedDataTypeErrorMessage(
+ "string",
+ `${key}[${index}]`,
+ ),
+ vscode.DiagnosticSeverity.Error,
+ ),
+ );
}
});
}
-
-
-
-
diff --git a/src/handlers/handleSearchQueryContextStatusBar.ts b/src/handlers/handleSearchQueryContextStatusBar.ts
index 3825abd2..7ada32a8 100644
--- a/src/handlers/handleSearchQueryContextStatusBar.ts
+++ b/src/handlers/handleSearchQueryContextStatusBar.ts
@@ -1,14 +1,28 @@
-import * as vscode from 'vscode';
-import { SearchWorkbench } from '../commands/fts/SearchWorkbench/searchWorkbench';
-import { showSearchContextStatusbar } from '../util/queryContextUtils';
-import SearchIndexNode from '../model/SearchIndexNode';
+import * as vscode from "vscode";
+import { SearchWorkbench } from "../commands/fts/SearchWorkbench/searchWorkbench";
+import { showSearchContextStatusbar } from "../util/queryContextUtils";
+import SearchIndexNode from "../model/SearchIndexNode";
-export const handleSearchContextStatusbar = async (editor: vscode.TextEditor | undefined,searchNode:SearchIndexNode, workbench:SearchWorkbench, globalStatusBarItem: vscode.StatusBarItem) => {
- if( editor && editor.document.languageId === "json" && editor.document.fileName.endsWith(".cbs.json")){
+export const handleSearchContextStatusbar = async (
+ editor: vscode.TextEditor | undefined,
+ searchNode: SearchIndexNode,
+ workbench: SearchWorkbench,
+ globalStatusBarItem: vscode.StatusBarItem,
+) => {
+ if (
+ editor &&
+ editor.document.languageId === "json" &&
+ editor.document.fileName.endsWith(".cbs.json")
+ ) {
// Case 1: Show Status bar
- showSearchContextStatusbar(editor,searchNode, workbench, globalStatusBarItem);
+ showSearchContextStatusbar(
+ editor,
+ searchNode,
+ workbench,
+ globalStatusBarItem,
+ );
} else {
// Case 2: Don't show status bar
globalStatusBarItem.hide();
}
-};
\ No newline at end of file
+};
diff --git a/src/pages/queryContext/queryContext.ts b/src/pages/queryContext/queryContext.ts
index dafa5be3..8df0762d 100644
--- a/src/pages/queryContext/queryContext.ts
+++ b/src/pages/queryContext/queryContext.ts
@@ -1,21 +1,28 @@
import { IConnection } from "../../types/IConnection";
import { Memory } from "../../util/util";
-import * as vscode from 'vscode';
+import * as vscode from "vscode";
import { logger } from "../../logger/logger";
import { Bucket, BucketSettings } from "couchbase";
import { QueryWorkbench } from "../../workbench/queryWorkbench";
-import { showQueryContextStatusbar, showSearchContextStatusbar } from "../../util/queryContextUtils";
+import {
+ showQueryContextStatusbar,
+ showSearchContextStatusbar,
+} from "../../util/queryContextUtils";
import { getActiveConnection } from "../../util/connections";
import { SearchWorkbench } from "../../commands/fts/SearchWorkbench/searchWorkbench";
import SearchIndexNode from "../../model/SearchIndexNode";
import { Commands } from "../../commands/extensionCommands/commands";
-const fetchBucketNames = (bucketsSettings: BucketSettings[] | undefined, connection: IConnection): Array => {
+const fetchBucketNames = (
+ bucketsSettings: BucketSettings[] | undefined,
+ connection: IConnection,
+): Array => {
const allBuckets: Array = [];
if (bucketsSettings !== undefined) {
for (let bucketSettings of bucketsSettings) {
const bucketName: string = bucketSettings.name;
- const bucket: Bucket | undefined = connection?.cluster?.bucket(bucketName);
+ const bucket: Bucket | undefined =
+ connection?.cluster?.bucket(bucketName);
if (bucket !== undefined) {
allBuckets.push(bucket);
}
@@ -24,52 +31,79 @@ const fetchBucketNames = (bucketsSettings: BucketSettings[] | undefined, connect
return allBuckets;
};
-export async function fetchQueryContext(workbench: QueryWorkbench, context: vscode.ExtensionContext, globalStatusBarItem:any) {
+export async function fetchQueryContext(
+ workbench: QueryWorkbench,
+ context: vscode.ExtensionContext,
+ globalStatusBarItem: any,
+) {
const connection = getActiveConnection();
if (!connection) {
- vscode.window.showErrorMessage("Please connect to a cluster before setting query context");
+ vscode.window.showErrorMessage(
+ "Please connect to a cluster before setting query context",
+ );
return;
}
try {
// Fetch active editor
const activeEditor = vscode.window.activeTextEditor;
- if (
- !(activeEditor &&
- activeEditor.document.languageId === "SQL++")
- ) {
- vscode.window.showErrorMessage("Please ensure that the workbench is open/active");
+ if (!(activeEditor && activeEditor.document.languageId === "SQL++")) {
+ vscode.window.showErrorMessage(
+ "Please ensure that the workbench is open/active",
+ );
return;
}
// Fetch all buckets
- const bucketsSettings = await connection?.cluster?.buckets().getAllBuckets();
+ const bucketsSettings = await connection?.cluster
+ ?.buckets()
+ .getAllBuckets();
const allBuckets = fetchBucketNames(bucketsSettings, connection);
if (!allBuckets || allBuckets.length === 0) {
- vscode.window.showErrorMessage('No buckets found.');
+ vscode.window.showErrorMessage("No buckets found.");
return;
}
- const bucketItems = allBuckets.map((bucket: Bucket) => { return { label: bucket.name, iconPath: new vscode.ThemeIcon("database") }; });
- const selectedItem = await vscode.window.showQuickPick([
- { label: "Clears any active query context", kind: vscode.QuickPickItemKind.Separator },
- { label: "Clear Context", iconPath: new vscode.ThemeIcon("clear-all") },
- { kind: vscode.QuickPickItemKind.Separator, label: "Buckets" },
- ...bucketItems
- ], {
- canPickMany: false,
- placeHolder: 'Query Context: Select a bucket',
+ const bucketItems = allBuckets.map((bucket: Bucket) => {
+ return {
+ label: bucket.name,
+ iconPath: new vscode.ThemeIcon("database"),
+ };
});
+ const selectedItem = await vscode.window.showQuickPick(
+ [
+ {
+ label: "Clears any active query context",
+ kind: vscode.QuickPickItemKind.Separator,
+ },
+ {
+ label: "Clear Context",
+ iconPath: new vscode.ThemeIcon("clear-all"),
+ },
+ { kind: vscode.QuickPickItemKind.Separator, label: "Buckets" },
+ ...bucketItems,
+ ],
+ {
+ canPickMany: false,
+ placeHolder: "Query Context: Select a bucket",
+ },
+ );
if (!selectedItem) {
vscode.window.showInformationMessage("No buckets selected.");
return;
}
const bucketNameSelected = selectedItem.label;
- if (bucketNameSelected === 'Clear Context') {
- workbench.editorToContext.delete(activeEditor.document.uri.toString());
- showQueryContextStatusbar(activeEditor, workbench,globalStatusBarItem);
+ if (bucketNameSelected === "Clear Context") {
+ workbench.editorToContext.delete(
+ activeEditor.document.uri.toString(),
+ );
+ showQueryContextStatusbar(
+ activeEditor,
+ workbench,
+ globalStatusBarItem,
+ );
return;
}
const scopes = await connection.cluster
@@ -77,56 +111,83 @@ export async function fetchQueryContext(workbench: QueryWorkbench, context: vsco
.collections()
.getAllScopes();
if (scopes === undefined || scopes.length === 0) {
- vscode.window.showErrorMessage('No scopes found.');
+ vscode.window.showErrorMessage("No scopes found.");
return;
}
- const scopeNameSelected = await vscode.window.showQuickPick(scopes.map((scope) => { return { label: scope.name, iconPath: new vscode.ThemeIcon("file-submodule") }; }), { placeHolder: 'Query Context: Select a scope' });
+ const scopeNameSelected = await vscode.window.showQuickPick(
+ scopes.map((scope) => {
+ return {
+ label: scope.name,
+ iconPath: new vscode.ThemeIcon("file-submodule"),
+ };
+ }),
+ { placeHolder: "Query Context: Select a scope" },
+ );
if (!scopeNameSelected) {
- vscode.window.showInformationMessage('No scope selected.');
+ vscode.window.showInformationMessage("No scope selected.");
return;
}
workbench.editorToContext.set(activeEditor.document.uri.toString(), {
bucketName: bucketNameSelected,
- scopeName: scopeNameSelected.label
+ scopeName: scopeNameSelected.label,
});
- showQueryContextStatusbar(activeEditor, workbench,globalStatusBarItem);
-
+ showQueryContextStatusbar(activeEditor, workbench, globalStatusBarItem);
} catch (err) {
logger.error(`failed to open and set query context: ${err}`);
logger.debug(err);
}
}
-export async function fetchSearchContext(searchIndexNode: SearchIndexNode, workbench: SearchWorkbench, context: vscode.ExtensionContext, globalStatusBarItem: vscode.StatusBarItem) {
+export async function fetchSearchContext(
+ searchIndexNode: SearchIndexNode,
+ workbench: SearchWorkbench,
+ context: vscode.ExtensionContext,
+ globalStatusBarItem: vscode.StatusBarItem,
+) {
const connection = getActiveConnection();
if (!connection) {
- vscode.window.showErrorMessage("Please connect to a cluster before setting query context");
+ vscode.window.showErrorMessage(
+ "Please connect to a cluster before setting query context",
+ );
return;
}
try {
const activeEditor = vscode.window.activeTextEditor;
- if (!(activeEditor && activeEditor.document.languageId === "json" && activeEditor.document.fileName.endsWith(".cbs.json"))) {
- vscode.window.showErrorMessage("Please ensure that the workbench is open/active");
+ if (
+ !(
+ activeEditor &&
+ activeEditor.document.languageId === "json" &&
+ activeEditor.document.fileName.endsWith(".cbs.json")
+ )
+ ) {
+ vscode.window.showErrorMessage(
+ "Please ensure that the workbench is open/active",
+ );
return;
}
// Fetching bucket names
- const bucketsSettings = await connection?.cluster?.buckets().getAllBuckets();
+ const bucketsSettings = await connection?.cluster
+ ?.buckets()
+ .getAllBuckets();
const allBuckets = fetchBucketNames(bucketsSettings, connection);
if (!allBuckets || allBuckets.length === 0) {
- vscode.window.showErrorMessage('No buckets found.');
+ vscode.window.showErrorMessage("No buckets found.");
return;
}
// Displaying QuickPick for buckets
- const selectedItem = await vscode.window.showQuickPick(allBuckets.map(bucket => ({
- label: bucket.name,
- iconPath: new vscode.ThemeIcon("database")
- })), {
- placeHolder: 'Search Query Context: Select a bucket',
- canPickMany: false
- });
+ const selectedItem = await vscode.window.showQuickPick(
+ allBuckets.map((bucket) => ({
+ label: bucket.name,
+ iconPath: new vscode.ThemeIcon("database"),
+ })),
+ {
+ placeHolder: "Search Query Context: Select a bucket",
+ canPickMany: false,
+ },
+ );
if (!selectedItem) {
vscode.window.showInformationMessage("No buckets selected.");
@@ -138,43 +199,53 @@ export async function fetchSearchContext(searchIndexNode: SearchIndexNode, workb
// Fetching search indexes specific to the selected bucket
const searchIndexesManager = connection?.cluster?.searchIndexes();
const ftsIndexes = await searchIndexesManager?.getAllIndexes();
- const bucketIndexes = ftsIndexes?.filter(index => index.sourceName === bucketNameSelected);
+ const bucketIndexes = ftsIndexes?.filter(
+ (index) => index.sourceName === bucketNameSelected,
+ );
if (!bucketIndexes || bucketIndexes.length === 0) {
- vscode.window.showErrorMessage('No Indexes found.');
+ vscode.window.showErrorMessage("No Indexes found.");
return;
}
// Displaying QuickPick for indexes
- const indexNameSelected = await vscode.window.showQuickPick(bucketIndexes.map(index => ({
- label: index.name,
- iconPath: new vscode.ThemeIcon("file-submodule")
- })), {
- placeHolder: 'Query Context: Select an Index',
- canPickMany: false
- });
+ const indexNameSelected = await vscode.window.showQuickPick(
+ bucketIndexes.map((index) => ({
+ label: index.name,
+ iconPath: new vscode.ThemeIcon("file-submodule"),
+ })),
+ {
+ placeHolder: "Query Context: Select an Index",
+ canPickMany: false,
+ },
+ );
if (!indexNameSelected) {
- vscode.window.showInformationMessage('No index selected.');
+ vscode.window.showInformationMessage("No index selected.");
return;
}
let editorId = activeEditor.document.uri.toString();
let editorContext = workbench.editorToContext.get(editorId);
-
- let displayBucketName = bucketNameSelected.length > 15 ? `${bucketNameSelected.substring(0, 13)}...` : bucketNameSelected;
- let displayIndexName = indexNameSelected.label.length > 15 ? `${indexNameSelected.label.substring(0, 13)}...` : indexNameSelected.label;
+
+ let displayBucketName =
+ bucketNameSelected.length > 15
+ ? `${bucketNameSelected.substring(0, 13)}...`
+ : bucketNameSelected;
+ let displayIndexName =
+ indexNameSelected.label.length > 15
+ ? `${indexNameSelected.label.substring(0, 13)}...`
+ : indexNameSelected.label;
editorContext = {
bucketName: bucketNameSelected,
indexName: indexNameSelected.label,
statusBarItem: globalStatusBarItem,
- searchNode: searchIndexNode
+ searchNode: searchIndexNode,
};
workbench.editorToContext.set(editorId, editorContext);
editorContext.statusBarItem.text = `$(group-by-ref-type) ${displayBucketName} > ${displayIndexName}`;
editorContext.statusBarItem.tooltip = "Search Query Context";
editorContext.statusBarItem.command = Commands.searchContext;
-
} catch (err) {
logger.error(`Failed to open and set query context: ${err}`);
logger.debug(err);
diff --git a/src/test/contributor/cbsCtlCodeCompletion.test.ts b/src/test/contributor/cbsCtlCodeCompletion.test.ts
index c62b3de2..c4bf70a5 100644
--- a/src/test/contributor/cbsCtlCodeCompletion.test.ts
+++ b/src/test/contributor/cbsCtlCodeCompletion.test.ts
@@ -1,70 +1,79 @@
-import * as assert from 'assert';
-import * as vscode from 'vscode';
-import * as path from 'path';
-import * as os from 'os';
-import * as fs from 'fs';
-import { AutocompleteVisitor } from '../../commands/fts/SearchWorkbench/contributor/autoCompleteVisitor';
-import { consistencyCbsContributor } from '../../commands/fts/SearchWorkbench/contributor/consistencyCbsContributor';
-import { ctlCbsContributor } from '../../commands/fts/SearchWorkbench/contributor/ctlCbsContributor';
-
-
-
-
-suite('CBSCtlCodeCompletion Test Suite', () => {
- let autocompleteVisitor: AutocompleteVisitor;
- let tempDir: string;
-
- setup(async () => {
- autocompleteVisitor = new AutocompleteVisitor();
- tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'vscode-test-'));
- });
-
- teardown(async () => {
- await fs.promises.rm(tempDir, { recursive: true, force: true });
- });
-
- const getCompletions = async (content: string): Promise => {
- const tempFile = path.join(tempDir, 'test.json');
- await fs.promises.writeFile(tempFile, content);
-
- const uri = vscode.Uri.file(tempFile);
- const document = await vscode.workspace.openTextDocument(uri);
-
- const caretIndex = content.indexOf('');
- const position = document.positionAt(caretIndex);
-
- const completionItems = await autocompleteVisitor.getAutoCompleteContributor(document, position);
- return completionItems.map(item => item.label as string);
- };
-
- test('completion for ctl', async () => {
- const content = `{
+import * as assert from "assert";
+import * as vscode from "vscode";
+import * as path from "path";
+import * as os from "os";
+import * as fs from "fs";
+import { AutocompleteVisitor } from "../../commands/fts/SearchWorkbench/contributor/autoCompleteVisitor";
+import { consistencyCbsContributor } from "../../commands/fts/SearchWorkbench/contributor/consistencyCbsContributor";
+import { ctlCbsContributor } from "../../commands/fts/SearchWorkbench/contributor/ctlCbsContributor";
+
+suite("CBSCtlCodeCompletion Test Suite", () => {
+ let autocompleteVisitor: AutocompleteVisitor;
+ let tempDir: string;
+
+ setup(async () => {
+ autocompleteVisitor = new AutocompleteVisitor();
+ tempDir = await fs.promises.mkdtemp(
+ path.join(os.tmpdir(), "vscode-test-"),
+ );
+ });
+
+ teardown(async () => {
+ await fs.promises.rm(tempDir, { recursive: true, force: true });
+ });
+
+ const getCompletions = async (content: string): Promise => {
+ const tempFile = path.join(tempDir, "test.json");
+ await fs.promises.writeFile(tempFile, content);
+
+ const uri = vscode.Uri.file(tempFile);
+ const document = await vscode.workspace.openTextDocument(uri);
+
+ const caretIndex = content.indexOf("");
+ const position = document.positionAt(caretIndex);
+
+ const completionItems =
+ await autocompleteVisitor.getAutoCompleteContributor(
+ document,
+ position,
+ );
+ return completionItems.map((item) => item.label as string);
+ };
+
+ test("completion for ctl", async () => {
+ const content = `{
"ctl": {""}
}`;
- const completionResults = await getCompletions(content);
-
- assert.notStrictEqual(completionResults, null, "No completions found");
- for (const keyword of ctlCbsContributor.keys) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
- });
-
- test('dont suggest keyword already exists', async () => {
- const content = `{
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ for (const keyword of ctlCbsContributor.keys) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
+ });
+
+ test("dont suggest keyword already exists", async () => {
+ const content = `{
"ctl": { "timeout": 10000,
""}
}`;
- const completionResults = await getCompletions(content);
-
- assert.notStrictEqual(completionResults, null, "No completions found");
- const expected = ["consistency"];
- for (const keyword of expected) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
- });
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ const expected = ["consistency"];
+ for (const keyword of expected) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
+ });
- test('completion consistency', async () => {
- const content = `{
+ test("completion consistency", async () => {
+ const content = `{
"ctl": {
"timeout": 10000,
"consistency": {
@@ -72,16 +81,19 @@ suite('CBSCtlCodeCompletion Test Suite', () => {
}
}
}`;
- const completionResults = await getCompletions(content);
-
- assert.notStrictEqual(completionResults, null, "No completions found");
- for (const keyword of consistencyCbsContributor.keys) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
- });
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ for (const keyword of consistencyCbsContributor.keys) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
+ });
- test('completion consistency existing values', async () => {
- const content = `{
+ test("completion consistency existing values", async () => {
+ const content = `{
"ctl": {
"timeout": 10000,
"consistency": {
@@ -90,16 +102,19 @@ suite('CBSCtlCodeCompletion Test Suite', () => {
}
}
}`;
- const completionResults = await getCompletions(content);
-
- assert.notStrictEqual(completionResults, null, "No completions found");
- for (const keyword of ["vectors", "results"]) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
- });
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ for (const keyword of ["vectors", "results"]) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
+ });
- test('suggest level values', async () => {
- const content = `{
+ test("suggest level values", async () => {
+ const content = `{
"ctl": {
"timeout": 10000,
"consistency": {
@@ -114,17 +129,20 @@ suite('CBSCtlCodeCompletion Test Suite', () => {
}
}
}`;
- const completionResults = await getCompletions(content);
-
- assert.notStrictEqual(completionResults, null, "No completions found");
- const expected = ["at_plus", "not_bounded"];
- for (const keyword of expected) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
- });
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ const expected = ["at_plus", "not_bounded"];
+ for (const keyword of expected) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
+ });
- test('suggest results values', async () => {
- const content = `{
+ test("suggest results values", async () => {
+ const content = `{
"ctl": {
"timeout": 10000,
"consistency": {
@@ -138,12 +156,15 @@ suite('CBSCtlCodeCompletion Test Suite', () => {
}
}
}`;
- const completionResults = await getCompletions(content);
-
- assert.notStrictEqual(completionResults, null, "No completions found");
- const expected = ["complete"];
- for (const keyword of expected) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
- });
-});
\ No newline at end of file
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ const expected = ["complete"];
+ for (const keyword of expected) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
+ });
+});
diff --git a/src/test/contributor/cbsGeometryCodeCompletion.test.ts b/src/test/contributor/cbsGeometryCodeCompletion.test.ts
index e1fbdf9f..cc6595f2 100644
--- a/src/test/contributor/cbsGeometryCodeCompletion.test.ts
+++ b/src/test/contributor/cbsGeometryCodeCompletion.test.ts
@@ -1,40 +1,46 @@
-import * as assert from 'assert';
-import * as vscode from 'vscode';
-import * as path from 'path';
-import * as os from 'os';
-import * as fs from 'fs';
-import { AutocompleteVisitor } from '../../commands/fts/SearchWorkbench/contributor/autoCompleteVisitor';
-import { geometryCbsContributor } from '../../commands/fts/SearchWorkbench/contributor/geometryCbsContributor';
+import * as assert from "assert";
+import * as vscode from "vscode";
+import * as path from "path";
+import * as os from "os";
+import * as fs from "fs";
+import { AutocompleteVisitor } from "../../commands/fts/SearchWorkbench/contributor/autoCompleteVisitor";
+import { geometryCbsContributor } from "../../commands/fts/SearchWorkbench/contributor/geometryCbsContributor";
-suite('CBSGeometryCodeCompletion Test Suite', () => {
+suite("CBSGeometryCodeCompletion Test Suite", () => {
let autocompleteVisitor: AutocompleteVisitor;
let tempDir: string;
-
+
setup(async () => {
- autocompleteVisitor = new AutocompleteVisitor();
- tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'vscode-test-'));
+ autocompleteVisitor = new AutocompleteVisitor();
+ tempDir = await fs.promises.mkdtemp(
+ path.join(os.tmpdir(), "vscode-test-"),
+ );
});
-
+
teardown(async () => {
- await fs.promises.rm(tempDir, { recursive: true, force: true });
+ await fs.promises.rm(tempDir, { recursive: true, force: true });
});
-
+
const getCompletions = async (content: string): Promise => {
- const tempFile = path.join(tempDir, 'test.json');
- await fs.promises.writeFile(tempFile, content);
-
- const uri = vscode.Uri.file(tempFile);
- const document = await vscode.workspace.openTextDocument(uri);
-
- const caretIndex = content.indexOf('');
- const position = document.positionAt(caretIndex);
-
- const completionItems = await autocompleteVisitor.getAutoCompleteContributor(document, position);
- return completionItems.map(item => item.label as string);
+ const tempFile = path.join(tempDir, "test.json");
+ await fs.promises.writeFile(tempFile, content);
+
+ const uri = vscode.Uri.file(tempFile);
+ const document = await vscode.workspace.openTextDocument(uri);
+
+ const caretIndex = content.indexOf("");
+ const position = document.positionAt(caretIndex);
+
+ const completionItems =
+ await autocompleteVisitor.getAutoCompleteContributor(
+ document,
+ position,
+ );
+ return completionItems.map((item) => item.label as string);
};
-
- test('completion for geometry', async () => {
- const content = `{
+
+ test("completion for geometry", async () => {
+ const content = `{
"query": {
"field": "geojson",
"geometry": {
@@ -42,16 +48,19 @@ suite('CBSGeometryCodeCompletion Test Suite', () => {
}
}
}`;
- const completionResults = await getCompletions(content);
-
- assert.notStrictEqual(completionResults, null, "No completions found");
- for (const keyword of geometryCbsContributor.keys) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ for (const keyword of geometryCbsContributor.keys) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
-
- test('completion for geometry relation', async () => {
- const content = `{
+
+ test("completion for geometry relation", async () => {
+ const content = `{
"query": {
"field": "geojson",
"geometry": {
@@ -59,12 +68,15 @@ suite('CBSGeometryCodeCompletion Test Suite', () => {
}
}
}`;
- const completionResults = await getCompletions(content);
-
- assert.notStrictEqual(completionResults, null, "No completions found");
- const expected = ["intersects", "within"];
- for (const keyword of expected) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ const expected = ["intersects", "within"];
+ for (const keyword of expected) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
- });
\ No newline at end of file
+});
diff --git a/src/test/contributor/cbsHighlightCodeCompletion.test.ts b/src/test/contributor/cbsHighlightCodeCompletion.test.ts
index fc4a4e6c..623901e0 100644
--- a/src/test/contributor/cbsHighlightCodeCompletion.test.ts
+++ b/src/test/contributor/cbsHighlightCodeCompletion.test.ts
@@ -1,77 +1,91 @@
-import * as assert from 'assert';
-import * as vscode from 'vscode';
-import * as path from 'path';
-import * as os from 'os';
-import * as fs from 'fs';
-import { AutocompleteVisitor } from '../../commands/fts/SearchWorkbench/contributor/autoCompleteVisitor';
-import { highlightCbsContributor } from '../../commands/fts/SearchWorkbench/contributor/highlightCbsContributor';
+import * as assert from "assert";
+import * as vscode from "vscode";
+import * as path from "path";
+import * as os from "os";
+import * as fs from "fs";
+import { AutocompleteVisitor } from "../../commands/fts/SearchWorkbench/contributor/autoCompleteVisitor";
+import { highlightCbsContributor } from "../../commands/fts/SearchWorkbench/contributor/highlightCbsContributor";
-
-suite('CBSHighlightCodeCompletion Test Suite', () => {
+suite("CBSHighlightCodeCompletion Test Suite", () => {
let autocompleteVisitor: AutocompleteVisitor;
let tempDir: string;
-
+
setup(async () => {
- autocompleteVisitor = new AutocompleteVisitor();
- tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'vscode-test-'));
+ autocompleteVisitor = new AutocompleteVisitor();
+ tempDir = await fs.promises.mkdtemp(
+ path.join(os.tmpdir(), "vscode-test-"),
+ );
});
-
+
teardown(async () => {
- await fs.promises.rm(tempDir, { recursive: true, force: true });
+ await fs.promises.rm(tempDir, { recursive: true, force: true });
});
-
+
const getCompletions = async (content: string): Promise => {
- const tempFile = path.join(tempDir, 'test.json');
- await fs.promises.writeFile(tempFile, content);
-
- const uri = vscode.Uri.file(tempFile);
- const document = await vscode.workspace.openTextDocument(uri);
-
- const caretIndex = content.indexOf('');
- const position = document.positionAt(caretIndex);
-
- const completionItems = await autocompleteVisitor.getAutoCompleteContributor(document, position);
- return completionItems.map(item => item.label as string);
+ const tempFile = path.join(tempDir, "test.json");
+ await fs.promises.writeFile(tempFile, content);
+
+ const uri = vscode.Uri.file(tempFile);
+ const document = await vscode.workspace.openTextDocument(uri);
+
+ const caretIndex = content.indexOf("");
+ const position = document.positionAt(caretIndex);
+
+ const completionItems =
+ await autocompleteVisitor.getAutoCompleteContributor(
+ document,
+ position,
+ );
+ return completionItems.map((item) => item.label as string);
};
-
- test('completion for highlight', async () => {
- const content = `{
+
+ test("completion for highlight", async () => {
+ const content = `{
"highlight": {""}
}`;
- const completionResults = await getCompletions(content);
-
- assert.notStrictEqual(completionResults, null, "No completions found");
- for (const keyword of highlightCbsContributor.keys) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ for (const keyword of highlightCbsContributor.keys) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
-
- test('dont suggest keyword already exists', async () => {
- const content = `{
+
+ test("dont suggest keyword already exists", async () => {
+ const content = `{
"highlight": { "fields": ["textField"],
""}
}`;
- const completionResults = await getCompletions(content);
-
- assert.notStrictEqual(completionResults, null, "No completions found");
- const expected = ["style"];
- for (const keyword of expected) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ const expected = ["style"];
+ for (const keyword of expected) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
-
- test('suggest style values', async () => {
- const content = `{
+
+ test("suggest style values", async () => {
+ const content = `{
"highlight": { "fields": ["textField"],
"style": ""
}
}`;
- const completionResults = await getCompletions(content);
-
- assert.notStrictEqual(completionResults, null, "No completions found");
- const expected = ["html", "ansi"];
- for (const keyword of expected) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ const expected = ["html", "ansi"];
+ for (const keyword of expected) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
- });
\ No newline at end of file
+});
diff --git a/src/test/contributor/cbsKnnCodeCompletion.test.ts b/src/test/contributor/cbsKnnCodeCompletion.test.ts
index 1c820a8f..073b9c08 100644
--- a/src/test/contributor/cbsKnnCodeCompletion.test.ts
+++ b/src/test/contributor/cbsKnnCodeCompletion.test.ts
@@ -1,62 +1,73 @@
-import * as assert from 'assert';
-import * as vscode from 'vscode';
-import * as path from 'path';
-import * as os from 'os';
-import * as fs from 'fs';
-import { AutocompleteVisitor } from '../../commands/fts/SearchWorkbench/contributor/autoCompleteVisitor';
-import { knnCbsContributor } from '../../commands/fts/SearchWorkbench/contributor/knnCbsContributor';
+import * as assert from "assert";
+import * as vscode from "vscode";
+import * as path from "path";
+import * as os from "os";
+import * as fs from "fs";
+import { AutocompleteVisitor } from "../../commands/fts/SearchWorkbench/contributor/autoCompleteVisitor";
+import { knnCbsContributor } from "../../commands/fts/SearchWorkbench/contributor/knnCbsContributor";
-
-suite('CBSKnnCodeCompletion Test Suite', () => {
+suite("CBSKnnCodeCompletion Test Suite", () => {
let autocompleteVisitor: AutocompleteVisitor;
let tempDir: string;
-
+
setup(async () => {
- autocompleteVisitor = new AutocompleteVisitor();
- tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'vscode-test-'));
+ autocompleteVisitor = new AutocompleteVisitor();
+ tempDir = await fs.promises.mkdtemp(
+ path.join(os.tmpdir(), "vscode-test-"),
+ );
});
-
+
teardown(async () => {
- await fs.promises.rm(tempDir, { recursive: true, force: true });
+ await fs.promises.rm(tempDir, { recursive: true, force: true });
});
-
+
const getCompletions = async (content: string): Promise => {
- const tempFile = path.join(tempDir, 'test.json');
- await fs.promises.writeFile(tempFile, content);
-
- const uri = vscode.Uri.file(tempFile);
- const document = await vscode.workspace.openTextDocument(uri);
-
- const caretIndex = content.indexOf('');
- const position = document.positionAt(caretIndex);
-
- const completionItems = await autocompleteVisitor.getAutoCompleteContributor(document, position);
- return completionItems.map(item => item.label as string);
+ const tempFile = path.join(tempDir, "test.json");
+ await fs.promises.writeFile(tempFile, content);
+
+ const uri = vscode.Uri.file(tempFile);
+ const document = await vscode.workspace.openTextDocument(uri);
+
+ const caretIndex = content.indexOf("");
+ const position = document.positionAt(caretIndex);
+
+ const completionItems =
+ await autocompleteVisitor.getAutoCompleteContributor(
+ document,
+ position,
+ );
+ return completionItems.map((item) => item.label as string);
};
-
- test('empty json completion', async () => {
- const content = `{ "knn": { "" } }`;
- const completionResults = await getCompletions(content);
-
- assert.notStrictEqual(completionResults, null, "No completions found");
- for (const keyword of knnCbsContributor.keys) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+
+ test("empty json completion", async () => {
+ const content = `{ "knn": { "" } }`;
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ for (const keyword of knnCbsContributor.keys) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
-
- test('dont suggest keyword already exists', async () => {
- const content = `{
+
+ test("dont suggest keyword already exists", async () => {
+ const content = `{
"knn": {
"field": "vector_field",
""
}
}`;
- const completionResults = await getCompletions(content);
-
- assert.notStrictEqual(completionResults, null, "No completions found");
- const expected = ["k", "vector"];
- for (const keyword of expected) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ const expected = ["k", "vector"];
+ for (const keyword of expected) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
- });
\ No newline at end of file
+});
diff --git a/src/test/contributor/cbsQueryCodeCompletion.test.ts b/src/test/contributor/cbsQueryCodeCompletion.test.ts
index 1acb5112..930cd88c 100644
--- a/src/test/contributor/cbsQueryCodeCompletion.test.ts
+++ b/src/test/contributor/cbsQueryCodeCompletion.test.ts
@@ -1,54 +1,63 @@
-import * as assert from 'assert';
-import * as vscode from 'vscode';
-import * as path from 'path';
-import * as os from 'os';
-import * as fs from 'fs';
-import { AutocompleteVisitor } from '../../commands/fts/SearchWorkbench/contributor/autoCompleteVisitor';
-import { queryCbsContributor } from '../../commands/fts/SearchWorkbench/contributor/queryCbsContributor';
-import { locationCbsContributor } from '../../commands/fts/SearchWorkbench/contributor/locationCbsContributor';
-
-suite('CBSQueryCodeCompletion Test Suite', () => {
+import * as assert from "assert";
+import * as vscode from "vscode";
+import * as path from "path";
+import * as os from "os";
+import * as fs from "fs";
+import { AutocompleteVisitor } from "../../commands/fts/SearchWorkbench/contributor/autoCompleteVisitor";
+import { queryCbsContributor } from "../../commands/fts/SearchWorkbench/contributor/queryCbsContributor";
+import { locationCbsContributor } from "../../commands/fts/SearchWorkbench/contributor/locationCbsContributor";
+
+suite("CBSQueryCodeCompletion Test Suite", () => {
let autocompleteVisitor: AutocompleteVisitor;
let tempDir: string;
-
+
setup(async () => {
- autocompleteVisitor = new AutocompleteVisitor();
- tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'vscode-test-'));
+ autocompleteVisitor = new AutocompleteVisitor();
+ tempDir = await fs.promises.mkdtemp(
+ path.join(os.tmpdir(), "vscode-test-"),
+ );
});
-
+
teardown(async () => {
- await fs.promises.rm(tempDir, { recursive: true, force: true });
+ await fs.promises.rm(tempDir, { recursive: true, force: true });
});
-
+
const getCompletions = async (content: string): Promise => {
- const tempFile = path.join(tempDir, 'test.json');
- await fs.promises.writeFile(tempFile, content);
-
- const uri = vscode.Uri.file(tempFile);
- const document = await vscode.workspace.openTextDocument(uri);
-
- const caretIndex = content.indexOf('');
- const position = document.positionAt(caretIndex);
- const completionItems = await autocompleteVisitor.getAutoCompleteContributor(document, position);
- return completionItems.map(item => item.label as string);
+ const tempFile = path.join(tempDir, "test.json");
+ await fs.promises.writeFile(tempFile, content);
+
+ const uri = vscode.Uri.file(tempFile);
+ const document = await vscode.workspace.openTextDocument(uri);
+
+ const caretIndex = content.indexOf("");
+ const position = document.positionAt(caretIndex);
+ const completionItems =
+ await autocompleteVisitor.getAutoCompleteContributor(
+ document,
+ position,
+ );
+ return completionItems.map((item) => item.label as string);
};
-
- test('query completion', async () => {
- const content = `{
+
+ test("query completion", async () => {
+ const content = `{
"query": {
""
}
}`;
- const completionResults = await getCompletions(content);
-
- assert.notStrictEqual(completionResults, null, "No completions found");
- for (const keyword of queryCbsContributor.allQueryKeys) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ for (const keyword of queryCbsContributor.allQueryKeys) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
-
- test('query completion conjuncts', async () => {
- const content = `{
+
+ test("query completion conjuncts", async () => {
+ const content = `{
"query": {
"conjuncts":[
{
@@ -57,16 +66,19 @@ suite('CBSQueryCodeCompletion Test Suite', () => {
]
}
}`;
- const completionResults = await getCompletions(content);
-
- assert.notStrictEqual(completionResults, null, "No completions found");
- for (const keyword of queryCbsContributor.allQueryKeys) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ for (const keyword of queryCbsContributor.allQueryKeys) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
-
- test('query completion disjuncts', async () => {
- const content = `{
+
+ test("query completion disjuncts", async () => {
+ const content = `{
"query": {
"disjuncts":[
{
@@ -75,235 +87,302 @@ suite('CBSQueryCodeCompletion Test Suite', () => {
]
}
}`;
- const completionResults = await getCompletions(content);
-
- assert.notStrictEqual(completionResults, null, "No completions found");
- for (const keyword of queryCbsContributor.allQueryKeys) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ for (const keyword of queryCbsContributor.allQueryKeys) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
-
- test('query completion disjuncts no recommendation', async () => {
- const content = `{
+
+ test("query completion disjuncts no recommendation", async () => {
+ const content = `{
"query": {
"disjuncts":[
""
]
}
}`;
- const completionResults = await getCompletions(content);
- assert.strictEqual(completionResults.length, 0);
+ const completionResults = await getCompletions(content);
+ assert.strictEqual(completionResults.length, 0);
});
-
- test('query completion conjuncts no recommendation', async () => {
- const content = `{
+
+ test("query completion conjuncts no recommendation", async () => {
+ const content = `{
"query": {
"conjuncts":[
""
]
}
}`;
- const completionResults = await getCompletions(content);
- assert.strictEqual(completionResults.length, 0);
+ const completionResults = await getCompletions(content);
+ assert.strictEqual(completionResults.length, 0);
});
-
- test('query completion empty', async () => {
- const content = `{
+
+ test("query completion empty", async () => {
+ const content = `{
"query": {
"query": "",
}
}`;
- const completionResults = await getCompletions(content);
- assert.strictEqual(completionResults.length, 0);
+ const completionResults = await getCompletions(content);
+ assert.strictEqual(completionResults.length, 0);
});
-
- test('match', async () => {
- const content = `{
+
+ test("match", async () => {
+ const content = `{
"query": {
"match":"",
""
}
}`;
- const completionResults = await getCompletions(content);
- const expected = ["field", "analyzer", "operator", "boost", "fuzziness", "prefix_length"];
- for (const keyword of expected) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+ const completionResults = await getCompletions(content);
+ const expected = [
+ "field",
+ "analyzer",
+ "operator",
+ "boost",
+ "fuzziness",
+ "prefix_length",
+ ];
+ for (const keyword of expected) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
-
- test('operator', async () => {
- const content = `{
+
+ test("operator", async () => {
+ const content = `{
"query": {
"operator": "or",
""
}
}`;
- const completionResults = await getCompletions(content);
- const expected = ["field", "analyzer", "boost", "fuzziness", "prefix_length"];
- for (const keyword of expected) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+ const completionResults = await getCompletions(content);
+ const expected = [
+ "field",
+ "analyzer",
+ "boost",
+ "fuzziness",
+ "prefix_length",
+ ];
+ for (const keyword of expected) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
-
- test('bool', async () => {
- const content = `{
+
+ test("bool", async () => {
+ const content = `{
"query": {
"bool": true
""
}
}`;
- const completionResults = await getCompletions(content);
- const expected = ["field", "boost"];
- for (const keyword of expected) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+ const completionResults = await getCompletions(content);
+ const expected = ["field", "boost"];
+ for (const keyword of expected) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
-
- test('prefix', async () => {
- const content = `{
+
+ test("prefix", async () => {
+ const content = `{
"query": {
"prefix": ""
""
}
}`;
- const completionResults = await getCompletions(content);
- const expected = ["field", "boost"];
- for (const keyword of expected) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+ const completionResults = await getCompletions(content);
+ const expected = ["field", "boost"];
+ for (const keyword of expected) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
-
- test('regex', async () => {
- const content = `{
+
+ test("regex", async () => {
+ const content = `{
"query": {
"regexp": ""
""
}
}`;
- const completionResults = await getCompletions(content);
- const expected = ["field", "boost"];
- for (const keyword of expected) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+ const completionResults = await getCompletions(content);
+ const expected = ["field", "boost"];
+ for (const keyword of expected) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
-
- test('term', async () => {
- const content = `{
+
+ test("term", async () => {
+ const content = `{
"query": {
"term": ""
""
}
}`;
- const completionResults = await getCompletions(content);
- const expected = ["field", "boost", "fuzziness"];
- for (const keyword of expected) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+ const completionResults = await getCompletions(content);
+ const expected = ["field", "boost", "fuzziness"];
+ for (const keyword of expected) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
-
- test('terms', async () => {
- const content = `{
+
+ test("terms", async () => {
+ const content = `{
"query": {
"terms": []
""
}
}`;
- const completionResults = await getCompletions(content);
- const expected = ["field", "boost"];
- for (const keyword of expected) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+ const completionResults = await getCompletions(content);
+ const expected = ["field", "boost"];
+ for (const keyword of expected) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
-
- test('wildcard', async () => {
- const content = `{
+
+ test("wildcard", async () => {
+ const content = `{
"query": {
"wildcard": "*"
""
}
}`;
- const completionResults = await getCompletions(content);
- const expected = ["field", "boost"];
- for (const keyword of expected) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+ const completionResults = await getCompletions(content);
+ const expected = ["field", "boost"];
+ for (const keyword of expected) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
-
- test('numeric min', async () => {
- const content = `{
+
+ test("numeric min", async () => {
+ const content = `{
"query": {
"min": 3,
""
}
}`;
- const completionResults = await getCompletions(content);
- const expected = ["max", "inclusive_min", "inclusive_max", "field", "boost"];
- for (const keyword of expected) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+ const completionResults = await getCompletions(content);
+ const expected = [
+ "max",
+ "inclusive_min",
+ "inclusive_max",
+ "field",
+ "boost",
+ ];
+ for (const keyword of expected) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
-
- test('numeric min max', async () => {
- const content = `{
+
+ test("numeric min max", async () => {
+ const content = `{
"query": {
"min": 3,
"min": 10,
""
}
}`;
- const completionResults = await getCompletions(content);
- const expected = ["inclusive_min", "inclusive_max", "field", "boost"];
- for (const keyword of expected) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+ const completionResults = await getCompletions(content);
+ const expected = ["inclusive_min", "inclusive_max", "field", "boost"];
+ for (const keyword of expected) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
-
- test('date start', async () => {
- const content = `{
+
+ test("date start", async () => {
+ const content = `{
"query": {
"start": "2001-10-09T10:20:30-08:00",
""
}
}`;
- const completionResults = await getCompletions(content);
- const expected = ["end", "inclusive_start", "inclusive_end", "field", "boost"];
- for (const keyword of expected) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+ const completionResults = await getCompletions(content);
+ const expected = [
+ "end",
+ "inclusive_start",
+ "inclusive_end",
+ "field",
+ "boost",
+ ];
+ for (const keyword of expected) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
-
- test('date start inclusive end', async () => {
- const content = `{
+
+ test("date start inclusive end", async () => {
+ const content = `{
"query": {
"start": "2001-10-09T10:20:30-08:00",
"inclusive_end": false,
""
}
}`;
- const completionResults = await getCompletions(content);
- const expected = ["end", "inclusive_start", "field", "boost"];
- for (const keyword of expected) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+ const completionResults = await getCompletions(content);
+ const expected = ["end", "inclusive_start", "field", "boost"];
+ for (const keyword of expected) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
-
- test('date inclusive end', async () => {
- const content = `{
+
+ test("date inclusive end", async () => {
+ const content = `{
"query": {
"inclusive_start": false,
""
}
}`;
- const completionResults = await getCompletions(content);
- const expected = ["start", "end", "inclusive_end", "field", "boost"];
- for (const keyword of expected) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+ const completionResults = await getCompletions(content);
+ const expected = ["start", "end", "inclusive_end", "field", "boost"];
+ for (const keyword of expected) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
-
- test('distance', async () => {
- const content = `{
+
+ test("distance", async () => {
+ const content = `{
"query": {
"location": {
"lon": -2.235143,
@@ -312,29 +391,35 @@ suite('CBSQueryCodeCompletion Test Suite', () => {
""
}
}`;
- const completionResults = await getCompletions(content);
- const expected = ["distance", "field", "boost"];
- for (const keyword of expected) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+ const completionResults = await getCompletions(content);
+ const expected = ["distance", "field", "boost"];
+ for (const keyword of expected) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
-
- test('rectangle', async () => {
- const content = `{
+
+ test("rectangle", async () => {
+ const content = `{
"query": {
"top_left": [-2.235143, 53.482358],
""
}
}`;
- const completionResults = await getCompletions(content);
- const expected = ["bottom_right", "field", "boost"];
- for (const keyword of expected) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+ const completionResults = await getCompletions(content);
+ const expected = ["bottom_right", "field", "boost"];
+ for (const keyword of expected) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
-
- test('polygon', async () => {
- const content = `{
+
+ test("polygon", async () => {
+ const content = `{
"query": {
"polygon_points": [
"37.79393211306212,-122.44234633404847",
@@ -347,54 +432,66 @@ suite('CBSQueryCodeCompletion Test Suite', () => {
""
}
}`;
- const completionResults = await getCompletions(content);
- const expected = ["field", "boost"];
- for (const keyword of expected) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+ const completionResults = await getCompletions(content);
+ const expected = ["field", "boost"];
+ for (const keyword of expected) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
-
- test('must', async () => {
- const content = `{
+
+ test("must", async () => {
+ const content = `{
"query":{
"must":{
""
}
}
}`;
- const completionResults = await getCompletions(content);
- assert.notStrictEqual(completionResults, null, "No completions found");
- assert.ok(completionResults.includes("conjuncts"), "Expected completion 'conjuncts' not found");
+ const completionResults = await getCompletions(content);
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ assert.ok(
+ completionResults.includes("conjuncts"),
+ "Expected completion 'conjuncts' not found",
+ );
});
-
- test('must not', async () => {
- const content = `{
+
+ test("must not", async () => {
+ const content = `{
"query":{
"must_not":{
""
}
}
}`;
- const completionResults = await getCompletions(content);
- assert.notStrictEqual(completionResults, null, "No completions found");
- assert.ok(completionResults.includes("disjuncts"), "Expected completion 'disjuncts' not found");
+ const completionResults = await getCompletions(content);
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ assert.ok(
+ completionResults.includes("disjuncts"),
+ "Expected completion 'disjuncts' not found",
+ );
});
-
- test('should', async () => {
- const content = `{
+
+ test("should", async () => {
+ const content = `{
"query":{
"disjuncts":{
""
}
}
}`;
- const completionResults = await getCompletions(content);
- assert.notStrictEqual(completionResults, null, "No completions found");
- assert.ok(completionResults.includes("disjuncts"), "Expected completion 'disjuncts' not found");
+ const completionResults = await getCompletions(content);
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ assert.ok(
+ completionResults.includes("disjuncts"),
+ "Expected completion 'disjuncts' not found",
+ );
});
-
- test('top left', async () => {
- const content = `{
+
+ test("top left", async () => {
+ const content = `{
"query": {
"top_left": {""},
"bottom_right": {
@@ -404,15 +501,18 @@ suite('CBSQueryCodeCompletion Test Suite', () => {
"field": "geo"
}
}`;
- const completionResults = await getCompletions(content);
- assert.notStrictEqual(completionResults, null, "No completions found");
- for (const keyword of locationCbsContributor.keys) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+ const completionResults = await getCompletions(content);
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ for (const keyword of locationCbsContributor.keys) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
-
- test('bottom right', async () => {
- const content = `{
+
+ test("bottom right", async () => {
+ const content = `{
"query": {
"top_left": [-2.235143, 53.482358],
"bottom_right": {
@@ -422,13 +522,16 @@ suite('CBSQueryCodeCompletion Test Suite', () => {
"field": "geo"
}
}`;
- const completionResults = await getCompletions(content);
- assert.notStrictEqual(completionResults, null, "No completions found");
- assert.ok(completionResults.includes("lat"), "Expected completion 'lat' not found");
+ const completionResults = await getCompletions(content);
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ assert.ok(
+ completionResults.includes("lat"),
+ "Expected completion 'lat' not found",
+ );
});
-
- test('location', async () => {
- const content = `{
+
+ test("location", async () => {
+ const content = `{
"query": {
"location": {
""
@@ -437,10 +540,13 @@ suite('CBSQueryCodeCompletion Test Suite', () => {
"field": "geo"
}
}`;
- const completionResults = await getCompletions(content);
- assert.notStrictEqual(completionResults, null, "No completions found");
- for (const keyword of locationCbsContributor.keys) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+ const completionResults = await getCompletions(content);
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ for (const keyword of locationCbsContributor.keys) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
- });
\ No newline at end of file
+});
diff --git a/src/test/contributor/cbsRootCodeCompletion.test.ts b/src/test/contributor/cbsRootCodeCompletion.test.ts
index be2a2a65..c7af0725 100644
--- a/src/test/contributor/cbsRootCodeCompletion.test.ts
+++ b/src/test/contributor/cbsRootCodeCompletion.test.ts
@@ -1,77 +1,92 @@
-import * as assert from 'assert';
-import * as vscode from 'vscode';
-import * as path from 'path';
-import * as os from 'os';
-import * as fs from 'fs';
-import { AutocompleteVisitor } from '../../commands/fts/SearchWorkbench/contributor/autoCompleteVisitor';
+import * as assert from "assert";
+import * as vscode from "vscode";
+import * as path from "path";
+import * as os from "os";
+import * as fs from "fs";
+import { AutocompleteVisitor } from "../../commands/fts/SearchWorkbench/contributor/autoCompleteVisitor";
-suite('CBSRootCodeCompletion Test Suite', () => {
+suite("CBSRootCodeCompletion Test Suite", () => {
let autocompleteVisitor: AutocompleteVisitor;
let tempDir: string;
-
+
setup(async () => {
- autocompleteVisitor = new AutocompleteVisitor();
- tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'vscode-test-'));
+ autocompleteVisitor = new AutocompleteVisitor();
+ tempDir = await fs.promises.mkdtemp(
+ path.join(os.tmpdir(), "vscode-test-"),
+ );
});
-
+
teardown(async () => {
- await fs.promises.rm(tempDir, { recursive: true, force: true });
+ await fs.promises.rm(tempDir, { recursive: true, force: true });
});
-
+
const getCompletions = async (content: string): Promise => {
- const tempFile = path.join(tempDir, 'test.json');
- await fs.promises.writeFile(tempFile, content);
-
- const uri = vscode.Uri.file(tempFile);
- const document = await vscode.workspace.openTextDocument(uri);
-
- const caretIndex = content.indexOf('');
- const position = document.positionAt(caretIndex);
-
- const completionItems = await autocompleteVisitor.getAutoCompleteContributor(document, position);
- return completionItems.map(item => item.label as string);
+ const tempFile = path.join(tempDir, "test.json");
+ await fs.promises.writeFile(tempFile, content);
+
+ const uri = vscode.Uri.file(tempFile);
+ const document = await vscode.workspace.openTextDocument(uri);
+
+ const caretIndex = content.indexOf("");
+ const position = document.positionAt(caretIndex);
+
+ const completionItems =
+ await autocompleteVisitor.getAutoCompleteContributor(
+ document,
+ position,
+ );
+ return completionItems.map((item) => item.label as string);
};
-
- test('empty json completion', async () => {
- const content = `{}`;
- const completionResults = await getCompletions(content);
-
- assert.notStrictEqual(completionResults, null, "No completions found");
- const expected = autocompleteVisitor.topLevelKeywords.map(e => `"${e}"`);
- for (const keyword of expected) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+
+ test("empty json completion", async () => {
+ const content = `{}`;
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ const expected = autocompleteVisitor.topLevelKeywords.map(
+ (e) => `"${e}"`,
+ );
+ for (const keyword of expected) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
-
- test('dont suggest keyword already exists', async () => {
- const content = `{
+
+ test("dont suggest keyword already exists", async () => {
+ const content = `{
"query": {},
}`;
- const completionResults = await getCompletions(content);
-
- assert.notStrictEqual(completionResults, null, "No completions found");
- const expected = autocompleteVisitor.topLevelKeywords
- .filter(e => e !== "query")
- .map(e => `"${e}"`);
- for (const keyword of expected) {
- assert.ok(completionResults.includes(keyword), `Expected completion '${keyword}' not found`);
- }
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ const expected = autocompleteVisitor.topLevelKeywords
+ .filter((e) => e !== "query")
+ .map((e) => `"${e}"`);
+ for (const keyword of expected) {
+ assert.ok(
+ completionResults.includes(keyword),
+ `Expected completion '${keyword}' not found`,
+ );
+ }
});
-
-
- test('score completion', async () => {
- const content = `{
+ test("score completion", async () => {
+ const content = `{
"query": {
"query": "your_query_here"
},
"fields": ["*"],
"score": ""
}`;
- const completionResults = await getCompletions(content);
-
- assert.notStrictEqual(completionResults, null, "No completions found");
- assert.ok(completionResults.includes("none"), "Expected completion 'none' not found");
+ const completionResults = await getCompletions(content);
+
+ assert.notStrictEqual(completionResults, null, "No completions found");
+ assert.ok(
+ completionResults.includes("none"),
+ "Expected completion 'none' not found",
+ );
});
- });
\ No newline at end of file
+});
diff --git a/src/test/contributor/cbsShapeCodeCompletion.test.ts b/src/test/contributor/cbsShapeCodeCompletion.test.ts
index 64f12e9d..0b997f9a 100644
--- a/src/test/contributor/cbsShapeCodeCompletion.test.ts
+++ b/src/test/contributor/cbsShapeCodeCompletion.test.ts
@@ -1,39 +1,45 @@
-import * as assert from 'assert';
-import * as vscode from 'vscode';
-import * as path from 'path';
-import * as os from 'os';
-import * as fs from 'fs';
-import { AutocompleteVisitor } from '../../commands/fts/SearchWorkbench/contributor/autoCompleteVisitor';
+import * as assert from "assert";
+import * as vscode from "vscode";
+import * as path from "path";
+import * as os from "os";
+import * as fs from "fs";
+import { AutocompleteVisitor } from "../../commands/fts/SearchWorkbench/contributor/autoCompleteVisitor";
-suite('CBSShapeCodeCompletion Test Suite', () => {
+suite("CBSShapeCodeCompletion Test Suite", () => {
let autocompleteVisitor: AutocompleteVisitor;
let tempDir: string;
-
+
setup(async () => {
- autocompleteVisitor = new AutocompleteVisitor();
- tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'vscode-test-'));
+ autocompleteVisitor = new AutocompleteVisitor();
+ tempDir = await fs.promises.mkdtemp(
+ path.join(os.tmpdir(), "vscode-test-"),
+ );
});
-
+
teardown(async () => {
- await fs.promises.rm(tempDir, { recursive: true, force: true });
+ await fs.promises.rm(tempDir, { recursive: true, force: true });
});
-
+
const getCompletions = async (content: string): Promise => {
- const tempFile = path.join(tempDir, 'test.json');
- await fs.promises.writeFile(tempFile, content);
-
- const uri = vscode.Uri.file(tempFile);
- const document = await vscode.workspace.openTextDocument(uri);
-
- const caretIndex = content.indexOf('');
- const position = document.positionAt(caretIndex);
-
- const completionItems = await autocompleteVisitor.getAutoCompleteContributor(document, position);
- return completionItems.map(item => item.label as string);
+ const tempFile = path.join(tempDir, "test.json");
+ await fs.promises.writeFile(tempFile, content);
+
+ const uri = vscode.Uri.file(tempFile);
+ const document = await vscode.workspace.openTextDocument(uri);
+
+ const caretIndex = content.indexOf("