mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-13 17:22:15 -05:00
Kusto extension for ADS (#11752)
* Kusto extension * Add kusto to extensions.ts * Remove objectExplorerNodeProvider * Removed some BDC items + CR cleanup * Cleanup unused strings in package.nls.json * Remove unused svgs, and some cleanup * Bringing objectExplorerNode back and hygiene changes * rename to KustoObjectExplorerNodeProvider * rename to KustoIconProvider * Cleanup SQL code * Fix compilation error * Clean up in objectExplorerNodeProvider folder * Some more clean up based on comments * apiWrapper add * changed to camelCase * Remove unused functions/files * Removed AgentServicesFeature * dacfx, cms, schemacompare clean up * Clean up and addressed few comments * Remove apWrapper from kusto extension * Addressed few comments * credentialstore and escapeexception changes * Added strict check for Kusto extension * Fix error and addressed comment * Saving Kusto files shoulf default to .kql * package.json changes * Fix objectExplorerNodeProvider * Amir/kusto fix (#11972) * Add the compiled extensions.js * Fix strict compile rules Co-authored-by: Monica Gupta <mogupt@microsoft.com> Co-authored-by: Amir Omidi <amomidi@microsoft.com>
This commit is contained in:
@@ -172,6 +172,7 @@ const copyrightFilter = [
|
||||
'!extensions/import/flatfileimportservice/**',
|
||||
'!extensions/notebook/src/prompts/**',
|
||||
'!extensions/mssql/src/prompts/**',
|
||||
'!extensions/kusto/src/prompts/**',
|
||||
'!extensions/notebook/resources/jupyter_config/**',
|
||||
'!extensions/query-history/images/**',
|
||||
'!**/*.gif',
|
||||
|
||||
@@ -218,6 +218,7 @@ const externalExtensions = [
|
||||
'schema-compare',
|
||||
'cms',
|
||||
'query-history',
|
||||
'kusto',
|
||||
'liveshare',
|
||||
'sql-database-projects',
|
||||
'machine-learning',
|
||||
|
||||
@@ -252,6 +252,7 @@ const externalExtensions = [
|
||||
'schema-compare',
|
||||
'cms',
|
||||
'query-history',
|
||||
'kusto',
|
||||
'liveshare',
|
||||
'sql-database-projects',
|
||||
'machine-learning',
|
||||
|
||||
1
extensions/kusto/.gitignore
vendored
Normal file
1
extensions/kusto/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
sqltoolsservice
|
||||
6
extensions/kusto/.vscodeignore
Normal file
6
extensions/kusto/.vscodeignore
Normal file
@@ -0,0 +1,6 @@
|
||||
src/**
|
||||
out/**
|
||||
tsconfig.json
|
||||
extension.webpack.config.js
|
||||
yarn.lock
|
||||
.vscode
|
||||
26
extensions/kusto/config.json
Normal file
26
extensions/kusto/config.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"downloadUrl": "https://github.com/Microsoft/sqltoolsservice/releases/download/v{#version#}/microsoft.sqltools.servicelayer-{#fileName#}",
|
||||
"version": "2.0.0-release.15",
|
||||
"downloadFileNames": {
|
||||
"Windows_86": "win-x86-netcoreapp2.2.zip",
|
||||
"Windows_64": "win-x64-netcoreapp2.2.zip",
|
||||
"OSX": "osx-x64-netcoreapp2.2.tar.gz",
|
||||
"CentOS_7": "rhel-x64-netcoreapp2.2.tar.gz",
|
||||
"Debian_8": "rhel-x64-netcoreapp2.2.tar.gz",
|
||||
"Fedora_23": "rhel-x64-netcoreapp2.2.tar.gz",
|
||||
"OpenSUSE_13_2": "rhel-x64-netcoreapp2.2.tar.gz",
|
||||
"RHEL_7": "rhel-x64-netcoreapp2.2.tar.gz",
|
||||
"SLES_12_2": "rhel-x64-netcoreapp2.2.tar.gz",
|
||||
"Ubuntu_14": "rhel-x64-netcoreapp2.2.tar.gz",
|
||||
"Ubuntu_16": "rhel-x64-netcoreapp2.2.tar.gz"
|
||||
},
|
||||
"installDirectory": "../sqltoolsservice/{#platform#}/{#version#}",
|
||||
"executableFiles": ["MicrosoftKustoServiceLayer.exe", "MicrosoftKustoServiceLayer"],
|
||||
"retry": {
|
||||
"retries": 15,
|
||||
"factor": 2,
|
||||
"minTimeout": 1000,
|
||||
"maxTimeout": 300000,
|
||||
"randomize": false
|
||||
}
|
||||
}
|
||||
17
extensions/kusto/extension.webpack.config.js
Normal file
17
extensions/kusto/extension.webpack.config.js
Normal file
@@ -0,0 +1,17 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
//@ts-check
|
||||
|
||||
'use strict';
|
||||
|
||||
const withDefaults = require('../shared.webpack.config');
|
||||
|
||||
module.exports = withDefaults({
|
||||
context: __dirname,
|
||||
entry: {
|
||||
main: './src/main.ts'
|
||||
}
|
||||
});
|
||||
73
extensions/kusto/language-configuration.json
Normal file
73
extensions/kusto/language-configuration.json
Normal file
@@ -0,0 +1,73 @@
|
||||
// If changing this file please also submit the change in kusto-language-server language-configuration.json
|
||||
{
|
||||
"comments": {
|
||||
// symbol used for single line comment. Remove this entry if your language does not support line comments
|
||||
"lineComment": "//",
|
||||
// symbols used for start and end a block comment. Remove this entry if your language does not support block comments
|
||||
"blockComment": [
|
||||
"/*",
|
||||
"*/"
|
||||
]
|
||||
},
|
||||
// symbols used as brackets
|
||||
"brackets": [
|
||||
[
|
||||
"{",
|
||||
"}"
|
||||
],
|
||||
[
|
||||
"[",
|
||||
"]"
|
||||
],
|
||||
[
|
||||
"(",
|
||||
")"
|
||||
]
|
||||
],
|
||||
// symbols that are auto closed when typing
|
||||
"autoClosingPairs": [
|
||||
[
|
||||
"{",
|
||||
"}"
|
||||
],
|
||||
[
|
||||
"[",
|
||||
"]"
|
||||
],
|
||||
[
|
||||
"(",
|
||||
")"
|
||||
],
|
||||
[
|
||||
"\"",
|
||||
"\""
|
||||
],
|
||||
[
|
||||
"'",
|
||||
"'"
|
||||
]
|
||||
],
|
||||
// symbols that that can be used to surround a selection
|
||||
"surroundingPairs": [
|
||||
[
|
||||
"{",
|
||||
"}"
|
||||
],
|
||||
[
|
||||
"[",
|
||||
"]"
|
||||
],
|
||||
[
|
||||
"(",
|
||||
")"
|
||||
],
|
||||
[
|
||||
"\"",
|
||||
"\""
|
||||
],
|
||||
[
|
||||
"'",
|
||||
"'"
|
||||
]
|
||||
]
|
||||
}
|
||||
418
extensions/kusto/package.json
Normal file
418
extensions/kusto/package.json
Normal file
@@ -0,0 +1,418 @@
|
||||
{
|
||||
"name": "kusto",
|
||||
"version": "0.1.0",
|
||||
"publisher": "Microsoft",
|
||||
"aiKey": "AIF-444c3af9-8e69-4462-ab49-4191e6ad1916",
|
||||
"activationEvents": [
|
||||
"*"
|
||||
],
|
||||
"engines": {
|
||||
"vscode": "*",
|
||||
"azdata": ">=1.22.0"
|
||||
},
|
||||
"main": "./out/main",
|
||||
"typings": "./src/kusto",
|
||||
"scripts": {
|
||||
"compile": "gulp compile-extension:kusto-client",
|
||||
"update-grammar": "node ../../build/npm/update-grammar.js Microsoft/vscode-kusto syntaxes/SQL.plist ./syntaxes/sql.tmLanguage.json"
|
||||
},
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "kustoCluster.task.newNotebook",
|
||||
"title": "%notebook.command.new%",
|
||||
"icon": {
|
||||
"dark": "resources/dark/new_notebook_inverse.svg",
|
||||
"light": "resources/light/new_notebook.svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "kustoCluster.task.openNotebook",
|
||||
"title": "%notebook.command.open%",
|
||||
"icon": {
|
||||
"dark": "resources/dark/open_notebook_inverse.svg",
|
||||
"light": "resources/light/open_notebook.svg"
|
||||
}
|
||||
}
|
||||
],
|
||||
"languages": [
|
||||
{
|
||||
"id": "kusto",
|
||||
"aliases": [
|
||||
"Kusto",
|
||||
"kusto"
|
||||
],
|
||||
"extensions": [
|
||||
".kql",
|
||||
".kusto",
|
||||
".csl"
|
||||
],
|
||||
"configuration": "./language-configuration.json"
|
||||
}
|
||||
],
|
||||
"grammars": [
|
||||
{
|
||||
"language": "kusto",
|
||||
"scopeName": "source.kusto",
|
||||
"path": "./syntaxes/kusto.tmLanguage"
|
||||
}
|
||||
],
|
||||
"themes": [
|
||||
{
|
||||
"label": "[Kuskus] Kusto (Dark)",
|
||||
"uiTheme": "vs-dark",
|
||||
"path": "./themes/kuskus-kusto-dark.json"
|
||||
}
|
||||
],
|
||||
"outputChannels": [
|
||||
"Kusto"
|
||||
],
|
||||
"snippets": [
|
||||
{
|
||||
"language": "kusto",
|
||||
"path": "./snippets/kusto.json"
|
||||
}
|
||||
],
|
||||
"configuration": {
|
||||
"type": "object",
|
||||
"title": "%kusto.configuration.title%",
|
||||
"properties": {
|
||||
"kusto.query.displayBitAsNumber": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"description": "%kusto.query.displayBitAsNumber%"
|
||||
},
|
||||
"kusto.format.alignColumnDefinitionsInColumns": {
|
||||
"type": "boolean",
|
||||
"description": "%kusto.format.alignColumnDefinitionsInColumns%",
|
||||
"default": false
|
||||
},
|
||||
"kusto.format.datatypeCasing": {
|
||||
"type": "string",
|
||||
"description": "%kusto.format.datatypeCasing%",
|
||||
"default": "none",
|
||||
"enum": [
|
||||
"none",
|
||||
"uppercase",
|
||||
"lowercase"
|
||||
]
|
||||
},
|
||||
"kusto.format.keywordCasing": {
|
||||
"type": "string",
|
||||
"description": "%kusto.format.keywordCasing%",
|
||||
"default": "none",
|
||||
"enum": [
|
||||
"none",
|
||||
"uppercase",
|
||||
"lowercase"
|
||||
]
|
||||
},
|
||||
"kusto.logDebugInfo": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "%kusto.logDebugInfo%"
|
||||
},
|
||||
"kusto.tracingLevel": {
|
||||
"type": "string",
|
||||
"description": "%kusto.tracingLevel%",
|
||||
"default": "Critical",
|
||||
"enum": [
|
||||
"All",
|
||||
"Off",
|
||||
"Critical",
|
||||
"Error",
|
||||
"Warning",
|
||||
"Information",
|
||||
"Verbose"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"menus": {
|
||||
"commandPalette": [
|
||||
{
|
||||
"command": "kustoCluster.task.newNotebook",
|
||||
"when": "false"
|
||||
},
|
||||
{
|
||||
"command": "kustoCluster.task.openNotebook",
|
||||
"when": "false"
|
||||
}
|
||||
]
|
||||
},
|
||||
"dashboard": {
|
||||
"provider": "KUSTO",
|
||||
"flavors": [
|
||||
{
|
||||
"flavor": "cloud",
|
||||
"conditions": [
|
||||
{
|
||||
"field": "isCloud",
|
||||
"operator": "==",
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"databaseProperties": [
|
||||
{
|
||||
"displayName": "%cloud.databaseProperties.name%",
|
||||
"value": "name"
|
||||
},
|
||||
{
|
||||
"displayName": "%cloud.databaseProperties.size%",
|
||||
"value": "sizeInMB"
|
||||
}
|
||||
],
|
||||
"serverProperties": [
|
||||
{
|
||||
"displayName": "%cloud.serverProperties.summary%",
|
||||
"value": "summary"
|
||||
},
|
||||
{
|
||||
"displayName": "%cloud.serverProperties.machinesTotal%",
|
||||
"value": "machinesTotal"
|
||||
},
|
||||
{
|
||||
"displayName": "%cloud.serverProperties.diskCacheCapacity%",
|
||||
"value": "diskCacheCapacity"
|
||||
}
|
||||
],
|
||||
"databasesListProperties": [
|
||||
{
|
||||
"displayName": "%databasesListProperties.name%",
|
||||
"value": "name",
|
||||
"widthWeight": 60
|
||||
},
|
||||
{
|
||||
"displayName": "%databasesListProperties.size%",
|
||||
"value": "sizeInMB",
|
||||
"widthWeight": 20
|
||||
}
|
||||
],
|
||||
"objectsListProperties": [
|
||||
{
|
||||
"displayName": "%objectsListProperties.name%",
|
||||
"value": "name",
|
||||
"widthWeight": 60
|
||||
},
|
||||
{
|
||||
"displayName": "%objectsListProperties.metadataTypeName%",
|
||||
"value": "metadataTypeName",
|
||||
"widthWeight": 20
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"connectionProvider": {
|
||||
"providerId": "KUSTO",
|
||||
"languageMode": "kusto",
|
||||
"notebookKernelAlias": "Kusto",
|
||||
"displayName": "%kusto.provider.displayName%",
|
||||
"iconPath": [
|
||||
{
|
||||
"id": "kusto:cloud",
|
||||
"path": {
|
||||
"light": "resources/light/azureDE.svg",
|
||||
"dark": "resources/dark/azureDE_inverse.svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "kusto:cluster",
|
||||
"path": {
|
||||
"light": "resources/light/sql_bigdata_cluster.svg",
|
||||
"dark": "resources/dark/sql_bigdata_cluster_inverse.svg"
|
||||
}
|
||||
}
|
||||
],
|
||||
"connectionOptions": [
|
||||
{
|
||||
"specialValueType": "connectionName",
|
||||
"isIdentity": true,
|
||||
"name": "connectionName",
|
||||
"displayName": "%kusto.connectionOptions.connectionName.displayName%",
|
||||
"description": "%kusto.connectionOptions.connectionName.description%",
|
||||
"groupName": "Source",
|
||||
"valueType": "string",
|
||||
"defaultValue": null,
|
||||
"objectType": null,
|
||||
"categoryValues": null,
|
||||
"isRequired": false,
|
||||
"isArray": false
|
||||
},
|
||||
{
|
||||
"specialValueType": "serverName",
|
||||
"isIdentity": true,
|
||||
"name": "server",
|
||||
"displayName": "%kusto.connectionOptions.serverName.displayName%",
|
||||
"description": "%kusto.connectionOptions.serverName.description%",
|
||||
"groupName": "Source",
|
||||
"valueType": "string",
|
||||
"defaultValue": null,
|
||||
"objectType": null,
|
||||
"categoryValues": null,
|
||||
"isRequired": true,
|
||||
"isArray": false
|
||||
},
|
||||
{
|
||||
"specialValueType": "databaseName",
|
||||
"isIdentity": true,
|
||||
"name": "database",
|
||||
"displayName": "%kusto.connectionOptions.databaseName.displayName%",
|
||||
"description": "%kusto.connectionOptions.databaseName.description%",
|
||||
"groupName": "Source",
|
||||
"valueType": "string",
|
||||
"defaultValue": null,
|
||||
"objectType": null,
|
||||
"categoryValues": null,
|
||||
"isRequired": false,
|
||||
"isArray": false
|
||||
},
|
||||
{
|
||||
"specialValueType": "authType",
|
||||
"isIdentity": true,
|
||||
"name": "authenticationType",
|
||||
"displayName": "%kusto.connectionOptions.authType.displayName%",
|
||||
"description": "%kusto.connectionOptions.authType.description%",
|
||||
"groupName": "Security",
|
||||
"valueType": "category",
|
||||
"defaultValue": "AzureMFA",
|
||||
"objectType": null,
|
||||
"categoryValues": [
|
||||
{
|
||||
"displayName": "%kusto.connectionOptions.authType.categoryValues.azureMFA%",
|
||||
"name": "AzureMFA"
|
||||
}
|
||||
],
|
||||
"isRequired": true,
|
||||
"isArray": false
|
||||
},
|
||||
{
|
||||
"specialValueType": "userName",
|
||||
"isIdentity": true,
|
||||
"name": "user",
|
||||
"displayName": "%kusto.connectionOptions.userName.displayName%",
|
||||
"description": "%kusto.connectionOptions.userName.description%",
|
||||
"groupName": "Security",
|
||||
"valueType": "string",
|
||||
"defaultValue": null,
|
||||
"objectType": null,
|
||||
"categoryValues": null,
|
||||
"isRequired": true,
|
||||
"isArray": false
|
||||
},
|
||||
{
|
||||
"specialValueType": "password",
|
||||
"isIdentity": true,
|
||||
"name": "password",
|
||||
"displayName": "%kusto.connectionOptions.password.displayName%",
|
||||
"description": "%kusto.connectionOptions.password.description%",
|
||||
"groupName": "Security",
|
||||
"valueType": "password",
|
||||
"defaultValue": null,
|
||||
"objectType": null,
|
||||
"categoryValues": null,
|
||||
"isRequired": true,
|
||||
"isArray": false
|
||||
},
|
||||
{
|
||||
"specialValueType": null,
|
||||
"isIdentity": false,
|
||||
"name": "connectTimeout",
|
||||
"displayName": "%kusto.connectionOptions.connectTimeout.displayName%",
|
||||
"description": "%kusto.connectionOptions.connectTimeout.description%",
|
||||
"groupName": "Initialization",
|
||||
"valueType": "number",
|
||||
"defaultValue": "30",
|
||||
"objectType": null,
|
||||
"categoryValues": null,
|
||||
"isRequired": false,
|
||||
"isArray": false
|
||||
},
|
||||
{
|
||||
"specialValueType": null,
|
||||
"isIdentity": false,
|
||||
"name": "connectRetryCount",
|
||||
"displayName": "%kusto.connectionOptions.connectRetryCount.displayName%",
|
||||
"description": "%kusto.connectionOptions.connectRetryCount.description%",
|
||||
"groupName": "Connection Resiliency",
|
||||
"valueType": "number",
|
||||
"defaultValue": "1",
|
||||
"objectType": null,
|
||||
"categoryValues": null,
|
||||
"isRequired": false,
|
||||
"isArray": false
|
||||
},
|
||||
{
|
||||
"specialValueType": null,
|
||||
"isIdentity": false,
|
||||
"name": "connectRetryInterval",
|
||||
"displayName": "%kusto.connectionOptions.connectRetryInterval.displayName%",
|
||||
"description": "%kusto.connectionOptions.connectRetryInterval.description%",
|
||||
"groupName": "Connection Resiliency",
|
||||
"valueType": "number",
|
||||
"defaultValue": "10",
|
||||
"objectType": null,
|
||||
"categoryValues": null,
|
||||
"isRequired": false,
|
||||
"isArray": false
|
||||
},
|
||||
{
|
||||
"specialValueType": "appName",
|
||||
"isIdentity": false,
|
||||
"name": "applicationName",
|
||||
"displayName": "%kusto.connectionOptions.applicationName.displayName%",
|
||||
"description": "%kusto.connectionOptions.applicationName.description%",
|
||||
"groupName": "Context",
|
||||
"valueType": "string",
|
||||
"defaultValue": null,
|
||||
"objectType": null,
|
||||
"categoryValues": null,
|
||||
"isRequired": false,
|
||||
"isArray": false
|
||||
},
|
||||
{
|
||||
"specialValueType": null,
|
||||
"isIdentity": false,
|
||||
"name": "workstationId",
|
||||
"displayName": "%kusto.connectionOptions.workstationId.displayName%",
|
||||
"description": "%kusto.connectionOptions.workstationId.description%",
|
||||
"groupName": "Context",
|
||||
"valueType": "string",
|
||||
"defaultValue": null,
|
||||
"objectType": null,
|
||||
"categoryValues": null,
|
||||
"isRequired": false,
|
||||
"isArray": false
|
||||
},
|
||||
{
|
||||
"specialValueType": null,
|
||||
"isIdentity": false,
|
||||
"name": "failoverPartner",
|
||||
"displayName": "%kusto.connectionOptions.failoverPartner.displayName%",
|
||||
"description": "%kusto.connectionOptions.failoverPartner.description%",
|
||||
"groupName": " Source",
|
||||
"valueType": "string",
|
||||
"defaultValue": null,
|
||||
"objectType": null,
|
||||
"categoryValues": null,
|
||||
"isRequired": false,
|
||||
"isArray": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"dataprotocol-client": "github:Microsoft/sqlops-dataprotocolclient#1.1.0",
|
||||
"figures": "^2.0.0",
|
||||
"find-remove": "1.2.1",
|
||||
"service-downloader": "github:anthonydresser/service-downloader#0.1.6",
|
||||
"vscode-extension-telemetry": "0.1.0",
|
||||
"vscode-languageclient": "5.2.1",
|
||||
"vscode-nls": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/kerberos": "^1.1.0",
|
||||
"@types/request": "^2.48.2",
|
||||
"@types/through2": "^2.0.34"
|
||||
}
|
||||
}
|
||||
52
extensions/kusto/package.nls.json
Normal file
52
extensions/kusto/package.nls.json
Normal file
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"notebook.command.new": "New Notebook",
|
||||
"notebook.command.open": "Open Notebook",
|
||||
|
||||
"cloud.databaseProperties.name": "Database Name",
|
||||
"cloud.databaseProperties.size": "Size (MB)",
|
||||
|
||||
"cloud.serverProperties.summary": "Status",
|
||||
"cloud.serverProperties.machinesTotal": "Total Machines in the cluster",
|
||||
"cloud.serverProperties.diskCacheCapacity": "% of Cluster data capacity used",
|
||||
|
||||
"databasesListProperties.name": "Name",
|
||||
"databasesListProperties.size": "Size (MB)",
|
||||
|
||||
"objectsListProperties.name": "Name",
|
||||
"objectsListProperties.metadataTypeName": "Type",
|
||||
|
||||
"kusto.configuration.title": "KUSTO configuration",
|
||||
"kusto.query.displayBitAsNumber": "Should BIT columns be displayed as numbers (1 or 0)? If false, BIT columns will be displayed as 'true' or 'false'",
|
||||
"kusto.format.alignColumnDefinitionsInColumns": "Should column definitions be aligned?",
|
||||
"kusto.format.datatypeCasing": "Should data types be formatted as UPPERCASE, lowercase, or none (not formatted)",
|
||||
"kusto.format.keywordCasing": "Should keywords be formatted as UPPERCASE, lowercase, or none (not formatted)",
|
||||
"kusto.logDebugInfo": "[Optional] Log debug output to the console (View -> Output) and then select appropriate output channel from the dropdown",
|
||||
"kusto.tracingLevel": "[Optional] Log level for backend services. Azure Data Studio generates a file name every time it starts and if the file already exists the logs entries are appended to that file. For cleanup of old log files see logRetentionMinutes and logFilesRemovalLimit settings. The default tracingLevel does not log much. Changing verbosity could lead to extensive logging and disk space requirements for the logs. Error includes Critical, Warning includes Error, Information includes Warning and Verbose includes Information",
|
||||
|
||||
"kusto.provider.displayName": "Kusto",
|
||||
"kusto.connectionOptions.connectionName.displayName": "Name (optional)",
|
||||
"kusto.connectionOptions.connectionName.description": "Custom name of the connection",
|
||||
"kusto.connectionOptions.serverName.displayName": "Cluster",
|
||||
"kusto.connectionOptions.serverName.description": "Kusto cluster name",
|
||||
"kusto.connectionOptions.databaseName.displayName": "Database",
|
||||
"kusto.connectionOptions.databaseName.description": "The name of the initial catalog or database in the data source",
|
||||
"kusto.connectionOptions.authType.displayName": "Authentication type",
|
||||
"kusto.connectionOptions.authType.description": "Specifies the method of authenticating with Kusto Server",
|
||||
"kusto.connectionOptions.authType.categoryValues.azureMFA": "Azure Active Directory - Universal with MFA support",
|
||||
"kusto.connectionOptions.userName.displayName": "User name",
|
||||
"kusto.connectionOptions.userName.description": "Indicates the user ID to be used when connecting to the data source",
|
||||
"kusto.connectionOptions.password.displayName": "Password",
|
||||
"kusto.connectionOptions.password.description": "Indicates the password to be used when connecting to the data source",
|
||||
"kusto.connectionOptions.connectTimeout.displayName": "Connect timeout",
|
||||
"kusto.connectionOptions.connectTimeout.description": "The length of time (in seconds) to wait for a connection to the server before terminating the attempt and generating an error",
|
||||
"kusto.connectionOptions.connectRetryCount.displayName": "Connect retry count",
|
||||
"kusto.connectionOptions.connectRetryCount.description": "Number of attempts to restore connection",
|
||||
"kusto.connectionOptions.connectRetryInterval.displayName": "Connect retry interval",
|
||||
"kusto.connectionOptions.connectRetryInterval.description": "Delay between attempts to restore connection",
|
||||
"kusto.connectionOptions.applicationName.displayName": "Application name",
|
||||
"kusto.connectionOptions.applicationName.description": "The name of the application",
|
||||
"kusto.connectionOptions.workstationId.displayName": "Workstation Id",
|
||||
"kusto.connectionOptions.workstationId.description": "The name of the workstation connecting to Kusto Server",
|
||||
"kusto.connectionOptions.failoverPartner.displayName": "Failover partner",
|
||||
"kusto.connectionOptions.failoverPartner.description": "The name or network address of the instance of Kusto Server that acts as a failover partner"
|
||||
}
|
||||
3
extensions/kusto/resources/dark/azureDE_inverse.svg
Normal file
3
extensions/kusto/resources/dark/azureDE_inverse.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M14.9844 0C15.1198 0 15.237 0.0494792 15.3359 0.148438C15.4349 0.247396 15.4844 0.364583 15.4844 0.5V14.4453C15.4844 14.5807 15.4349 14.6979 15.3359 14.7969C15.237 14.8958 15.1198 14.9453 14.9844 14.9453C14.849 14.9453 14.7318 14.8958 14.6328 14.7969L0.6875 0.851562C0.588542 0.752604 0.539062 0.635417 0.539062 0.5C0.539062 0.364583 0.588542 0.247396 0.6875 0.148438C0.786458 0.0494792 0.903646 0 1.03906 0H14.9844ZM14.4844 5.42969V1H10.2578L6.25 5.00781L10.5781 9.32812L14.4844 5.42969ZM8.84375 1H2.25L5.54688 4.29688L8.84375 1ZM11.2891 10.0391L14.4844 13.2344V6.84375L11.2891 10.0391ZM6.125 8.64844L6.82812 9.35156L0.828125 15.3516L0.125 14.6484L6.125 8.64844ZM4.24219 14.7656L8.24219 10.7656L8.95312 11.4766L4.95312 15.4766L4.24219 14.7656ZM4.71094 7.23438L0.710938 11.2344L0 10.5234L4 6.52344L4.71094 7.23438ZM9.60938 3.17188L10.4922 2.28125L11.375 3.17188L10.4922 4.05469L9.60938 3.17188ZM13.2031 4.97656L12.3203 5.85938L11.4297 4.97656L12.3203 4.09375L13.2031 4.97656ZM7.65625 5.10938L8.53906 4.22656L9.42188 5.10938L8.53906 5.99219L7.65625 5.10938ZM9.48438 6.92188L10.3672 6.03906L11.25 6.92188L10.3672 7.80469L9.48438 6.92188Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
1
extensions/kusto/resources/dark/new_notebook_inverse.svg
Normal file
1
extensions/kusto/resources/dark/new_notebook_inverse.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:#388a34;}</style></defs><title>new_notebook_inverse</title><path class="cls-1" d="M11.87,1.24V.33H9.13A3.78,3.78,0,0,0,7.92.52a3.48,3.48,0,0,0-1.07.58A3.6,3.6,0,0,0,5.78.52,3.78,3.78,0,0,0,4.57.33H1.83v.91H0V13.1H9.67v-.91H7a4,4,0,0,1,.47-.39A2.39,2.39,0,0,1,8,11.52a2.2,2.2,0,0,1,.53-.18,2.93,2.93,0,0,1,.61-.06h2.74V2.15h.91V9h.91V1.24Zm-9.13,0H4.57a3,3,0,0,1,1,.17,2.58,2.58,0,0,1,.85.49v8.93a3.94,3.94,0,0,0-.88-.35,3.73,3.73,0,0,0-.94-.12H2.74Zm-1.82,11v-10h.91v9.13H4.57a2.93,2.93,0,0,1,.61.06,2.55,2.55,0,0,1,.53.18,2.68,2.68,0,0,1,.49.28,3.29,3.29,0,0,1,.46.39Zm8.21-1.83a3.73,3.73,0,0,0-.94.12,4.22,4.22,0,0,0-.89.35V1.9a2.74,2.74,0,0,1,.86-.49,2.91,2.91,0,0,1,1-.17H11v9.12ZM12.87,10v2.2h-2.2v.91h3V10Z"/><polygon class="cls-2" points="16 12.19 16 13.13 13.8 13.13 13.8 15.33 12.87 15.33 12.87 13.13 10.67 13.13 10.67 12.19 12.87 12.19 12.87 9.99 13.8 9.99 13.8 12.19 16 12.19"/><path class="cls-2" d="M13.8,12.19V10h-.93v2.2h-2.2v.94h2.2v2.2h.93v-2.2H16v-.94Z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:#0095d7;}</style></defs><title>open_notebook_inverse</title><path class="cls-1" d="M12.55,4.21l-.08-.11h-.56l-.69.06a1.54,1.54,0,0,0-.23.29v8.69H9.18a3.32,3.32,0,0,0-.93.13,3.34,3.34,0,0,0-.87.34V4.76a2.88,2.88,0,0,1,.43-.31A5.58,5.58,0,0,1,8.29,3.3a2.63,2.63,0,0,0-.3.09A3.62,3.62,0,0,0,6.93,4a3.68,3.68,0,0,0-1.07-.57A3.58,3.58,0,0,0,4.67,3.2H2v.9H.15V15.85H13.72V5.48ZM2.86,4.1H4.67a2.61,2.61,0,0,1,1,.17,2.32,2.32,0,0,1,.86.49v8.85a3.27,3.27,0,0,0-.88-.34,3.22,3.22,0,0,0-.93-.13H2.86ZM1,15V5H2v9H4.67a3.94,3.94,0,0,1,.61.06,3.2,3.2,0,0,1,.52.18,4.19,4.19,0,0,1,.49.29,2.28,2.28,0,0,1,.45.39ZM12.8,15H7.11a2.7,2.7,0,0,1,.47-.39A2.83,2.83,0,0,1,8,14.28a3.42,3.42,0,0,1,.54-.18A3.81,3.81,0,0,1,9.18,14h2.73V5h.89Z"/><polygon class="cls-2" points="13.2 3.56 13.2 3.58 13.19 3.57 13.2 3.56"/><path class="cls-2" d="M13.19,3.57h0v0Z"/><polygon class="cls-2" points="13.2 3.56 13.2 3.58 13.19 3.57 13.2 3.56"/><polygon class="cls-2" points="14.21 1.65 14.19 1.65 14.19 1.63 14.21 1.65"/><path class="cls-2" d="M15.91,2.1,14.2,3.81l-.38.38-.62-.61v0l1-1H12.79a3.35,3.35,0,0,0-1.09.26h0a3.94,3.94,0,0,0-.86.52l-.24.21s0,0,0,0a3.3,3.3,0,0,0-.51.67,3.1,3.1,0,0,0-.26.47A3.41,3.41,0,0,0,9.5,6.11H8.6a4.68,4.68,0,0,1,.16-1.19A4.74,4.74,0,0,1,9,4.26a2.21,2.21,0,0,1,.2-.41,4.66,4.66,0,0,1,.36-.51c.1-.13.22-.26.34-.39a4.14,4.14,0,0,1,.66-.53,1.19,1.19,0,0,1,.23-.16,2.79,2.79,0,0,1,.34-.18l.31-.13.42-.14a4.32,4.32,0,0,1,1.19-.16h1.15l-1-1L13.82,0Z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
3
extensions/kusto/resources/light/azureDE.svg
Normal file
3
extensions/kusto/resources/light/azureDE.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M15.5 0C15.6354 0 15.7526 0.0494792 15.8516 0.148438C15.9505 0.247396 16 0.364583 16 0.5V14.4453C16 14.5807 15.9505 14.6979 15.8516 14.7969C15.7526 14.8958 15.6354 14.9453 15.5 14.9453C15.3646 14.9453 15.2474 14.8958 15.1484 14.7969L1.20312 0.851562C1.10417 0.752604 1.05469 0.635417 1.05469 0.5C1.05469 0.364583 1.10417 0.247396 1.20312 0.148438C1.30208 0.0494792 1.41927 0 1.55469 0H15.5ZM15 5.42969V1H10.7734L6.76562 5.00781L11.0938 9.32812L15 5.42969ZM9.35938 1H2.76562L6.0625 4.29688L9.35938 1ZM11.8047 10.0391L15 13.2344V6.84375L11.8047 10.0391ZM6.64062 8.64844L7.34375 9.35156L1.34375 15.3516L0.640625 14.6484L6.64062 8.64844ZM4.75781 14.7656L8.75781 10.7656L9.46875 11.4766L5.46875 15.4766L4.75781 14.7656ZM5.22656 7.23438L1.22656 11.2344L0.515625 10.5234L4.51562 6.52344L5.22656 7.23438ZM10.125 3.17188L11.0078 2.28125L11.8906 3.17188L11.0078 4.05469L10.125 3.17188ZM13.7188 4.97656L12.8359 5.85938L11.9453 4.97656L12.8359 4.09375L13.7188 4.97656ZM8.17188 5.10938L9.05469 4.22656L9.9375 5.10938L9.05469 5.99219L8.17188 5.10938ZM10 6.92188L10.8828 6.03906L11.7656 6.92188L10.8828 7.80469L10 6.92188Z" fill="#323130"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
1
extensions/kusto/resources/light/new_notebook.svg
Normal file
1
extensions/kusto/resources/light/new_notebook.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#388a34;}</style></defs><title>new_notebook</title><path d="M11.86,1.24V.33H9.13A3.78,3.78,0,0,0,7.91.52a3.48,3.48,0,0,0-1.07.58A3.6,3.6,0,0,0,5.78.52,3.78,3.78,0,0,0,4.57.33H1.83v.91H0V13.1H9.66v-.91H7a4,4,0,0,1,.47-.39A2.39,2.39,0,0,1,8,11.52a2.2,2.2,0,0,1,.53-.18,2.93,2.93,0,0,1,.61-.06h2.74V2.15h.91V9h.91V1.24Zm-9.13,0H4.57a3,3,0,0,1,1,.17,2.58,2.58,0,0,1,.85.49v8.93a3.94,3.94,0,0,0-.88-.35,3.73,3.73,0,0,0-.94-.12H2.73Zm-1.82,11v-10h.91v9.13H4.57a2.93,2.93,0,0,1,.61.06,2.55,2.55,0,0,1,.53.18,2.68,2.68,0,0,1,.49.28,3.29,3.29,0,0,1,.46.39Zm8.21-1.83a3.73,3.73,0,0,0-.94.12,4.22,4.22,0,0,0-.89.35V1.9a2.74,2.74,0,0,1,.86-.49,2.91,2.91,0,0,1,1-.17h1.82v9.12ZM12.86,10v2.2h-2.2v.91h3V10Z"/><polygon class="cls-1" points="15.99 12.19 15.99 13.13 13.79 13.13 13.79 15.33 12.87 15.33 12.87 13.13 10.66 13.13 10.66 12.19 12.87 12.19 12.87 9.99 13.79 9.99 13.79 12.19 15.99 12.19"/><path class="cls-1" d="M13.79,12.19V10h-.93v2.2h-2.2v.94h2.2v2.2h.93v-2.2H16v-.94Z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
1
extensions/kusto/resources/light/open_notebook.svg
Normal file
1
extensions/kusto/resources/light/open_notebook.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#00539c;}</style></defs><title>open_notebook</title><path d="M12.4,4.21l-.08-.11h-.56l-.69.06a1.54,1.54,0,0,0-.23.29v8.69H9a3.32,3.32,0,0,0-.93.13,3.34,3.34,0,0,0-.87.34V4.76a2.88,2.88,0,0,1,.43-.31A5.58,5.58,0,0,1,8.14,3.3a2.63,2.63,0,0,0-.3.09A3.62,3.62,0,0,0,6.78,4a3.68,3.68,0,0,0-1.07-.57A3.58,3.58,0,0,0,4.52,3.2H1.81v.9H0V15.85H13.57V5.48ZM2.71,4.1H4.52a2.61,2.61,0,0,1,1,.17,2.32,2.32,0,0,1,.86.49v8.85a3.27,3.27,0,0,0-.88-.34,3.22,3.22,0,0,0-.93-.13H2.71ZM.9,15V5h.91v9H4.52a3.94,3.94,0,0,1,.61.06,3.2,3.2,0,0,1,.52.18,4.19,4.19,0,0,1,.49.29,2.28,2.28,0,0,1,.45.39Zm11.75,0H7a2.7,2.7,0,0,1,.47-.39,2.83,2.83,0,0,1,.47-.29,3.42,3.42,0,0,1,.54-.18A3.81,3.81,0,0,1,9,14h2.73V5h.89Z"/><polygon class="cls-1" points="13.05 3.56 13.05 3.58 13.04 3.57 13.05 3.56"/><path class="cls-1" d="M13,3.57h0v0Z"/><polygon class="cls-1" points="13.05 3.56 13.05 3.58 13.04 3.57 13.05 3.56"/><polygon class="cls-1" points="14.06 1.65 14.04 1.65 14.04 1.63 14.06 1.65"/><path class="cls-1" d="M15.76,2.1,14,3.81l-.38.38L13,3.58v0l1-1H12.64a3.35,3.35,0,0,0-1.09.26h0a3.94,3.94,0,0,0-.86.52l-.24.21s0,0,0,0a3.3,3.3,0,0,0-.51.67,3.1,3.1,0,0,0-.26.47,3.41,3.41,0,0,0-.27,1.39h-.9a4.68,4.68,0,0,1,.16-1.19,4.74,4.74,0,0,1,.25-.66,2.21,2.21,0,0,1,.2-.41,4.66,4.66,0,0,1,.36-.51c.1-.13.22-.26.34-.39a4.14,4.14,0,0,1,.66-.53,1.19,1.19,0,0,1,.23-.16A2.79,2.79,0,0,1,11,2.08l.31-.13.42-.14a4.32,4.32,0,0,1,1.19-.16h1.15l-1-1L13.67,0Z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
10
extensions/kusto/snippets/kusto.json
Normal file
10
extensions/kusto/snippets/kusto.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"Top N by count": {
|
||||
"prefix": "kustoTopNested",
|
||||
"body": [
|
||||
"// Get top ${1:N} of column: ${2:ColumnName} by count",
|
||||
"top-nested ${1:N} of ${2:ColumnName} by agg_${2:ColumnName}=count() desc"
|
||||
],
|
||||
"description": "Get the top N of a column by the count of rows"
|
||||
}
|
||||
}
|
||||
34
extensions/kusto/src/appContext.ts
Normal file
34
extensions/kusto/src/appContext.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
/**
|
||||
* Global context for the application
|
||||
*/
|
||||
export class AppContext {
|
||||
|
||||
private serviceMap: Map<string, any> = new Map();
|
||||
|
||||
constructor(public readonly extensionContext: vscode.ExtensionContext) { }
|
||||
|
||||
public getService<T>(serviceName: string): T | undefined {
|
||||
const service = this.serviceMap.get(serviceName) as T;
|
||||
if (!service) {
|
||||
console.warn('Service ', serviceName, ' is not registered');
|
||||
}
|
||||
return service;
|
||||
}
|
||||
|
||||
public registerService<T>(serviceName: string, service: T): void {
|
||||
if (this.serviceMap.has(serviceName)) {
|
||||
console.warn('Multiple services ', serviceName, ' registered!');
|
||||
} else {
|
||||
this.serviceMap.set(serviceName, service);
|
||||
}
|
||||
}
|
||||
}
|
||||
48
extensions/kusto/src/constants.ts
Normal file
48
extensions/kusto/src/constants.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
export const serviceName = 'Kusto service';
|
||||
export const providerId = 'KUSTO';
|
||||
export const serviceCrashLink = 'https://github.com/Microsoft/vscode-kusto/wiki/SqlToolsService-Known-Issues';
|
||||
export const extensionConfigSectionName = 'kusto';
|
||||
|
||||
// DATA PROTOCOL VALUES ///////////////////////////////////////////////////////////
|
||||
export const kustoClusterProviderName = 'kustoCluster';
|
||||
export const protocolVersion = '1.0';
|
||||
export const authenticationTypePropName = 'authenticationType';
|
||||
export const integratedAuth = 'integrated';
|
||||
export const serverPropName = 'server';
|
||||
export const userPropName = 'user';
|
||||
export const passwordPropName = 'password';
|
||||
export const groupIdPropName = 'groupId';
|
||||
export const groupIdName = 'groupId';
|
||||
export const kustoProviderName = 'KUSTO';
|
||||
|
||||
export const UNTITLED_SCHEMA = 'untitled';
|
||||
|
||||
export const clusterEndpointsProperty = 'clusterEndpoints';
|
||||
export const hdfsRootPath = '/';
|
||||
|
||||
// SERVICE NAMES //////////////////////////////////////////////////////////
|
||||
export const ObjectExplorerService = 'objectexplorer';
|
||||
export const objectExplorerPrefix: string = 'objectexplorer://';
|
||||
export const ViewType = 'view';
|
||||
|
||||
export enum BuiltInCommands {
|
||||
SetContext = 'setContext'
|
||||
}
|
||||
|
||||
export enum CommandContext {
|
||||
WizardServiceEnabled = 'wizardservice:enabled'
|
||||
}
|
||||
|
||||
export enum KustoClusterItems {
|
||||
Connection = 'kustoCluster:connection',
|
||||
Folder = 'kustoCluster:folder',
|
||||
File = 'kustoCluster:file',
|
||||
Error = 'kustoCluster:error'
|
||||
}
|
||||
|
||||
export const kustoClusterNewNotebookTask = 'kustoCluster.task.newNotebook';
|
||||
export const kustoClusterOpenNotebookTask = 'kustoCluster.task.openNotebook';
|
||||
75
extensions/kusto/src/contextProvider.ts
Normal file
75
extensions/kusto/src/contextProvider.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as vscode from 'vscode';
|
||||
import * as azdata from 'azdata';
|
||||
|
||||
import * as types from './types';
|
||||
|
||||
export enum BuiltInCommands {
|
||||
SetContext = 'setContext',
|
||||
}
|
||||
|
||||
export enum ContextKeys {
|
||||
ISCLOUD = 'kusto:iscloud',
|
||||
EDITIONID = 'kusto:engineedition',
|
||||
ISCLUSTER = 'kusto:iscluster',
|
||||
SERVERMAJORVERSION = 'kusto:servermajorversion'
|
||||
}
|
||||
|
||||
const isCloudEditions = [
|
||||
5,
|
||||
6
|
||||
];
|
||||
|
||||
export function setCommandContext(key: ContextKeys | string, value: any) {
|
||||
return vscode.commands.executeCommand(BuiltInCommands.SetContext, key, value);
|
||||
}
|
||||
|
||||
export default class ContextProvider {
|
||||
private _disposables = new Array<vscode.Disposable>();
|
||||
|
||||
constructor() {
|
||||
this._disposables.push(azdata.workspace.onDidOpenDashboard(this.onDashboardOpen, this));
|
||||
this._disposables.push(azdata.workspace.onDidChangeToDashboard(this.onDashboardOpen, this));
|
||||
}
|
||||
|
||||
public onDashboardOpen(e: azdata.DashboardDocument): void {
|
||||
let iscloud: boolean = false;
|
||||
let edition: number | undefined;
|
||||
let isCluster: boolean = false; // TODO: Do we even need this for Kusto
|
||||
let serverMajorVersion: number | undefined;
|
||||
if (e.profile.providerName.toLowerCase() === 'kusto' && !types.isUndefinedOrNull(e.serverInfo) && !types.isUndefinedOrNull(e.serverInfo.engineEditionId)) {
|
||||
if (isCloudEditions.some(i => i === e.serverInfo.engineEditionId)) {
|
||||
iscloud = true;
|
||||
} else {
|
||||
iscloud = false;
|
||||
}
|
||||
|
||||
edition = e.serverInfo.engineEditionId;
|
||||
|
||||
serverMajorVersion = e.serverInfo.serverMajorVersion;
|
||||
}
|
||||
|
||||
if (iscloud === true || iscloud === false) {
|
||||
setCommandContext(ContextKeys.ISCLOUD, iscloud);
|
||||
}
|
||||
|
||||
if (!types.isUndefinedOrNull(edition)) {
|
||||
setCommandContext(ContextKeys.EDITIONID, edition);
|
||||
}
|
||||
|
||||
if (!types.isUndefinedOrNull(isCluster)) {
|
||||
setCommandContext(ContextKeys.ISCLUSTER, isCluster);
|
||||
}
|
||||
|
||||
if (!types.isUndefinedOrNull(serverMajorVersion)) {
|
||||
setCommandContext(ContextKeys.SERVERMAJORVERSION, serverMajorVersion);
|
||||
}
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this._disposables = this._disposables.map(i => i.dispose());
|
||||
}
|
||||
}
|
||||
63
extensions/kusto/src/contracts.ts
Normal file
63
extensions/kusto/src/contracts.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { NotificationType, RequestType } from 'vscode-languageclient';
|
||||
import { ITelemetryEventProperties, ITelemetryEventMeasures } from './telemetry';
|
||||
import * as azdata from 'azdata';
|
||||
|
||||
// ------------------------------- < Telemetry Sent Event > ------------------------------------
|
||||
|
||||
/**
|
||||
* Event sent when the language service send a telemetry event
|
||||
*/
|
||||
export namespace TelemetryNotification {
|
||||
export const type = new NotificationType<TelemetryParams, void>('telemetry/sqlevent');
|
||||
}
|
||||
|
||||
/**
|
||||
* Update event parameters
|
||||
*/
|
||||
export class TelemetryParams {
|
||||
public params!: {
|
||||
eventName: string;
|
||||
properties: ITelemetryEventProperties;
|
||||
measures: ITelemetryEventMeasures;
|
||||
};
|
||||
}
|
||||
|
||||
// ------------------------------- </ Telemetry Sent Event > ----------------------------------
|
||||
|
||||
// ------------------------------- <Serialization> -----------------------------
|
||||
export namespace SerializeDataStartRequest {
|
||||
export const type = new RequestType<azdata.SerializeDataStartRequestParams, azdata.SerializeDataResult, void, void>('serialize/start');
|
||||
}
|
||||
|
||||
export namespace SerializeDataContinueRequest {
|
||||
export const type = new RequestType<azdata.SerializeDataContinueRequestParams, azdata.SerializeDataResult, void, void>('serialize/continue');
|
||||
}
|
||||
// ------------------------------- <Serialization> -----------------------------
|
||||
|
||||
// ------------------------------- < Load Completion Extension Request > ------------------------------------
|
||||
/**
|
||||
* Completion extension load parameters
|
||||
*/
|
||||
export class CompletionExtensionParams {
|
||||
/// <summary>
|
||||
/// Absolute path for the assembly containing the completion extension
|
||||
/// </summary>
|
||||
public assemblyPath?: string;
|
||||
/// <summary>
|
||||
/// The type name for the completion extension
|
||||
/// </summary>
|
||||
public typeName?: string;
|
||||
/// <summary>
|
||||
/// Property bag for initializing the completion extension
|
||||
/// </summary>
|
||||
public properties?: {};
|
||||
}
|
||||
|
||||
export namespace CompletionExtLoadRequest {
|
||||
export const type = new RequestType<CompletionExtensionParams, boolean, void, void>('completion/extLoad');
|
||||
}
|
||||
89
extensions/kusto/src/features.ts
Normal file
89
extensions/kusto/src/features.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { SqlOpsDataClient, SqlOpsFeature } from 'dataprotocol-client';
|
||||
import { ClientCapabilities, StaticFeature, RPCMessageType, ServerCapabilities } from 'vscode-languageclient';
|
||||
import { Disposable } from 'vscode';
|
||||
import { Telemetry } from './telemetry';
|
||||
import * as contracts from './contracts';
|
||||
import * as azdata from 'azdata';
|
||||
import * as Utils from './utils';
|
||||
import * as UUID from 'vscode-languageclient/lib/utils/uuid';
|
||||
|
||||
export class TelemetryFeature implements StaticFeature {
|
||||
|
||||
constructor(private _client: SqlOpsDataClient) { }
|
||||
|
||||
fillClientCapabilities(capabilities: ClientCapabilities): void {
|
||||
Utils.ensure(capabilities, 'telemetry')!.telemetry = true;
|
||||
}
|
||||
|
||||
initialize(): void {
|
||||
this._client.onNotification(contracts.TelemetryNotification.type, e => {
|
||||
Telemetry.sendTelemetryEvent(e.params.eventName, e.params.properties, e.params.measures);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class SerializationFeature extends SqlOpsFeature<undefined> {
|
||||
private static readonly messageTypes: RPCMessageType[] = [
|
||||
contracts.SerializeDataStartRequest.type,
|
||||
contracts.SerializeDataContinueRequest.type,
|
||||
];
|
||||
|
||||
constructor(client: SqlOpsDataClient) {
|
||||
super(client, SerializationFeature.messageTypes);
|
||||
}
|
||||
|
||||
public fillClientCapabilities(capabilities: ClientCapabilities): void {
|
||||
}
|
||||
|
||||
public initialize(capabilities: ServerCapabilities): void {
|
||||
this.register(this.messages, {
|
||||
id: UUID.generateUuid(),
|
||||
registerOptions: undefined
|
||||
});
|
||||
}
|
||||
|
||||
protected registerProvider(options: undefined): Disposable {
|
||||
const client = this._client;
|
||||
|
||||
let startSerialization = (requestParams: azdata.SerializeDataStartRequestParams): Thenable<azdata.SerializeDataResult> => {
|
||||
return client.sendRequest(contracts.SerializeDataStartRequest.type, requestParams).then(
|
||||
r => {
|
||||
return r;
|
||||
},
|
||||
e => {
|
||||
client.logFailedRequest(contracts.SerializeDataStartRequest.type, e);
|
||||
return Promise.resolve(<azdata.SerializeDataResult>{
|
||||
succeeded: false,
|
||||
messages: Utils.getErrorMessage(e)
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
let continueSerialization = (requestParams: azdata.SerializeDataContinueRequestParams): Thenable<azdata.SerializeDataResult> => {
|
||||
return client.sendRequest(contracts.SerializeDataContinueRequest.type, requestParams).then(
|
||||
r => {
|
||||
return r;
|
||||
},
|
||||
e => {
|
||||
client.logFailedRequest(contracts.SerializeDataContinueRequest.type, e);
|
||||
return Promise.resolve(<azdata.SerializeDataResult>{
|
||||
succeeded: false,
|
||||
messages: Utils.getErrorMessage(e)
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
return azdata.dataprotocol.registerSerializationProvider({
|
||||
providerId: client.providerId,
|
||||
startSerialization,
|
||||
continueSerialization
|
||||
});
|
||||
}
|
||||
}
|
||||
21
extensions/kusto/src/iconProvider.ts
Normal file
21
extensions/kusto/src/iconProvider.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import * as constants from './constants';
|
||||
|
||||
const cloudIcon = 'kusto:cloud';
|
||||
|
||||
export class KustoIconProvider implements azdata.IconProvider {
|
||||
public readonly providerId: string = constants.kustoProviderName;
|
||||
public handle?: number;
|
||||
getConnectionIconId(connection: azdata.IConnectionProfile, serverInfo: azdata.ServerInfo): Thenable<string | undefined> {
|
||||
let iconName: string | undefined;
|
||||
if (connection.providerName === this.providerId) {
|
||||
iconName = cloudIcon;
|
||||
}
|
||||
return Promise.resolve(iconName);
|
||||
}
|
||||
}
|
||||
38
extensions/kusto/src/kusto.d.ts
vendored
Normal file
38
extensions/kusto/src/kusto.d.ts
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
// This is the place for extensions to expose APIs.
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
|
||||
/**
|
||||
* The APIs provided by Kusto extension
|
||||
*/
|
||||
export interface IExtension {
|
||||
/**
|
||||
* Gets the object explorer API that supports querying over the connections supported by this extension
|
||||
*
|
||||
*/
|
||||
getKustoObjectExplorerBrowser(): KustoObjectExplorerBrowser;
|
||||
}
|
||||
|
||||
/**
|
||||
* A browser supporting actions over the object explorer connections provided by this extension.
|
||||
* Currently this is the
|
||||
*/
|
||||
export interface KustoObjectExplorerBrowser {
|
||||
/**
|
||||
* Gets the matching node given a context object, e.g. one from a right-click on a node in Object Explorer
|
||||
*/
|
||||
getNode<T extends ITreeNode>(objectExplorerContext: azdata.ObjectExplorerContext): Thenable<T>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A tree node in the object explorer tree
|
||||
*/
|
||||
export interface ITreeNode {
|
||||
getNodeInfo(): azdata.NodeInfo;
|
||||
getChildren(refreshChildren: boolean): ITreeNode[] | Thenable<ITreeNode[]>;
|
||||
}
|
||||
23
extensions/kusto/src/kustoApiFactory.ts
Normal file
23
extensions/kusto/src/kustoApiFactory.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { AppContext } from './appContext';
|
||||
import { IExtension, KustoObjectExplorerBrowser } from './kusto';
|
||||
import * as constants from './constants';
|
||||
import { KustoObjectExplorerNodeProvider } from './objectExplorerNodeProvider/objectExplorerNodeProvider';
|
||||
import * as azdata from 'azdata';
|
||||
|
||||
export function createKustoApi(context: AppContext): IExtension {
|
||||
return {
|
||||
getKustoObjectExplorerBrowser(): KustoObjectExplorerBrowser {
|
||||
return {
|
||||
getNode: (explorerContext: azdata.ObjectExplorerContext) => {
|
||||
let oeProvider = context.getService<KustoObjectExplorerNodeProvider>(constants.ObjectExplorerService);
|
||||
return <any>oeProvider?.findSqlClusterNodeByContext(explorerContext);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
163
extensions/kusto/src/kustoServer.ts
Normal file
163
extensions/kusto/src/kustoServer.ts
Normal file
@@ -0,0 +1,163 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ServerProvider, IConfig, Events } from 'service-downloader';
|
||||
import { ServerOptions, TransportKind } from 'vscode-languageclient';
|
||||
import * as Constants from './constants';
|
||||
import * as vscode from 'vscode';
|
||||
import * as path from 'path';
|
||||
import { getCommonLaunchArgsAndCleanupOldLogFiles } from './utils';
|
||||
import { localize } from './localize';
|
||||
import { Telemetry, LanguageClientErrorHandler } from './telemetry';
|
||||
import { SqlOpsDataClient, ClientOptions } from 'dataprotocol-client';
|
||||
import { TelemetryFeature, SerializationFeature } from './features';
|
||||
import { AppContext } from './appContext';
|
||||
import { CompletionExtensionParams, CompletionExtLoadRequest } from './contracts';
|
||||
import { promises as fs } from 'fs';
|
||||
|
||||
const outputChannel = vscode.window.createOutputChannel(Constants.serviceName);
|
||||
const statusView = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
|
||||
|
||||
export class KustoServer {
|
||||
|
||||
private client!: SqlOpsDataClient;
|
||||
private config!: IConfig;
|
||||
private disposables: vscode.Disposable[] = [];
|
||||
|
||||
public async start(context: AppContext): Promise<SqlOpsDataClient> {
|
||||
try {
|
||||
const installationStart = Date.now();
|
||||
const path = await this.download(context); // TodoKusto: Remove this commented line once the Kusto service layer has been published to Github. Until then copy manually for debugging.
|
||||
// const path = "e:\\repos\\azuredatastudio\\extensions\\kusto\\sqltoolsservice\\Windows\\2.0.0-release.15\\MicrosoftKustoServiceLayer.exe";
|
||||
const installationComplete = Date.now();
|
||||
let serverOptions = generateServerOptions(context.extensionContext.logPath, path);
|
||||
let clientOptions = getClientOptions(context);
|
||||
this.client = new SqlOpsDataClient(Constants.serviceName, serverOptions, clientOptions); // TodoKusto: Update constant
|
||||
const processStart = Date.now();
|
||||
const clientReadyPromise = this.client.onReady().then(() => {
|
||||
const processEnd = Date.now();
|
||||
statusView.text = localize('serviceStartedStatusMsg', "{0} Started", Constants.serviceName);
|
||||
setTimeout(() => {
|
||||
statusView.hide();
|
||||
}, 1500);
|
||||
vscode.commands.registerCommand('kusto.loadCompletionExtension', (params: CompletionExtensionParams) => {
|
||||
this.client.sendRequest(CompletionExtLoadRequest.type, params);
|
||||
});
|
||||
Telemetry.sendTelemetryEvent('startup/LanguageClientStarted', {
|
||||
installationTime: String(installationComplete - installationStart),
|
||||
processStartupTime: String(processEnd - processStart),
|
||||
totalTime: String(processEnd - installationStart),
|
||||
beginningTimestamp: String(installationStart)
|
||||
});
|
||||
});
|
||||
statusView.show();
|
||||
statusView.text = localize('startingServiceStatusMsg', "Starting {0}", Constants.serviceName);
|
||||
this.client.start();
|
||||
await Promise.all([clientReadyPromise]);
|
||||
return this.client;
|
||||
} catch (e) {
|
||||
Telemetry.sendTelemetryEvent('ServiceInitializingFailed');
|
||||
vscode.window.showErrorMessage(localize('failedToStartServiceErrorMsg', "Failed to start {0}", Constants.serviceName));
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private async download(context: AppContext): Promise<string> {
|
||||
const rawConfig = await fs.readFile(path.join(context.extensionContext.extensionPath, 'config.json')); // TodoKusto: Update config.json to refer to the right exe
|
||||
this.config = JSON.parse(rawConfig.toString())!;
|
||||
this.config.installDirectory = path.join(__dirname, this.config.installDirectory);
|
||||
this.config.proxy = vscode.workspace.getConfiguration('http').get<string>('proxy')!;
|
||||
this.config.strictSSL = vscode.workspace.getConfiguration('http').get('proxyStrictSSL') || true;
|
||||
|
||||
const serverdownloader = new ServerProvider(this.config);
|
||||
serverdownloader.eventEmitter.onAny(() => generateHandleServerProviderEvent());
|
||||
return serverdownloader.getOrDownloadServer();
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this.disposables.forEach(d => d.dispose());
|
||||
if (this.client) {
|
||||
this.client.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function generateServerOptions(logPath: string, executablePath: string): ServerOptions {
|
||||
const launchArgs = getCommonLaunchArgsAndCleanupOldLogFiles(logPath, 'kustoService.log', executablePath);
|
||||
return { command: executablePath, args: launchArgs, transport: TransportKind.stdio };
|
||||
}
|
||||
|
||||
function generateHandleServerProviderEvent() {
|
||||
let dots = 0;
|
||||
return (e: string, ...args: any[]) => {
|
||||
switch (e) {
|
||||
case Events.INSTALL_START:
|
||||
outputChannel.show(true);
|
||||
statusView.show();
|
||||
outputChannel.appendLine(localize('installingServiceChannelMsg', "Installing {0} to {1}", Constants.serviceName, args[0]));
|
||||
statusView.text = localize('installingServiceStatusMsg', "Installing {0}", Constants.serviceName);
|
||||
break;
|
||||
case Events.INSTALL_END:
|
||||
outputChannel.appendLine(localize('installedServiceChannelMsg', "Installed {0}", Constants.serviceName));
|
||||
break;
|
||||
case Events.DOWNLOAD_START:
|
||||
outputChannel.appendLine(localize('downloadingServiceChannelMsg', "Downloading {0}", args[0]));
|
||||
outputChannel.append(localize('downloadingServiceSizeChannelMsg', "({0} KB)", Math.ceil(args[1] / 1024).toLocaleString(vscode.env.language)));
|
||||
statusView.text = localize('downloadingServiceStatusMsg', "Downloading {0}", Constants.serviceName);
|
||||
break;
|
||||
case Events.DOWNLOAD_PROGRESS:
|
||||
let newDots = Math.ceil(args[0] / 5);
|
||||
if (newDots > dots) {
|
||||
outputChannel.append('.'.repeat(newDots - dots));
|
||||
dots = newDots;
|
||||
}
|
||||
break;
|
||||
case Events.DOWNLOAD_END:
|
||||
outputChannel.appendLine(localize('downloadServiceDoneChannelMsg', "Done installing {0}", Constants.serviceName));
|
||||
break;
|
||||
default:
|
||||
console.error(`Unknown event from Server Provider ${e}`);
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function getClientOptions(context: AppContext): ClientOptions {
|
||||
return {
|
||||
documentSelector: ['kusto'], // TodoKusto: This should be same as the language id in package.json. See if we can surface that better later.
|
||||
synchronize: {
|
||||
configurationSection: Constants.extensionConfigSectionName
|
||||
},
|
||||
providerId: Constants.providerId,
|
||||
errorHandler: new LanguageClientErrorHandler(),
|
||||
features: [
|
||||
// we only want to add new features
|
||||
...SqlOpsDataClient.defaultFeatures,
|
||||
TelemetryFeature,
|
||||
SerializationFeature
|
||||
],
|
||||
outputChannel: new CustomOutputChannel()
|
||||
};
|
||||
}
|
||||
|
||||
class CustomOutputChannel implements vscode.OutputChannel {
|
||||
name!: string;
|
||||
append(value: string): void {
|
||||
console.log(value);
|
||||
}
|
||||
appendLine(value: string): void {
|
||||
console.log(value);
|
||||
}
|
||||
clear(): void {
|
||||
}
|
||||
show(preserveFocus?: boolean): void;
|
||||
show(column?: vscode.ViewColumn, preserveFocus?: boolean): void;
|
||||
show(column?: any, preserveFocus?: any) {
|
||||
}
|
||||
hide(): void {
|
||||
}
|
||||
dispose(): void {
|
||||
}
|
||||
}
|
||||
8
extensions/kusto/src/localize.ts
Normal file
8
extensions/kusto/src/localize.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as nls from 'vscode-nls';
|
||||
|
||||
export const localize = nls.loadMessageBundle();
|
||||
135
extensions/kusto/src/main.ts
Normal file
135
extensions/kusto/src/main.ts
Normal file
@@ -0,0 +1,135 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as azdata from 'azdata';
|
||||
import * as path from 'path';
|
||||
|
||||
import * as Constants from './constants';
|
||||
import ContextProvider from './contextProvider';
|
||||
import * as Utils from './utils';
|
||||
import { AppContext } from './appContext';
|
||||
import { IExtension } from './kusto';
|
||||
import { KustoObjectExplorerNodeProvider } from './objectExplorerNodeProvider/objectExplorerNodeProvider';
|
||||
import { registerSearchServerCommand } from './objectExplorerNodeProvider/command';
|
||||
import { KustoIconProvider } from './iconProvider';
|
||||
import { createKustoApi } from './kustoApiFactory';
|
||||
import { localize } from './localize';
|
||||
import { KustoServer } from './kustoServer';
|
||||
import { promises as fs } from 'fs';
|
||||
|
||||
export async function activate(context: vscode.ExtensionContext): Promise<IExtension | undefined> {
|
||||
// lets make sure we support this platform first
|
||||
let supported = await Utils.verifyPlatform();
|
||||
|
||||
if (!supported) {
|
||||
vscode.window.showErrorMessage(localize('kusto.unsupportedPlatform', 'Unsupported platform'));
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// ensure our log path exists
|
||||
if (!(await Utils.exists(context.logPath))) {
|
||||
await fs.mkdir(context.logPath);
|
||||
}
|
||||
|
||||
let appContext = new AppContext(context);
|
||||
|
||||
let nodeProvider = new KustoObjectExplorerNodeProvider(appContext);
|
||||
azdata.dataprotocol.registerObjectExplorerNodeProvider(nodeProvider);
|
||||
let iconProvider = new KustoIconProvider();
|
||||
azdata.dataprotocol.registerIconProvider(iconProvider);
|
||||
|
||||
activateNotebookTask();
|
||||
|
||||
registerSearchServerCommand();
|
||||
context.subscriptions.push(new ContextProvider());
|
||||
|
||||
registerLogCommand(context);
|
||||
|
||||
// initialize client last so we don't have features stuck behind it
|
||||
const server = new KustoServer();
|
||||
context.subscriptions.push(server);
|
||||
await server.start(appContext);
|
||||
|
||||
return createKustoApi(appContext);
|
||||
}
|
||||
|
||||
const logFiles = ['resourceprovider.log', 'kustoservice.log', 'credentialstore.log'];
|
||||
function registerLogCommand(context: vscode.ExtensionContext) {
|
||||
context.subscriptions.push(vscode.commands.registerCommand('kusto.showLogFile', async () => {
|
||||
const choice = await vscode.window.showQuickPick(logFiles);
|
||||
if (choice) {
|
||||
const document = await vscode.workspace.openTextDocument(vscode.Uri.file(path.join(context.logPath, choice)));
|
||||
if (document) {
|
||||
vscode.window.showTextDocument(document);
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
function activateNotebookTask(): void {
|
||||
azdata.tasks.registerTask(Constants.kustoClusterNewNotebookTask, (profile: azdata.IConnectionProfile) => {
|
||||
return saveProfileAndCreateNotebook(profile);
|
||||
});
|
||||
azdata.tasks.registerTask(Constants.kustoClusterOpenNotebookTask, (profile: azdata.IConnectionProfile) => {
|
||||
return handleOpenNotebookTask(profile);
|
||||
});
|
||||
}
|
||||
|
||||
function saveProfileAndCreateNotebook(profile: azdata.IConnectionProfile): Promise<void> {
|
||||
return handleNewNotebookTask(undefined, profile);
|
||||
}
|
||||
|
||||
function findNextUntitledEditorName(): string {
|
||||
let nextVal = 0;
|
||||
// Note: this will go forever if it's coded wrong, or you have inifinite Untitled notebooks!
|
||||
while (true) {
|
||||
let title = `Notebook-${nextVal}`;
|
||||
let hasNotebookDoc = azdata.nb.notebookDocuments.findIndex(doc => doc.isUntitled && doc.fileName === title) > -1;
|
||||
if (!hasNotebookDoc) {
|
||||
return title;
|
||||
}
|
||||
nextVal++;
|
||||
}
|
||||
}
|
||||
|
||||
async function handleNewNotebookTask(oeContext?: azdata.ObjectExplorerContext, profile?: azdata.IConnectionProfile): Promise<void> {
|
||||
// Ensure we get a unique ID for the notebook. For now we're using a different prefix to the built-in untitled files
|
||||
// to handle this. We should look into improving this in the future
|
||||
let title = findNextUntitledEditorName();
|
||||
let untitledUri = vscode.Uri.parse(`untitled:${title}`);
|
||||
await azdata.nb.showNotebookDocument(untitledUri, {
|
||||
connectionProfile: profile,
|
||||
preview: false
|
||||
});
|
||||
}
|
||||
|
||||
async function handleOpenNotebookTask(profile: azdata.IConnectionProfile): Promise<void> {
|
||||
let notebookFileTypeName = localize('notebookFileType', "Notebooks");
|
||||
let filter = {};
|
||||
filter[notebookFileTypeName] = 'ipynb';
|
||||
let uris = await vscode.window.showOpenDialog({
|
||||
filters: filter,
|
||||
canSelectFiles: true,
|
||||
canSelectMany: false
|
||||
});
|
||||
if (uris && uris.length > 0) {
|
||||
let fileUri = uris[0];
|
||||
// Verify this is a .ipynb file since this isn't actually filtered on Mac/Linux
|
||||
if (path.extname(fileUri.fsPath) !== '.ipynb') {
|
||||
// in the future might want additional supported types
|
||||
vscode.window.showErrorMessage(localize('unsupportedFileType', "Only .ipynb Notebooks are supported"));
|
||||
} else {
|
||||
await azdata.nb.showNotebookDocument(fileUri, {
|
||||
connectionProfile: profile,
|
||||
preview: false
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this method is called when your extension is deactivated
|
||||
export function deactivate(): void {
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import { Transform } from 'stream';
|
||||
import * as vscode from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
export class CancelableStream extends Transform {
|
||||
constructor(private cancelationToken: vscode.CancellationTokenSource) {
|
||||
super();
|
||||
}
|
||||
|
||||
public _transform(chunk: any, encoding: string, callback: Function): void {
|
||||
if (this.cancelationToken && this.cancelationToken.token.isCancellationRequested) {
|
||||
callback(new Error(localize('streamCanceled', 'Stream operation canceled by the user')));
|
||||
} else {
|
||||
this.push(chunk);
|
||||
callback();
|
||||
}
|
||||
}
|
||||
}
|
||||
187
extensions/kusto/src/objectExplorerNodeProvider/command.ts
Normal file
187
extensions/kusto/src/objectExplorerNodeProvider/command.ts
Normal file
@@ -0,0 +1,187 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as azdata from 'azdata';
|
||||
import * as nls from 'vscode-nls';
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
import { TreeNode } from './treeNodes';
|
||||
import { QuestionTypes, IPrompter, IQuestion } from '../prompts/question';
|
||||
import * as utils from '../utils';
|
||||
import * as constants from '../constants';
|
||||
import { AppContext } from '../appContext';
|
||||
|
||||
export interface ICommandContextParsingOptions {
|
||||
editor: boolean;
|
||||
uri: boolean;
|
||||
}
|
||||
|
||||
export interface ICommandBaseContext {
|
||||
command: string;
|
||||
editor?: vscode.TextEditor;
|
||||
uri?: vscode.Uri;
|
||||
}
|
||||
|
||||
export interface ICommandUnknownContext extends ICommandBaseContext {
|
||||
type: 'unknown';
|
||||
}
|
||||
|
||||
export interface ICommandUriContext extends ICommandBaseContext {
|
||||
type: 'uri';
|
||||
}
|
||||
|
||||
export interface ICommandViewContext extends ICommandBaseContext {
|
||||
type: 'view';
|
||||
node: TreeNode;
|
||||
}
|
||||
|
||||
export interface ICommandObjectExplorerContext extends ICommandBaseContext {
|
||||
type: 'objectexplorer';
|
||||
explorerContext: azdata.ObjectExplorerContext;
|
||||
}
|
||||
|
||||
export type CommandContext = ICommandObjectExplorerContext | ICommandViewContext | ICommandUriContext | ICommandUnknownContext;
|
||||
|
||||
function isTextEditor(editor: any): editor is vscode.TextEditor {
|
||||
if (editor === undefined) { return false; }
|
||||
|
||||
return editor.id !== undefined && ((editor as vscode.TextEditor).edit !== undefined || (editor as vscode.TextEditor).document !== undefined);
|
||||
}
|
||||
|
||||
export abstract class Command extends vscode.Disposable {
|
||||
|
||||
|
||||
protected readonly contextParsingOptions: ICommandContextParsingOptions = { editor: false, uri: false };
|
||||
|
||||
private disposable: vscode.Disposable;
|
||||
|
||||
constructor(command: string | string[], protected appContext: AppContext) {
|
||||
super(() => this.dispose());
|
||||
|
||||
if (typeof command === 'string') {
|
||||
this.disposable = vscode.commands.registerCommand(command, (...args: any[]) => this._execute(command, ...args), this);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const subscriptions = command.map(cmd => vscode.commands.registerCommand(cmd, (...args: any[]) => this._execute(cmd, ...args), this));
|
||||
this.disposable = vscode.Disposable.from(...subscriptions);
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
if (this.disposable) {
|
||||
this.disposable.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
protected async preExecute(...args: any[]): Promise<any> {
|
||||
return this.execute(...args);
|
||||
}
|
||||
|
||||
abstract execute(...args: any[]): any;
|
||||
|
||||
protected _execute(command: string, ...args: any[]): any {
|
||||
// TODO consider using Telemetry.trackEvent(command);
|
||||
|
||||
const [context, rest] = Command.parseContext(command, this.contextParsingOptions, ...args);
|
||||
return this.preExecute(context, ...rest);
|
||||
}
|
||||
|
||||
private static parseContext(command: string, options: ICommandContextParsingOptions, ...args: any[]): [CommandContext, any[]] {
|
||||
let editor: vscode.TextEditor | undefined = undefined;
|
||||
|
||||
let firstArg = args[0];
|
||||
if (options.editor && (firstArg === undefined || isTextEditor(firstArg))) {
|
||||
editor = firstArg;
|
||||
args = args.slice(1);
|
||||
firstArg = args[0];
|
||||
}
|
||||
|
||||
if (options.uri && (firstArg === undefined || firstArg instanceof vscode.Uri)) {
|
||||
const [uri, ...rest] = args as [vscode.Uri, any];
|
||||
return [{ command: command, type: 'uri', editor: editor, uri: uri }, rest];
|
||||
}
|
||||
|
||||
if (firstArg instanceof TreeNode) {
|
||||
const [node, ...rest] = args as [TreeNode, any];
|
||||
return [{ command: command, type: constants.ViewType, node: node }, rest];
|
||||
}
|
||||
|
||||
if (firstArg && utils.isObjectExplorerContext(firstArg)) {
|
||||
const [explorerContext, ...rest] = args as [azdata.ObjectExplorerContext, any];
|
||||
return [{ command: command, type: constants.ObjectExplorerService, explorerContext: explorerContext }, rest];
|
||||
}
|
||||
|
||||
return [{ command: command, type: 'unknown', editor: editor }, args];
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class ProgressCommand extends Command {
|
||||
static progressId = 0;
|
||||
constructor(command: string, protected prompter: IPrompter, appContext: AppContext) {
|
||||
super(command, appContext);
|
||||
}
|
||||
|
||||
protected async executeWithProgress(
|
||||
execution: (cancelToken: vscode.CancellationTokenSource) => Promise<void>,
|
||||
label: string,
|
||||
isCancelable: boolean = false,
|
||||
onCanceled?: () => void
|
||||
): Promise<void> {
|
||||
let disposables: vscode.Disposable[] = [];
|
||||
const tokenSource = new vscode.CancellationTokenSource();
|
||||
const statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
|
||||
disposables.push(vscode.Disposable.from(statusBarItem));
|
||||
statusBarItem.text = localize('progress', '$(sync~spin) {0}...', label);
|
||||
if (isCancelable) {
|
||||
const cancelCommandId = `cancelProgress${ProgressCommand.progressId++}`;
|
||||
disposables.push(vscode.commands.registerCommand(cancelCommandId, async () => {
|
||||
if (await this.confirmCancel()) {
|
||||
tokenSource.cancel();
|
||||
}
|
||||
}));
|
||||
statusBarItem.tooltip = localize('cancelTooltip', 'Cancel');
|
||||
statusBarItem.command = cancelCommandId;
|
||||
}
|
||||
statusBarItem.show();
|
||||
|
||||
try {
|
||||
await execution(tokenSource);
|
||||
} catch (error) {
|
||||
if (isCancelable && onCanceled && tokenSource.token.isCancellationRequested) {
|
||||
// The error can be assumed to be due to cancelation occurring. Do the callback
|
||||
onCanceled();
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
} finally {
|
||||
disposables.forEach(d => d.dispose());
|
||||
}
|
||||
}
|
||||
|
||||
private async confirmCancel(): Promise<boolean> {
|
||||
return (await this.prompter.promptSingle<boolean>(<IQuestion>{
|
||||
type: QuestionTypes.confirm,
|
||||
message: localize('cancel', 'Cancel operation?'),
|
||||
default: true
|
||||
}))!;
|
||||
}
|
||||
}
|
||||
|
||||
export function registerSearchServerCommand(): void {
|
||||
vscode.commands.registerCommand('kusto.searchServers', () => {
|
||||
vscode.window.showInputBox({
|
||||
placeHolder: localize('kusto.searchServers', 'Search Server Names')
|
||||
}).then((stringSearch) => {
|
||||
if (stringSearch) {
|
||||
vscode.commands.executeCommand('registeredServers.searchServer', (stringSearch));
|
||||
}
|
||||
});
|
||||
});
|
||||
vscode.commands.registerCommand('kusto.clearSearchServerResult', () => {
|
||||
vscode.commands.executeCommand('registeredServers.clearSearchServerResult');
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import * as nls from 'vscode-nls';
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
import * as constants from '../constants';
|
||||
|
||||
export class KustoClusterConnection {
|
||||
private _connection: azdata.connection.Connection;
|
||||
private _profile!: azdata.IConnectionProfile;
|
||||
private _user: string;
|
||||
private _password: string;
|
||||
|
||||
constructor(connectionInfo: azdata.connection.Connection | azdata.IConnectionProfile) {
|
||||
this.validate(connectionInfo);
|
||||
|
||||
if ('id' in connectionInfo) {
|
||||
this._profile = connectionInfo;
|
||||
this._connection = this.toConnection(this._profile);
|
||||
} else {
|
||||
this._connection = connectionInfo;
|
||||
}
|
||||
this._user = this._connection.options[constants.userPropName];
|
||||
this._password = this._connection.options[constants.passwordPropName];
|
||||
}
|
||||
|
||||
public get connection(): azdata.connection.Connection { return this._connection; }
|
||||
public get user(): string { return this._user; }
|
||||
public get password(): string { return this._password; }
|
||||
|
||||
public isMatch(connection: KustoClusterConnection | azdata.ConnectionInfo): boolean {
|
||||
if (!connection) { return false; }
|
||||
let options1 = connection instanceof KustoClusterConnection ?
|
||||
connection._connection.options : connection.options;
|
||||
let options2 = this._connection.options;
|
||||
return [constants.serverPropName, constants.userPropName]
|
||||
.every(e => options1[e] === options2[e]);
|
||||
}
|
||||
|
||||
public isIntegratedAuth(): boolean {
|
||||
let authType: string = this._connection.options[constants.authenticationTypePropName];
|
||||
return authType?.toLowerCase() === constants.integratedAuth;
|
||||
}
|
||||
|
||||
public updatePassword(password: string): void {
|
||||
if (password) {
|
||||
this._password = password;
|
||||
}
|
||||
}
|
||||
|
||||
private validate(connectionInfo: azdata.ConnectionInfo): void {
|
||||
if (!connectionInfo) {
|
||||
throw new Error(localize('connectionInfoUndefined', 'ConnectionInfo is undefined.'));
|
||||
}
|
||||
if (!connectionInfo.options) {
|
||||
throw new Error(localize('connectionInfoOptionsUndefined', 'ConnectionInfo.options is undefined.'));
|
||||
}
|
||||
let missingProperties: string[] = this.getMissingProperties(connectionInfo)!;
|
||||
if (missingProperties && missingProperties.length > 0) {
|
||||
throw new Error(localize('connectionInfoOptionsMissingProperties',
|
||||
'Some missing properties in connectionInfo.options: {0}',
|
||||
missingProperties.join(', ')));
|
||||
}
|
||||
}
|
||||
|
||||
private getMissingProperties(connectionInfo: azdata.ConnectionInfo): string[] | undefined {
|
||||
if (!connectionInfo || !connectionInfo.options) { return undefined; }
|
||||
let requiredProps = [constants.serverPropName];
|
||||
requiredProps.push(constants.userPropName);
|
||||
return requiredProps.filter(e => connectionInfo.options[e] === undefined);
|
||||
}
|
||||
|
||||
private toConnection(connProfile: azdata.IConnectionProfile): azdata.connection.Connection {
|
||||
let connection: azdata.connection.Connection = Object.assign(connProfile,
|
||||
{ connectionId: this._profile.id });
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import * as vscode from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
import { ProviderBase } from './providerBase';
|
||||
import { KustoClusterConnection } from './connection';
|
||||
import { TreeNode } from './treeNodes';
|
||||
import { AppContext } from '../appContext';
|
||||
import * as constants from '../constants';
|
||||
import { ICommandObjectExplorerContext } from './command';
|
||||
|
||||
export const kustoOutputChannel = vscode.window.createOutputChannel(constants.providerId);
|
||||
|
||||
export interface ITreeChangeHandler {
|
||||
notifyNodeChanged(node: TreeNode): void;
|
||||
}
|
||||
|
||||
export class KustoObjectExplorerNodeProvider extends ProviderBase implements azdata.ObjectExplorerNodeProvider, ITreeChangeHandler {
|
||||
public readonly supportedProviderId: string = constants.providerId;
|
||||
private expandCompleteEmitter = new vscode.EventEmitter<azdata.ObjectExplorerExpandInfo>();
|
||||
|
||||
constructor(private appContext: AppContext) {
|
||||
super();
|
||||
this.appContext.registerService<KustoObjectExplorerNodeProvider>(constants.ObjectExplorerService, this);
|
||||
}
|
||||
|
||||
handleSessionOpen(session: azdata.ObjectExplorerSession): Thenable<boolean> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!session) {
|
||||
reject('handleSessionOpen requires a session object to be passed');
|
||||
} else {
|
||||
resolve(this.doSessionOpen(session));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async doSessionOpen(session: azdata.ObjectExplorerSession): Promise<boolean> {
|
||||
if (!session || !session.sessionId) { return false; }
|
||||
|
||||
let connProfile = await azdata.objectexplorer.getSessionConnectionProfile(session.sessionId);
|
||||
if (!connProfile) { return false; }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
expandNode(nodeInfo: azdata.ExpandNodeInfo, isRefresh: boolean = false): Thenable<boolean> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!nodeInfo) {
|
||||
reject('expandNode requires a nodeInfo object to be passed');
|
||||
} else {
|
||||
resolve(this.doExpandNode(nodeInfo, isRefresh));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async doExpandNode(nodeInfo: azdata.ExpandNodeInfo, isRefresh: boolean = false): Promise<boolean> {
|
||||
let response = {
|
||||
sessionId: nodeInfo.sessionId!,
|
||||
nodePath: nodeInfo.nodePath!,
|
||||
errorMessage: undefined,
|
||||
nodes: []
|
||||
};
|
||||
|
||||
this.expandCompleteEmitter.fire(response);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
refreshNode(nodeInfo: azdata.ExpandNodeInfo): Thenable<boolean> {
|
||||
return this.expandNode(nodeInfo, true);
|
||||
}
|
||||
|
||||
handleSessionClose(closeSessionInfo: azdata.ObjectExplorerCloseSessionInfo): void {
|
||||
}
|
||||
|
||||
findNodes(findNodesInfo: azdata.FindNodesInfo): Thenable<azdata.ObjectExplorerFindNodesResponse> {
|
||||
let response: azdata.ObjectExplorerFindNodesResponse = {
|
||||
nodes: []
|
||||
};
|
||||
return Promise.resolve(response);
|
||||
}
|
||||
|
||||
registerOnExpandCompleted(handler: (response: azdata.ObjectExplorerExpandInfo) => any): void {
|
||||
this.expandCompleteEmitter.event(handler);
|
||||
}
|
||||
|
||||
notifyNodeChanged(node: TreeNode): void {
|
||||
this.notifyNodeChangesAsync(node);
|
||||
}
|
||||
|
||||
private async notifyNodeChangesAsync(node: TreeNode): Promise<void> {
|
||||
try {
|
||||
let session = this.getSqlClusterSessionForNode(node);
|
||||
if (!session) {
|
||||
vscode.window.showErrorMessage(localize('sessionNotFound', "Session for node {0} does not exist", node.nodePathValue));
|
||||
} else {
|
||||
let nodeInfo = node.getNodeInfo();
|
||||
let expandInfo: azdata.ExpandNodeInfo = {
|
||||
nodePath: nodeInfo.nodePath,
|
||||
sessionId: session.sessionId
|
||||
};
|
||||
await this.refreshNode(expandInfo);
|
||||
}
|
||||
} catch (err) {
|
||||
kustoOutputChannel.appendLine(localize('notifyError', "Error notifying of node change: {0}", err));
|
||||
}
|
||||
}
|
||||
|
||||
private getSqlClusterSessionForNode(node?: TreeNode): SqlClusterSession | undefined {
|
||||
let sqlClusterSession: SqlClusterSession | undefined = undefined;
|
||||
while (node !== undefined) {
|
||||
if (node instanceof SqlClusterRootNode) {
|
||||
sqlClusterSession = node.session;
|
||||
break;
|
||||
} else {
|
||||
node = node.parent;
|
||||
}
|
||||
}
|
||||
return sqlClusterSession;
|
||||
}
|
||||
|
||||
async findSqlClusterNodeByContext<T extends TreeNode>(context: ICommandObjectExplorerContext | azdata.ObjectExplorerContext): Promise<T | undefined> {
|
||||
let node: T | undefined = undefined;
|
||||
let explorerContext = 'explorerContext' in context ? context.explorerContext : context;
|
||||
let sqlConnProfile = explorerContext.connectionProfile;
|
||||
let session = this.findSqlClusterSessionBySqlConnProfile(sqlConnProfile!);
|
||||
if (session) {
|
||||
if (explorerContext.isConnectionNode) {
|
||||
// Note: ideally fix so we verify T matches RootNode and go from there
|
||||
node = <T><any>session.rootNode;
|
||||
} else {
|
||||
// Find the node under the session
|
||||
node = <T><any>await session.rootNode.findNodeByPath(explorerContext?.nodeInfo?.nodePath!, true);
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
public findSqlClusterSessionBySqlConnProfile(connectionProfile: azdata.IConnectionProfile): SqlClusterSession | undefined {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export class SqlClusterSession {
|
||||
private _rootNode: SqlClusterRootNode;
|
||||
|
||||
constructor(
|
||||
private _sqlClusterConnection: KustoClusterConnection,
|
||||
private _sqlSession: azdata.ObjectExplorerSession,
|
||||
private _sqlConnectionProfile: azdata.IConnectionProfile
|
||||
) {
|
||||
this._rootNode = new SqlClusterRootNode(this,
|
||||
this._sqlSession.rootNode.nodePath!);
|
||||
}
|
||||
|
||||
public get sqlClusterConnection(): KustoClusterConnection { return this._sqlClusterConnection; }
|
||||
public get sqlSession(): azdata.ObjectExplorerSession { return this._sqlSession; }
|
||||
public get sqlConnectionProfile(): azdata.IConnectionProfile { return this._sqlConnectionProfile; }
|
||||
public get sessionId(): string { return this._sqlSession.sessionId!; }
|
||||
public get rootNode(): SqlClusterRootNode { return this._rootNode; }
|
||||
|
||||
public isMatchedSqlConnection(sqlConnProfile: azdata.IConnectionProfile): boolean {
|
||||
return this._sqlConnectionProfile.id === sqlConnProfile.id;
|
||||
}
|
||||
}
|
||||
|
||||
class SqlClusterRootNode extends TreeNode {
|
||||
private _children: TreeNode[] = [];
|
||||
constructor(
|
||||
private _session: SqlClusterSession,
|
||||
private _nodePathValue: string
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
public get session(): SqlClusterSession {
|
||||
return this._session;
|
||||
}
|
||||
|
||||
public get nodePathValue(): string {
|
||||
return this._nodePathValue;
|
||||
}
|
||||
|
||||
public getChildren(refreshChildren: boolean): TreeNode[] | Promise<TreeNode[]> {
|
||||
if (refreshChildren || !this._children) {
|
||||
return this.refreshChildren();
|
||||
}
|
||||
return this._children;
|
||||
}
|
||||
|
||||
private async refreshChildren(): Promise<TreeNode[]> {
|
||||
this._children = [];
|
||||
return this._children;
|
||||
}
|
||||
|
||||
getTreeItem(): vscode.TreeItem | Promise<vscode.TreeItem> {
|
||||
throw new Error('Not intended for use in a file explorer view.');
|
||||
}
|
||||
|
||||
getNodeInfo(): azdata.NodeInfo {
|
||||
let nodeInfo: azdata.NodeInfo = {
|
||||
label: localize('rootLabel', "Root")!,
|
||||
isLeaf: false,
|
||||
errorMessage: undefined,
|
||||
metadata: undefined,
|
||||
nodePath: this.generateNodePath()!,
|
||||
nodeStatus: undefined,
|
||||
nodeType: 'sqlCluster:root',
|
||||
nodeSubType: undefined,
|
||||
iconType: 'folder'
|
||||
};
|
||||
return nodeInfo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as constants from '../constants';
|
||||
|
||||
export abstract class ProviderBase {
|
||||
public readonly providerId: string = constants.kustoClusterProviderName;
|
||||
public handle?: number;
|
||||
}
|
||||
87
extensions/kusto/src/objectExplorerNodeProvider/treeNodes.ts
Normal file
87
extensions/kusto/src/objectExplorerNodeProvider/treeNodes.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import * as vscode from 'vscode';
|
||||
import { ITreeNode } from './types';
|
||||
|
||||
type TreeNodePredicate = (node: TreeNode) => boolean;
|
||||
|
||||
export abstract class TreeNode implements ITreeNode {
|
||||
private _parent?: TreeNode;
|
||||
private _errorStatusCode?: number;
|
||||
|
||||
public get parent(): TreeNode | undefined {
|
||||
return this._parent;
|
||||
}
|
||||
|
||||
public set parent(node: TreeNode | undefined) {
|
||||
this._parent = node;
|
||||
}
|
||||
|
||||
public get errorStatusCode(): number | undefined {
|
||||
return this._errorStatusCode;
|
||||
}
|
||||
|
||||
public set errorStatusCode(error: number | undefined) {
|
||||
this._errorStatusCode = error;
|
||||
}
|
||||
|
||||
public generateNodePath(): string | undefined {
|
||||
let path: string | undefined;
|
||||
if (this.parent) {
|
||||
path = this.parent.generateNodePath();
|
||||
}
|
||||
path = path ? `${path}/${this.nodePathValue}` : this.nodePathValue;
|
||||
return path;
|
||||
}
|
||||
|
||||
public findNodeByPath(path: string, expandIfNeeded: boolean = false): Promise<TreeNode | undefined> {
|
||||
let condition: TreeNodePredicate = (node: TreeNode) => node.getNodeInfo().nodePath === path || node.getNodeInfo().nodePath.startsWith(path);
|
||||
let filter: TreeNodePredicate = (node: TreeNode) => path.startsWith(node.getNodeInfo().nodePath);
|
||||
return TreeNode.findNode(this, condition, filter, true);
|
||||
}
|
||||
|
||||
public static async findNode(node: TreeNode, condition: TreeNodePredicate, filter: TreeNodePredicate, expandIfNeeded: boolean): Promise<TreeNode | undefined> {
|
||||
if (!node) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (condition(node)) {
|
||||
return node;
|
||||
}
|
||||
|
||||
let nodeInfo = node.getNodeInfo();
|
||||
if (nodeInfo.isLeaf) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// TODO #3813 support filtering by already expanded / not yet expanded
|
||||
let children = await node.getChildren(false);
|
||||
if (children) {
|
||||
for (let child of children) {
|
||||
if (filter && filter(child)) {
|
||||
let childNode = await this.findNode(child, condition, filter, expandIfNeeded);
|
||||
if (childNode) {
|
||||
return childNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* The value to use for this node in the node path
|
||||
*/
|
||||
public abstract get nodePathValue(): string;
|
||||
|
||||
abstract getChildren(refreshChildren: boolean): TreeNode[] | Promise<TreeNode[]>;
|
||||
abstract getTreeItem(): vscode.TreeItem | Promise<vscode.TreeItem>;
|
||||
|
||||
abstract getNodeInfo(): azdata.NodeInfo;
|
||||
}
|
||||
17
extensions/kusto/src/objectExplorerNodeProvider/types.d.ts
vendored
Normal file
17
extensions/kusto/src/objectExplorerNodeProvider/types.d.ts
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as azdata from 'azdata';
|
||||
|
||||
/**
|
||||
* A tree node in the object explorer tree
|
||||
*
|
||||
* @export
|
||||
*/
|
||||
export interface ITreeNode {
|
||||
getNodeInfo(): azdata.NodeInfo;
|
||||
getChildren(refreshChildren: boolean): ITreeNode[] | Promise<ITreeNode[]>;
|
||||
}
|
||||
77
extensions/kusto/src/prompts/adapter.ts
Normal file
77
extensions/kusto/src/prompts/adapter.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
// This code is originally from https://github.com/DonJayamanne/bowerVSCode
|
||||
// License: https://github.com/DonJayamanne/bowerVSCode/blob/master/LICENSE
|
||||
|
||||
import { window } from 'vscode';
|
||||
import PromptFactory from './factory';
|
||||
import EscapeException from './escapeException';
|
||||
import { IQuestion, IPrompter, IPromptCallback, Answers } from './question';
|
||||
|
||||
// Supports simple pattern for prompting for user input and acting on this
|
||||
export default class CodeAdapter implements IPrompter {
|
||||
|
||||
// TODO define question interface
|
||||
private fixQuestion(question: IQuestion): any {
|
||||
if (question.type === 'checkbox' && Array.isArray(question.choices)) {
|
||||
// For some reason when there's a choice of checkboxes, they aren't formatted properly
|
||||
// Not sure where the issue is
|
||||
question.choices = question.choices.map(item => {
|
||||
if (typeof (item) === 'string') {
|
||||
return { checked: false, name: item, value: item };
|
||||
} else {
|
||||
return item;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public async promptSingle<T>(question: IQuestion, ignoreFocusOut?: boolean): Promise<T | undefined> {
|
||||
let questions: IQuestion[] = [question];
|
||||
const answers = this.prompt(questions, ignoreFocusOut);
|
||||
if (answers) {
|
||||
let response: T = answers[question.name];
|
||||
return response || undefined;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public async prompt<T>(questions: IQuestion[], ignoreFocusOut?: boolean): Promise<Answers<T> | undefined> {
|
||||
// Collapse multiple questions into a set of prompt steps
|
||||
const promptResult = new Promise<Answers<T>>((resolve) => {
|
||||
let answers: Answers<T> = {};
|
||||
questions.forEach(async (question: IQuestion) => {
|
||||
this.fixQuestion(question);
|
||||
const prompt = await PromptFactory.createPrompt(question, ignoreFocusOut);
|
||||
if (!question.shouldPrompt || question.shouldPrompt(answers) === true) {
|
||||
const result = await prompt.render();
|
||||
answers[question.name] = result;
|
||||
|
||||
if (question.onAnswered) {
|
||||
question.onAnswered(result);
|
||||
}
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
resolve(answers);
|
||||
});
|
||||
|
||||
try {
|
||||
return await promptResult;
|
||||
} catch (err) {
|
||||
if (err instanceof EscapeException || err instanceof TypeError) {
|
||||
window.showErrorMessage(err.message);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to make it possible to prompt using callback pattern. Generally Promise is a preferred flow
|
||||
public promptCallback(questions: IQuestion[], callback: IPromptCallback): void {
|
||||
// Collapse multiple questions into a set of prompt steps
|
||||
this.prompt(questions).then(answers => {
|
||||
if (callback && answers) {
|
||||
callback(answers);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
52
extensions/kusto/src/prompts/checkbox.ts
Normal file
52
extensions/kusto/src/prompts/checkbox.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
'use strict';
|
||||
|
||||
// This code is originally from https://github.com/DonJayamanne/bowerVSCode
|
||||
// License: https://github.com/DonJayamanne/bowerVSCode/blob/master/LICENSE
|
||||
|
||||
import { window } from 'vscode';
|
||||
import Prompt from './prompt';
|
||||
import EscapeException from './escapeException';
|
||||
|
||||
const figures = require('figures');
|
||||
|
||||
export default class CheckboxPrompt extends Prompt {
|
||||
|
||||
constructor(question: any, ignoreFocusOut?: boolean) {
|
||||
super(question, ignoreFocusOut);
|
||||
}
|
||||
|
||||
public render(): any {
|
||||
let choices = this._question.choices.reduce((result, choice) => {
|
||||
let choiceName = choice.name || choice;
|
||||
result[`${choice.checked === true ? figures.radioOn : figures.radioOff} ${choiceName}`] = choice;
|
||||
return result;
|
||||
}, {});
|
||||
|
||||
let options = this.defaultQuickPickOptions;
|
||||
options.placeHolder = this._question.message;
|
||||
|
||||
let quickPickOptions = Object.keys(choices);
|
||||
quickPickOptions.push(figures.tick);
|
||||
|
||||
return window.showQuickPick(quickPickOptions, options)
|
||||
.then(result => {
|
||||
if (result === undefined) {
|
||||
throw new EscapeException();
|
||||
}
|
||||
|
||||
if (result !== figures.tick) {
|
||||
choices[result].checked = !choices[result].checked;
|
||||
|
||||
return this.render();
|
||||
}
|
||||
|
||||
return this._question.choices.reduce((result2, choice) => {
|
||||
if (choice.checked === true) {
|
||||
result2.push(choice.value);
|
||||
}
|
||||
|
||||
return result2;
|
||||
}, []);
|
||||
});
|
||||
}
|
||||
}
|
||||
36
extensions/kusto/src/prompts/confirm.ts
Normal file
36
extensions/kusto/src/prompts/confirm.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
'use strict';
|
||||
|
||||
// This code is originally from https://github.com/DonJayamanne/bowerVSCode
|
||||
// License: https://github.com/DonJayamanne/bowerVSCode/blob/master/LICENSE
|
||||
|
||||
import * as nls from 'vscode-nls';
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
import { window } from 'vscode';
|
||||
import Prompt from './prompt';
|
||||
import EscapeException from './escapeException';
|
||||
|
||||
export default class ConfirmPrompt extends Prompt {
|
||||
|
||||
constructor(question: any, ignoreFocusOut?: boolean) {
|
||||
super(question, ignoreFocusOut);
|
||||
}
|
||||
|
||||
public render(): any {
|
||||
let choices: { [id: string]: boolean } = {};
|
||||
choices[localize('msgYes', 'Yes')] = true;
|
||||
choices[localize('msgNo', 'No')] = false;
|
||||
|
||||
let options = this.defaultQuickPickOptions;
|
||||
options.placeHolder = this._question.message;
|
||||
|
||||
return window.showQuickPick(Object.keys(choices), options)
|
||||
.then(result => {
|
||||
if (result === undefined) {
|
||||
throw new EscapeException();
|
||||
}
|
||||
|
||||
return choices[result] || false;
|
||||
});
|
||||
}
|
||||
}
|
||||
8
extensions/kusto/src/prompts/escapeException.ts
Normal file
8
extensions/kusto/src/prompts/escapeException.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export default class EscapeException extends Error {
|
||||
|
||||
}
|
||||
78
extensions/kusto/src/prompts/expand.ts
Normal file
78
extensions/kusto/src/prompts/expand.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
'use strict';
|
||||
|
||||
// This code is originally from https://github.com/DonJayamanne/bowerVSCode
|
||||
// License: https://github.com/DonJayamanne/bowerVSCode/blob/master/LICENSE
|
||||
|
||||
import vscode = require('vscode');
|
||||
import Prompt from './prompt';
|
||||
import EscapeException from './escapeException';
|
||||
import { INameValueChoice } from './question';
|
||||
|
||||
const figures = require('figures');
|
||||
|
||||
export default class ExpandPrompt extends Prompt {
|
||||
|
||||
constructor(question: any, ignoreFocusOut?: boolean) {
|
||||
super(question, ignoreFocusOut);
|
||||
}
|
||||
|
||||
public render(): any {
|
||||
// label indicates this is a quickpick item. Otherwise it's a name-value pair
|
||||
if (this._question.choices[0].label) {
|
||||
return this.renderQuickPick(this._question.choices);
|
||||
} else {
|
||||
return this.renderNameValueChoice(this._question.choices);
|
||||
}
|
||||
}
|
||||
|
||||
private renderQuickPick(choices: vscode.QuickPickItem[]): any {
|
||||
let options = this.defaultQuickPickOptions;
|
||||
options.placeHolder = this._question.message;
|
||||
|
||||
return vscode.window.showQuickPick(choices, options)
|
||||
.then(result => {
|
||||
if (result === undefined) {
|
||||
throw new EscapeException();
|
||||
}
|
||||
|
||||
return this.validateAndReturn(result || false);
|
||||
});
|
||||
}
|
||||
private renderNameValueChoice(choices: INameValueChoice[]): any {
|
||||
const choiceMap = this._question.choices.reduce((result, choice) => {
|
||||
result[choice.name] = choice.value;
|
||||
return result;
|
||||
}, {});
|
||||
|
||||
let options = this.defaultQuickPickOptions;
|
||||
options.placeHolder = this._question.message;
|
||||
|
||||
return vscode.window.showQuickPick(Object.keys(choiceMap), options)
|
||||
.then(result => {
|
||||
if (result === undefined) {
|
||||
throw new EscapeException();
|
||||
}
|
||||
|
||||
// Note: cannot be used with 0 or false responses
|
||||
let returnVal = choiceMap[result] || false;
|
||||
return this.validateAndReturn(returnVal);
|
||||
});
|
||||
}
|
||||
|
||||
private validateAndReturn(value: any): any {
|
||||
if (!this.validate(value)) {
|
||||
return this.render();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private validate(value: any): boolean {
|
||||
const validationError = this._question.validate ? this._question.validate(value || '') : undefined;
|
||||
|
||||
if (validationError) {
|
||||
this._question.message = `${figures.warning} ${validationError}`;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
35
extensions/kusto/src/prompts/factory.ts
Normal file
35
extensions/kusto/src/prompts/factory.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
'use strict';
|
||||
|
||||
// This code is originally from https://github.com/DonJayamanne/bowerVSCode
|
||||
// License: https://github.com/DonJayamanne/bowerVSCode/blob/master/LICENSE
|
||||
|
||||
import Prompt from './prompt';
|
||||
import InputPrompt from './input';
|
||||
import PasswordPrompt from './password';
|
||||
import ListPrompt from './list';
|
||||
import ConfirmPrompt from './confirm';
|
||||
import CheckboxPrompt from './checkbox';
|
||||
import ExpandPrompt from './expand';
|
||||
|
||||
export default class PromptFactory {
|
||||
|
||||
public static createPrompt(question: any, ignoreFocusOut?: boolean): Prompt {
|
||||
switch (question.type || 'input') {
|
||||
case 'string':
|
||||
case 'input':
|
||||
return new InputPrompt(question, ignoreFocusOut);
|
||||
case 'password':
|
||||
return new PasswordPrompt(question, ignoreFocusOut);
|
||||
case 'list':
|
||||
return new ListPrompt(question, ignoreFocusOut);
|
||||
case 'confirm':
|
||||
return new ConfirmPrompt(question, ignoreFocusOut);
|
||||
case 'checkbox':
|
||||
return new CheckboxPrompt(question, ignoreFocusOut);
|
||||
case 'expand':
|
||||
return new ExpandPrompt(question, ignoreFocusOut);
|
||||
default:
|
||||
throw new Error(`Could not find a prompt for question type ${question.type}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
59
extensions/kusto/src/prompts/input.ts
Normal file
59
extensions/kusto/src/prompts/input.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
'use strict';
|
||||
|
||||
// This code is originally from https://github.com/DonJayamanne/bowerVSCode
|
||||
// License: https://github.com/DonJayamanne/bowerVSCode/blob/master/LICENSE
|
||||
|
||||
import { window, InputBoxOptions } from 'vscode';
|
||||
import Prompt from './prompt';
|
||||
import EscapeException from './escapeException';
|
||||
|
||||
const figures = require('figures');
|
||||
|
||||
export default class InputPrompt extends Prompt {
|
||||
|
||||
protected _options: InputBoxOptions;
|
||||
|
||||
constructor(question: any, ignoreFocusOut?: boolean) {
|
||||
super(question, ignoreFocusOut);
|
||||
|
||||
this._options = this.defaultInputBoxOptions;
|
||||
this._options.prompt = this._question.message;
|
||||
}
|
||||
|
||||
// Helper for callers to know the right type to get from the type factory
|
||||
public static get promptType(): string { return 'input'; }
|
||||
|
||||
public render(): any {
|
||||
// Prefer default over the placeHolder, if specified
|
||||
let placeHolder = this._question.default ? this._question.default : this._question.placeHolder;
|
||||
|
||||
if (this._question.default instanceof Error) {
|
||||
placeHolder = this._question.default.message;
|
||||
this._question.default = undefined;
|
||||
}
|
||||
|
||||
this._options.placeHolder = placeHolder;
|
||||
|
||||
return window.showInputBox(this._options)
|
||||
.then(result => {
|
||||
if (result === undefined) {
|
||||
throw new EscapeException();
|
||||
}
|
||||
|
||||
if (result === '') {
|
||||
// Use the default value, if defined
|
||||
result = this._question.default || '';
|
||||
}
|
||||
|
||||
const validationError = this._question.validate ? this._question.validate(result || '') : undefined;
|
||||
|
||||
if (validationError) {
|
||||
this._question.default = new Error(`${figures.warning} ${validationError}`);
|
||||
|
||||
return this.render();
|
||||
}
|
||||
|
||||
return result;
|
||||
});
|
||||
}
|
||||
}
|
||||
33
extensions/kusto/src/prompts/list.ts
Normal file
33
extensions/kusto/src/prompts/list.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
'use strict';
|
||||
|
||||
// This code is originally from https://github.com/DonJayamanne/bowerVSCode
|
||||
// License: https://github.com/DonJayamanne/bowerVSCode/blob/master/LICENSE
|
||||
|
||||
import { window } from 'vscode';
|
||||
import Prompt from './prompt';
|
||||
import EscapeException from './escapeException';
|
||||
|
||||
export default class ListPrompt extends Prompt {
|
||||
constructor(question: any, ignoreFocusOut?: boolean) {
|
||||
super(question, ignoreFocusOut);
|
||||
}
|
||||
|
||||
public render(): any {
|
||||
const choices = this._question.choices.reduce((result, choice) => {
|
||||
result[choice.name] = choice.value;
|
||||
return result;
|
||||
}, {});
|
||||
|
||||
let options = this.defaultQuickPickOptions;
|
||||
options.placeHolder = this._question.message;
|
||||
|
||||
return window.showQuickPick(Object.keys(choices), options)
|
||||
.then(result => {
|
||||
if (result === undefined) {
|
||||
throw new EscapeException();
|
||||
}
|
||||
|
||||
return choices[result];
|
||||
});
|
||||
}
|
||||
}
|
||||
15
extensions/kusto/src/prompts/password.ts
Normal file
15
extensions/kusto/src/prompts/password.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
'use strict';
|
||||
|
||||
// This code is originally from https://github.com/DonJayamanne/bowerVSCode
|
||||
// License: https://github.com/DonJayamanne/bowerVSCode/blob/master/LICENSE
|
||||
|
||||
import InputPrompt from './input';
|
||||
|
||||
export default class PasswordPrompt extends InputPrompt {
|
||||
|
||||
constructor(question: any, ignoreFocusOut?: boolean) {
|
||||
super(question, ignoreFocusOut);
|
||||
|
||||
this._options.password = true;
|
||||
}
|
||||
}
|
||||
70
extensions/kusto/src/prompts/progressIndicator.ts
Normal file
70
extensions/kusto/src/prompts/progressIndicator.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
'use strict';
|
||||
|
||||
// This code is originally from https://github.com/DonJayamanne/bowerVSCode
|
||||
// License: https://github.com/DonJayamanne/bowerVSCode/blob/master/LICENSE
|
||||
|
||||
import { window, StatusBarItem, StatusBarAlignment } from 'vscode';
|
||||
|
||||
export default class ProgressIndicator {
|
||||
|
||||
private _statusBarItem: StatusBarItem;
|
||||
|
||||
constructor() {
|
||||
this._statusBarItem = window.createStatusBarItem(StatusBarAlignment.Left);
|
||||
}
|
||||
|
||||
private _tasks: string[] = [];
|
||||
public beginTask(task: string): void {
|
||||
this._tasks.push(task);
|
||||
this.displayProgressIndicator();
|
||||
}
|
||||
|
||||
public endTask(task: string): void {
|
||||
if (this._tasks.length > 0) {
|
||||
this._tasks.pop();
|
||||
}
|
||||
|
||||
this.setMessage();
|
||||
}
|
||||
|
||||
private setMessage(): void {
|
||||
if (this._tasks.length === 0) {
|
||||
this._statusBarItem.text = '';
|
||||
this.hideProgressIndicator();
|
||||
return;
|
||||
}
|
||||
|
||||
this._statusBarItem.text = this._tasks[this._tasks.length - 1];
|
||||
this._statusBarItem.show();
|
||||
}
|
||||
|
||||
private _interval: any;
|
||||
private displayProgressIndicator(): void {
|
||||
this.setMessage();
|
||||
this.hideProgressIndicator();
|
||||
this._interval = setInterval(() => this.onDisplayProgressIndicator(), 100);
|
||||
}
|
||||
private hideProgressIndicator(): void {
|
||||
if (this._interval) {
|
||||
clearInterval(this._interval);
|
||||
this._interval = undefined;
|
||||
}
|
||||
this.ProgressCounter = 0;
|
||||
}
|
||||
|
||||
private ProgressText = ['|', '/', '-', '\\', '|', '/', '-', '\\'];
|
||||
private ProgressCounter = 0;
|
||||
private onDisplayProgressIndicator(): void {
|
||||
if (this._tasks.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
let txt = this.ProgressText[this.ProgressCounter];
|
||||
this._statusBarItem.text = this._tasks[this._tasks.length - 1] + ' ' + txt;
|
||||
this.ProgressCounter++;
|
||||
|
||||
if (this.ProgressCounter >= this.ProgressText.length - 1) {
|
||||
this.ProgressCounter = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
33
extensions/kusto/src/prompts/prompt.ts
Normal file
33
extensions/kusto/src/prompts/prompt.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
'use strict';
|
||||
|
||||
// This code is originally from https://github.com/DonJayamanne/bowerVSCode
|
||||
// License: https://github.com/DonJayamanne/bowerVSCode/blob/master/LICENSE
|
||||
|
||||
import { InputBoxOptions, QuickPickOptions } from 'vscode';
|
||||
|
||||
abstract class Prompt {
|
||||
|
||||
protected _question: any;
|
||||
protected _ignoreFocusOut?: boolean;
|
||||
|
||||
constructor(question: any, ignoreFocusOut?: boolean) {
|
||||
this._question = question;
|
||||
this._ignoreFocusOut = ignoreFocusOut ? ignoreFocusOut : false;
|
||||
}
|
||||
|
||||
public abstract render(): any;
|
||||
|
||||
protected get defaultQuickPickOptions(): QuickPickOptions {
|
||||
return {
|
||||
ignoreFocusOut: this._ignoreFocusOut
|
||||
};
|
||||
}
|
||||
|
||||
protected get defaultInputBoxOptions(): InputBoxOptions {
|
||||
return {
|
||||
ignoreFocusOut: this._ignoreFocusOut
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default Prompt;
|
||||
73
extensions/kusto/src/prompts/question.ts
Normal file
73
extensions/kusto/src/prompts/question.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
// TODO: Common file with mssql
|
||||
import vscode = require('vscode');
|
||||
|
||||
export class QuestionTypes {
|
||||
public static get input(): string { return 'input'; }
|
||||
public static get password(): string { return 'password'; }
|
||||
public static get list(): string { return 'list'; }
|
||||
public static get confirm(): string { return 'confirm'; }
|
||||
public static get checkbox(): string { return 'checkbox'; }
|
||||
public static get expand(): string { return 'expand'; }
|
||||
}
|
||||
|
||||
// Question interface to clarify how to use the prompt feature
|
||||
// based on Bower Question format: https://github.com/bower/bower/blob/89069784bb46bfd6639b4a75e98a0d7399a8c2cb/packages/bower-logger/README.md
|
||||
export interface IQuestion {
|
||||
// Type of question (see QuestionTypes)
|
||||
type: string;
|
||||
// Name of the question for disambiguation
|
||||
name: string;
|
||||
// Message to display to the user
|
||||
message: string;
|
||||
// Optional placeHolder to give more detailed information to the user
|
||||
placeHolder?: any;
|
||||
// Optional default value - this will be used instead of placeHolder
|
||||
default?: any;
|
||||
// optional set of choices to be used. Can be QuickPickItems or a simple name-value pair
|
||||
choices?: Array<vscode.QuickPickItem | INameValueChoice>;
|
||||
// Optional validation function that returns an error string if validation fails
|
||||
validate?: (value: any) => string;
|
||||
// Optional pre-prompt function. Takes in set of answers so far, and returns true if prompt should occur
|
||||
shouldPrompt?: (answers: { [id: string]: any }) => boolean;
|
||||
// Optional action to take on the question being answered
|
||||
onAnswered?: (value: any) => void;
|
||||
// Optional set of options to support matching choices.
|
||||
matchOptions?: vscode.QuickPickOptions;
|
||||
}
|
||||
|
||||
// Pair used to display simple choices to the user
|
||||
export interface INameValueChoice {
|
||||
name: string;
|
||||
value: any;
|
||||
}
|
||||
|
||||
// Generic object that can be used to define a set of questions and handle the result
|
||||
export interface IQuestionHandler {
|
||||
// Set of questions to be answered
|
||||
questions: IQuestion[];
|
||||
// Optional callback, since questions may handle themselves
|
||||
callback?: IPromptCallback;
|
||||
}
|
||||
|
||||
export type Answers<T> = { [key: string]: T };
|
||||
|
||||
export interface IPrompter {
|
||||
promptSingle<T>(question: IQuestion, ignoreFocusOut?: boolean): Promise<T | undefined>;
|
||||
/**
|
||||
* Prompts for multiple questions
|
||||
*
|
||||
* @returns Map of question IDs to results, or undefined if
|
||||
* the user canceled the question session
|
||||
*/
|
||||
prompt<T>(questions: IQuestion[], ignoreFocusOut?: boolean): Promise<Answers<T> | undefined>;
|
||||
promptCallback(questions: IQuestion[], callback: IPromptCallback): void;
|
||||
}
|
||||
|
||||
export interface IPromptCallback {
|
||||
(answers: { [id: string]: any }): void;
|
||||
}
|
||||
165
extensions/kusto/src/telemetry.ts
Normal file
165
extensions/kusto/src/telemetry.ts
Normal file
@@ -0,0 +1,165 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import TelemetryReporter from 'vscode-extension-telemetry';
|
||||
import { ErrorAction, ErrorHandler, Message, CloseAction } from 'vscode-languageclient';
|
||||
|
||||
import * as Utils from './utils';
|
||||
import * as Constants from './constants';
|
||||
import { localize } from './localize';
|
||||
|
||||
const packageJson = require('../package.json');
|
||||
const viewKnownIssuesAction = localize('viewKnownIssuesText', "View Known Issues");
|
||||
|
||||
export interface ITelemetryEventProperties {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
export interface ITelemetryEventMeasures {
|
||||
[key: string]: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters error paths to only include source files. Exported to support testing
|
||||
*/
|
||||
export function FilterErrorPath(line: string): string | undefined {
|
||||
if (line) {
|
||||
let values: string[] = line.split('/out/');
|
||||
if (values.length <= 1) {
|
||||
// Didn't match expected format
|
||||
return line;
|
||||
} else {
|
||||
return values[1];
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export class Telemetry {
|
||||
private static reporter: TelemetryReporter;
|
||||
private static disabled: boolean;
|
||||
|
||||
/**
|
||||
* Disable telemetry reporting
|
||||
*/
|
||||
public static disable(): void {
|
||||
this.disabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the telemetry reporter for use.
|
||||
*/
|
||||
public static initialize(): void {
|
||||
if (typeof this.reporter === 'undefined') {
|
||||
// Check if the user has opted out of telemetry
|
||||
if (!vscode.workspace.getConfiguration('telemetry').get<boolean>('enableTelemetry', true)) {
|
||||
this.disable();
|
||||
return;
|
||||
}
|
||||
|
||||
let packageInfo = Utils.getPackageInfo(packageJson)!;
|
||||
this.reporter = new TelemetryReporter(packageInfo.name, packageInfo.version, packageInfo.aiKey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a telemetry event for an exception
|
||||
*/
|
||||
public static sendTelemetryEventForException(
|
||||
err: any, methodName: string, extensionConfigName: string): void {
|
||||
let stackArray: string[];
|
||||
let firstLine: string = '';
|
||||
if (err !== undefined && err.stack !== undefined) {
|
||||
stackArray = err.stack.split('\n');
|
||||
if (stackArray !== undefined && stackArray.length >= 2) {
|
||||
firstLine = stackArray[1]; // The fist line is the error message and we don't want to send that telemetry event
|
||||
firstLine = FilterErrorPath(firstLine)!;
|
||||
}
|
||||
}
|
||||
|
||||
// Only adding the method name and the fist line of the stack trace. We don't add the error message because it might have PII
|
||||
this.sendTelemetryEvent('Exception', { methodName: methodName, errorLine: firstLine });
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a telemetry event using application insights
|
||||
*/
|
||||
public static sendTelemetryEvent(
|
||||
eventName: string,
|
||||
properties?: ITelemetryEventProperties,
|
||||
measures?: ITelemetryEventMeasures): void {
|
||||
|
||||
if (typeof this.disabled === 'undefined') {
|
||||
this.disabled = false;
|
||||
}
|
||||
|
||||
if (this.disabled || typeof (this.reporter) === 'undefined') {
|
||||
// Don't do anything if telemetry is disabled
|
||||
return;
|
||||
}
|
||||
|
||||
if (!properties || typeof properties === 'undefined') {
|
||||
properties = {};
|
||||
}
|
||||
|
||||
try {
|
||||
this.reporter.sendTelemetryEvent(eventName, properties, measures);
|
||||
} catch (telemetryErr) {
|
||||
// If sending telemetry event fails ignore it so it won't break the extension
|
||||
console.error('Failed to send telemetry event. error: ' + telemetryErr);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Language Service client errors
|
||||
*/
|
||||
export class LanguageClientErrorHandler implements ErrorHandler {
|
||||
|
||||
/**
|
||||
* Show an error message prompt with a link to known issues wiki page
|
||||
* @memberOf LanguageClientErrorHandler
|
||||
*/
|
||||
showOnErrorPrompt(): void {
|
||||
Telemetry.sendTelemetryEvent(Constants.serviceName + 'Crash');
|
||||
vscode.window.showErrorMessage(
|
||||
localize('serviceCrashMessage', "{0} component exited unexpectedly. Please restart Azure Data Studio.", Constants.serviceName),
|
||||
viewKnownIssuesAction).then(action => {
|
||||
if (action && action === viewKnownIssuesAction) {
|
||||
vscode.env.openExternal(vscode.Uri.parse(Constants.serviceCrashLink));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for language service client error
|
||||
*
|
||||
* @memberOf LanguageClientErrorHandler
|
||||
*/
|
||||
error(error: Error, message: Message, count: number): ErrorAction {
|
||||
this.showOnErrorPrompt();
|
||||
|
||||
// we don't retry running the service since crashes leave the extension
|
||||
// in a bad, unrecovered state
|
||||
return ErrorAction.Shutdown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for language service client closed
|
||||
*
|
||||
* @memberOf LanguageClientErrorHandler
|
||||
*/
|
||||
closed(): CloseAction {
|
||||
this.showOnErrorPrompt();
|
||||
|
||||
// we don't retry running the service since crashes leave the extension
|
||||
// in a bad, unrecovered state
|
||||
return CloseAction.DoNotRestart;
|
||||
}
|
||||
}
|
||||
|
||||
Telemetry.initialize();
|
||||
14
extensions/kusto/src/types.ts
Normal file
14
extensions/kusto/src/types.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @returns whether the provided parameter is undefined or null.
|
||||
*/
|
||||
export function isUndefinedOrNull(obj: any): boolean {
|
||||
// Intentional ==
|
||||
// eslint-disable-next-line eqeqeq
|
||||
return obj == undefined;
|
||||
}
|
||||
8
extensions/kusto/src/typings/refs.d.ts
vendored
Normal file
8
extensions/kusto/src/typings/refs.d.ts
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
/// <reference path='../../../../src/sql/azdata.d.ts'/>
|
||||
/// <reference path='../../../../src/sql/azdata.proposed.d.ts'/>
|
||||
/// <reference path='../../../../src/vs/vscode.d.ts'/>
|
||||
141
extensions/kusto/src/utils.ts
Normal file
141
extensions/kusto/src/utils.ts
Normal file
@@ -0,0 +1,141 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
//TODO: This is the same file from mssql. Move this into a common place.
|
||||
import * as azdata from 'azdata';
|
||||
import * as vscode from 'vscode';
|
||||
import * as path from 'path';
|
||||
import * as os from 'os';
|
||||
import * as findRemoveSync from 'find-remove';
|
||||
import { promises as fs } from 'fs';
|
||||
|
||||
const configTracingLevel = 'tracingLevel';
|
||||
const configLogRetentionMinutes = 'logRetentionMinutes';
|
||||
const configLogFilesRemovalLimit = 'logFilesRemovalLimit';
|
||||
const extensionConfigSectionName = 'kusto';
|
||||
|
||||
export function removeOldLogFiles(logPath: string, prefix: string): JSON {
|
||||
return findRemoveSync(logPath, { age: { seconds: getConfigLogRetentionSeconds() }, limit: getConfigLogFilesRemovalLimit() });
|
||||
}
|
||||
|
||||
export function getConfiguration(config: string = extensionConfigSectionName): vscode.WorkspaceConfiguration {
|
||||
return vscode.workspace.getConfiguration(extensionConfigSectionName);
|
||||
}
|
||||
|
||||
export function getConfigLogFilesRemovalLimit(): number | undefined {
|
||||
let config = getConfiguration();
|
||||
if (config && config[configLogFilesRemovalLimit]) {
|
||||
return Number((config[configLogFilesRemovalLimit]).toFixed(0));
|
||||
}
|
||||
else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export function getConfigLogRetentionSeconds(): number | undefined {
|
||||
let config = getConfiguration();
|
||||
if (config && config[configLogRetentionMinutes]) {
|
||||
return Number((config[configLogRetentionMinutes] * 60).toFixed(0));
|
||||
}
|
||||
else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export function getConfigTracingLevel(): string | undefined {
|
||||
let config = getConfiguration();
|
||||
if (config) {
|
||||
return config[configTracingLevel];
|
||||
}
|
||||
else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export function getLogFileName(prefix: string, pid: number): string {
|
||||
return `${prefix}_${pid}.log`;
|
||||
}
|
||||
|
||||
export function getCommonLaunchArgsAndCleanupOldLogFiles(logPath: string, fileName: string, executablePath: string): string[] {
|
||||
let launchArgs: string[] = [];
|
||||
launchArgs.push('--log-file');
|
||||
let logFile = path.join(logPath, fileName);
|
||||
launchArgs.push(logFile);
|
||||
|
||||
console.log(`logFile for ${path.basename(executablePath)} is ${logFile}`);
|
||||
console.log(`This process (ui Extenstion Host) is pid: ${process.pid}`);
|
||||
// Delete old log files
|
||||
let deletedLogFiles = removeOldLogFiles(logPath, fileName);
|
||||
console.log(`Old log files deletion report: ${JSON.stringify(deletedLogFiles)}`);
|
||||
let config = getConfigTracingLevel();
|
||||
if (config) {
|
||||
launchArgs.push('--tracing-level');
|
||||
launchArgs.push(config);
|
||||
}
|
||||
return launchArgs;
|
||||
}
|
||||
|
||||
export function ensure(target: object, key: string): any {
|
||||
if (target[key] === void 0) {
|
||||
target[key] = {} as any;
|
||||
}
|
||||
return target[key];
|
||||
}
|
||||
|
||||
export interface IPackageInfo {
|
||||
name: string;
|
||||
version: string;
|
||||
aiKey: string;
|
||||
}
|
||||
|
||||
export function getPackageInfo(packageJson: IPackageInfo): IPackageInfo | undefined {
|
||||
if (packageJson) {
|
||||
return {
|
||||
name: packageJson.name,
|
||||
version: packageJson.version,
|
||||
aiKey: packageJson.aiKey
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function verifyPlatform(): Thenable<boolean> {
|
||||
if (os.platform() === 'darwin' && parseFloat(os.release()) < 16) {
|
||||
return Promise.resolve(false);
|
||||
} else {
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
}
|
||||
|
||||
export function getErrorMessage(error: Error | any, removeHeader: boolean = false): string {
|
||||
let errorMessage: string = (error instanceof Error) ? error.message : error.toString();
|
||||
if (removeHeader) {
|
||||
errorMessage = removeErrorHeader(errorMessage);
|
||||
}
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
export function removeErrorHeader(errorMessage: string): string {
|
||||
if (errorMessage && errorMessage !== '') {
|
||||
let header: string = 'Error:';
|
||||
if (errorMessage.startsWith(header)) {
|
||||
errorMessage = errorMessage.substring(header.length);
|
||||
}
|
||||
}
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
export function isObjectExplorerContext(object: any): object is azdata.ObjectExplorerContext {
|
||||
return 'connectionProfile' in object && 'isConnectionNode' in object;
|
||||
}
|
||||
|
||||
export async function exists(path: string): Promise<boolean> {
|
||||
try {
|
||||
await fs.access(path);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
448
extensions/kusto/syntaxes/kusto.tmLanguage
Normal file
448
extensions/kusto/syntaxes/kusto.tmLanguage
Normal file
@@ -0,0 +1,448 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>scopeName</key>
|
||||
<string>source.kusto</string>
|
||||
|
||||
<key>fileTypes</key>
|
||||
<array>
|
||||
<string>csl</string>
|
||||
<string>kusto</string>
|
||||
</array>
|
||||
|
||||
<key>name</key>
|
||||
<string>kusto file</string>
|
||||
|
||||
<key>patterns</key>
|
||||
<!-- Kusto Query Language
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/
|
||||
-->
|
||||
<array>
|
||||
<dict>
|
||||
<!-- Query statements
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/statements
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(let|set|alias|declare|pattern|restrict|access|to|set)\b</string>
|
||||
<key>name</key>
|
||||
<string>keyword.control.kusto</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Special functions
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/clusterfunction
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(cluster|database|materialize|table|toscalar)(?=\W*\()</string>
|
||||
<key>name</key>
|
||||
<string>support.function</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Scalar operators
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/binoperators
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(and|or|!in|has|has_cs|hasprefix|hasprefix_cs|hassuffix|hassuffix_cs|contains|contains_cs|startswith|startswith_cs|endswith|endswith_cs|matches|regex|in|between)\b</string>
|
||||
<key>name</key>
|
||||
<string>keyword.operator.kusto</string>
|
||||
</dict>
|
||||
<!-- Scalar functions
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/scalarfunctions
|
||||
-->
|
||||
<dict>
|
||||
<!-- Scalar function: Binary Functions
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/scalarfunctions#binary-functions
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(binary_and|binary_not|binary_or|binary_shift_left|binary_shift_right|binary_xor)(?=\W*\()</string>
|
||||
<key>name</key>
|
||||
<string>support.function</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Scalar function: Conversion Functions
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/scalarfunctions#binary-functions
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(tobool|todatetime|todecimal|todouble|toguid|tohex|toreal|toint|tolong|tolower|toreal|tostring|totimespan|toupper|to_utf8|translate|treepath|trim|trim_end|trim_start|url_decode|url_encode|weekofyear|welch_test|zip)(?=\W*\()</string>
|
||||
<key>name</key>
|
||||
<string>support.function</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- timespan literals
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/scalar-data-types/timespan#timespan-literals
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>(?<=\.\d|\d|\d\W)(d|h|m|s|ms|microsecond|tick|seconds)\b</string>
|
||||
<key>name</key>
|
||||
<string>variable.language</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Scalar function: DateTime/Timespan Functions
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/scalarfunctions#datetimetimespan-functions
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(ago|datetime_add|datetime_part|datetime_diff|dayofmonth|dayofweek|dayofyear|endofday|endofmonth|endofweek|endofyear|format_datetime|format_timespan|getmonth|getyear|hourofday|make_datetime|make_timespan|monthofyear|now|startofday|startofmonth|startofweek|startofyear|todatetime|totimespan|weekofyear)(?=\W*\()</string>
|
||||
<key>name</key>
|
||||
<string>support.function</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Scalar function: Dynamic/Array Functions
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/scalarfunctions#dynamicarray-functions
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(array_concat|array_length|array_slice|array_split|array_strcat|bag_keys|pack|pack_all|pack_array|repeat|treepath|zip)(?=\W*\()</string>
|
||||
<key>name</key>
|
||||
<string>support.function</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Scalar function: Window Scalar Functions
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/scalarfunctions#window-scalar-functions
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(next|prev|row_cumsum|row_number)(?=\W*\()</string>
|
||||
<key>name</key>
|
||||
<string>support.function</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Scalar function: Flow Control Functions
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/scalarfunctions#flow-control-functions
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(toscalar)(?=\W*\()</string>
|
||||
<key>name</key>
|
||||
<string>support.function</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Scalar function: Mathematical Functions
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/scalarfunctions#mathematical-functions
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(abs|acos|asin|atan|atan2|beta_cdf|beta_inv|beta_pdf|cos|cot|degrees|exp|exp100|exp2|gamma|hash|isfinite|isinf|isnan|log|log10|log2|loggamma|not|pi|pow|radians|rand|range|round|sign|sin|sqrt|tan|welch_test)(?=\W*\()</string>
|
||||
<key>name</key>
|
||||
<string>support.function</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Scalar function: Metadata Functions
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/scalarfunctions#metadata-functions
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(column_ifexists|current_principal|cursor_after|extent_id|extent_tags|ingestion_time)(?=\W*\()</string>
|
||||
<key>name</key>
|
||||
<string>support.function</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Scalar function: Rounding Functions
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/scalarfunctions#rounding-functions
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(bin|bin_at|ceiling|floor)(?=\W*\()</string>
|
||||
<key>name</key>
|
||||
<string>support.function</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Scalar function: Conditional Functions
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/scalarfunctions#conditional-functions
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(case|coalesce|iif|iff|max_of|min_of)(?=\W*\()</string>
|
||||
<key>name</key>
|
||||
<string>support.function</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Scalar function: Series Element-wise Functions
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/scalarfunctions#series-element-wise-functions
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(series_add|series_divide|series_equals|series_greater|series_greater_equals|series_less|series_less_equals|series_multiply|series_not_equals|series_subtract)(?=\W*\()</string>
|
||||
<key>name</key>
|
||||
<string>support.function</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Scalar function: Series Processing Functions
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/scalarfunctions#series-processing-functions
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(series_decompose|series_decompose_anomalies|series_decompose_forecast|series_fill_backward|series_fill_const|series_fill_forward|series_fill_linear|series_fir|series_fit_2lines|series_fit_2lines_dynamic|series_fit_line|series_fit_line_dynamic|series_iir|series_outliers|series_periods_detect|series_periods_validate|series_seasonal|series_stats|series_stats_dynamic)(?=\W*\()</string>
|
||||
<key>name</key>
|
||||
<string>support.function</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Scalar function: String Functions
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/scalarfunctions#string-functions
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(base64_decodestring|base64_encodestring|countof|extract|extract_all|extractjson|indexof|isempty|isnotempty|isnotnull|isnull|parse_ipv4|parse_json|parse_url|parse_urlquery|parse_version|replace|reverse|split|strcat|strcat_delim|strcmp|strlen|strrep|substring|toupper|translate|trim|trim_end|trim_start|url_decode|url_encode)(?=\W*\()</string>
|
||||
<key>name</key>
|
||||
<string>support.function</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Scalar function: Type Functions
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/scalarfunctions#type-functions
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(gettype)(?=\W*\()</string>
|
||||
<key>name</key>
|
||||
<string>support.function</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Scalar function: Scalar Aggregation Functions
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/scalarfunctions#scalar-aggregation-functions
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(dcount_hll|hll_merge|percentile_tdigest|percentrank_tdigest|rank_tdigest|tdigest_merge)(?=\W*\()</string>
|
||||
<key>name</key>
|
||||
<string>support.function</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Aggregation functions
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/any-aggfunction
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(any|arg_max|arg_min|avg|avgif|buildschema|count|countif|dcount|dcountif|hll|hll_merge|make_bag|make_list|make_set|max|min|percentiles|stdev|stdevif|stdevp|sum|sumif|tdigest|tdigest_merge|variance|varianceif|variancep)(?=\W*\()</string>
|
||||
<key>name</key>
|
||||
<string>support.function</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Window functions
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/windowsfunctions
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(next|prev|row_cumsum|row_number)(?=\W*\()</string>
|
||||
<key>name</key>
|
||||
<string>support.function</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- User Analytics (evaluate plugins)
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/useranalytics
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(activity_counts_metrics|sliding_window_counts|activity_metrics|new_activity_metrics|activity_engagement|active_users_count|session_count|funnel_sequence|funnel_sequence_completion)(?=\W*\()</string>
|
||||
<key>name</key>
|
||||
<string>support.function</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- User-defined functions
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/functions/user-defined-functions
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\.create-or-alter</string>
|
||||
<key>name</key>
|
||||
<string>keyword.control.kusto</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- User-defined functions
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/functions/user-defined-functions
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>(?<=let ).+(?=\W*=)</string>
|
||||
<key>name</key>
|
||||
<string>entity.function.name.lambda.kusto</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- User-defined functions
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/functions/user-defined-functions
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(with|folder|docstring|skipvalidation)\b</string>
|
||||
<key>name</key>
|
||||
<string>keyword.operator.kusto</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\b(function)\b</string>
|
||||
<key>name</key>
|
||||
<string>variable.language</string>
|
||||
</dict>
|
||||
|
||||
<dict>
|
||||
<!-- Data types
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/scalar-data-types/
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(bool|datetime|decimal|dynamic|guid|int|long|real|string|timespan)\b</string>
|
||||
<key>name</key>
|
||||
<string>storage.type</string>
|
||||
</dict>
|
||||
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\b(datatable)(?=\W*\()</string>
|
||||
<key>name</key>
|
||||
<string>support.function</string>
|
||||
</dict>
|
||||
|
||||
<!-- Tabular operators
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/statements
|
||||
-->
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\b(as|consume|count|datatable|distinct|evaluate|extend|externaldata|facet|find|fork|getschema|invoke|join|limit|take|lookup|make-series|mv-expand|order|sort|project-away|project-rename|project|parse|partition|print|range|reduce|render|sample|sample-distinct|search|serialize|sort|summarize|take|top-nested|top|top-hitters|union|where)\b</string>
|
||||
<key>name</key>
|
||||
<string>keyword.operator.special.kusto</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Tabular operators: evalute (plugins)
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/evaluateoperator
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(autocluster|bag_unpack|basket|dcount_intersect|diffpatterns|narrow|pivot|preview|rolling_percentile|sql_request)(?=\W*\()</string>
|
||||
<key>name</key>
|
||||
<string>support.function</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Tabular operators: join
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/joinoperator
|
||||
- TODO $left, $right
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(on|kind|hint\.remote|hint\.strategy)\b</string>
|
||||
<key>name</key>
|
||||
<string>keyword.operator.kusto</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Tabular operators: join ($left, $right)
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/joinoperator
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>(\$left|\$right)\b</string>
|
||||
<key>name</key>
|
||||
<string>keyword.other.kusto</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Tabular operators: join (kinds, strategies)
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/joinoperator
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(innerunique|inner|leftouter|rightouter|fullouter|leftanti|anti|leftantisemi|rightanti|rightantisemi|leftsemi|rightsemi|shuffle|broadcast)\b</string>
|
||||
<key>name</key>
|
||||
<string>keyword.other.kusto</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Tabular operators: make-series (series analysis functions)
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/make-seriesoperator
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(series_fir|series_iir|series_fit_line|series_fit_line_dynamic|series_fit_2lines|series_fit_2lines_dynamic|series_outliers|series_periods_detect|series_periods_validate|series_stats_dynamic|series_stats)(?=\W*\()</string>
|
||||
<key>name</key>
|
||||
<string>support.function</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Tabular operators: make-series (series interpolation functions)
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/make-seriesoperator
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(series_fill_backward|series_fill_const|series_fill_forward|series_fill_linear)(?=\W*\()</string>
|
||||
<key>name</key>
|
||||
<string>support.function</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Tabular operators: mv-expand (bagexpand options)
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/mvexpandoperator
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(bag|array)\b</string>
|
||||
<key>name</key>
|
||||
<string>keyword.operator.kusto</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Tabular operators: order
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/orderoperator
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(asc|desc|nulls first|nulls last)\b</string>
|
||||
<key>name</key>
|
||||
<string>keyword.other.kusto</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Tabular operators: parse
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/parseoperator
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(regex|simple|relaxed)\b</string>
|
||||
<key>name</key>
|
||||
<string>keyword.other.kusto</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Tabular operators: render
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/renderoperator
|
||||
-
|
||||
- TODO Properties (accumulate ... anomalycolumns)
|
||||
- TODO visualization kinds (areachart ... columnchart)
|
||||
- TODO ysplit
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(anomalychart|areachart|barchart|columnchart|ladderchart|linechart|piechart|pivotchart|scatterchart|stackedareachart|table|timechart|timepivot)\b</string>
|
||||
<key>name</key>
|
||||
<string>support.function</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Tabular operators: common helper operators
|
||||
- https://docs.microsoft.com/en-us/azure/kusto/query/evaluateoperator
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(by|from|in|of|to|step|with)\b</string>
|
||||
<key>name</key>
|
||||
<string>keyword.operator.word</string>
|
||||
</dict>
|
||||
|
||||
<dict>
|
||||
<!-- Strings
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>".*?"</string>
|
||||
<key>name</key>
|
||||
<string>string.quoted.double</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\{.*?\}</string>
|
||||
<key>name</key>
|
||||
<string>string.variable</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>'.*?'</string>
|
||||
<key>name</key>
|
||||
<string>string.quoted.single</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Comments
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>//.*</string>
|
||||
<key>name</key>
|
||||
<string>comment.line</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\.?[0-9]*+)|(\.[0-9]+))((e|E)(\+|-)?[0-9]+)?)(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?(?=\b|\w)</string>
|
||||
<key>name</key>
|
||||
<string>constant.numeric</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\b(true|false)\b</string>
|
||||
<key>name</key>
|
||||
<string>constant.language</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Deprecated functions
|
||||
-->
|
||||
<key>match</key>
|
||||
<string>\b(array_strcat|make_dictionary|makelist|makeset|mvexpand|todynamic)(?=\W*\(|\b)</string>
|
||||
<key>name</key>
|
||||
<string>invalid.deprecated</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<!-- Illegal keywords
|
||||
-->
|
||||
<key>match</key>
|
||||
<string></string>
|
||||
<key>name</key>
|
||||
<string>invalid.illegal</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>uuid</key>
|
||||
<string>FF0550E0-3A29-11E3-AA6E-0800200C9B77</string>
|
||||
</dict>
|
||||
</plist>
|
||||
404
extensions/kusto/themes/Kuskus.Dark.tmTheme
Normal file
404
extensions/kusto/themes/Kuskus.Dark.tmTheme
Normal file
@@ -0,0 +1,404 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>[Kuskus] Kusto (Dark)</string>
|
||||
<key>settings</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>background</key>
|
||||
<string>#272822</string>
|
||||
<key>caret</key>
|
||||
<string>#F8F8F0</string>
|
||||
<key>foreground</key>
|
||||
<string>#F8F8F2</string>
|
||||
<key>invisibles</key>
|
||||
<string>#3B3A32</string>
|
||||
<key>lineHighlight</key>
|
||||
<string>#3E3D32</string>
|
||||
<key>selection</key>
|
||||
<string>#49483E</string>
|
||||
<key>findHighlight</key>
|
||||
<string>#FFE792</string>
|
||||
<key>findHighlightForeground</key>
|
||||
<string>#000000</string>
|
||||
<key>selectionBorder</key>
|
||||
<string>#222218</string>
|
||||
<key>activeGuide</key>
|
||||
<string>#9D550FB0</string>
|
||||
|
||||
<key>bracketsForeground</key>
|
||||
<string>#F8F8F2A5</string>
|
||||
<key>bracketsOptions</key>
|
||||
<string>underline</string>
|
||||
|
||||
<key>bracketContentsForeground</key>
|
||||
<string>#F8F8F2A5</string>
|
||||
<key>bracketContentsOptions</key>
|
||||
<string>underline</string>
|
||||
|
||||
<key>tagsOptions</key>
|
||||
<string>stippled_underline</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Comment</string>
|
||||
<key>scope</key>
|
||||
<string>comment</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#75715E</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>String</string>
|
||||
<key>scope</key>
|
||||
<string>string</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#E6DB74</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Number</string>
|
||||
<key>scope</key>
|
||||
<string>constant.numeric</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#AE81FF</string>
|
||||
</dict>
|
||||
</dict>
|
||||
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Built-in constant</string>
|
||||
<key>scope</key>
|
||||
<string>constant.language</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#AE81FF</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>User-defined constant</string>
|
||||
<key>scope</key>
|
||||
<string>constant.character, constant.other</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#AE81FF</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Variable</string>
|
||||
<key>scope</key>
|
||||
<string>variable</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Keyword</string>
|
||||
<key>scope</key>
|
||||
<string>keyword</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#F92672</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Keyword operator words</string>
|
||||
<key>scope</key>
|
||||
<string>keyword.operator.word</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#FD971F</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Storage</string>
|
||||
<key>scope</key>
|
||||
<string>storage</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#F92672</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Storage type</string>
|
||||
<key>scope</key>
|
||||
<string>storage.type</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#66D9EF</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Class name</string>
|
||||
<key>scope</key>
|
||||
<string>entity.name.class</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>underline</string>
|
||||
<key>foreground</key>
|
||||
<string>#A6E22E</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Inherited class</string>
|
||||
<key>scope</key>
|
||||
<string>entity.other.inherited-class</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>italic underline</string>
|
||||
<key>foreground</key>
|
||||
<string>#A6E22E</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Function name</string>
|
||||
<key>scope</key>
|
||||
<string>entity.name.function</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#A6E22E</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Function argument</string>
|
||||
<key>scope</key>
|
||||
<string>variable.parameter</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
<key>foreground</key>
|
||||
<string>#FD971F</string>
|
||||
</dict>
|
||||
<key>name</key>
|
||||
<string>TODO better semantic scope</string>
|
||||
<key>scope</key>
|
||||
<string>variable.language</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#FD971F</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Tag name</string>
|
||||
<key>scope</key>
|
||||
<string>entity.name.tag</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#F92672</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Tag attribute</string>
|
||||
<key>scope</key>
|
||||
<string>entity.other.attribute-name</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#A6E22E</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Library function</string>
|
||||
<key>scope</key>
|
||||
<string>support.function</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#A6E22E</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Library constant</string>
|
||||
<key>scope</key>
|
||||
<string>support.constant</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#66D9EF</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Library class/type</string>
|
||||
<key>scope</key>
|
||||
<string>support.type, support.class</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
<key>foreground</key>
|
||||
<string>#66D9EF</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Library variable</string>
|
||||
<key>scope</key>
|
||||
<string>support.other.variable</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Invalid</string>
|
||||
<key>scope</key>
|
||||
<string>invalid</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>background</key>
|
||||
<string></string>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#F8F8F0</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Invalid deprecated</string>
|
||||
<key>scope</key>
|
||||
<string>invalid.deprecated</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>underline</string>
|
||||
<key>foreground</key>
|
||||
<string>#FF0000</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>JSON String</string>
|
||||
<key>scope</key>
|
||||
<string>meta.structure.dictionary.json string.quoted.double.json</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#CFCFC2</string>
|
||||
</dict>
|
||||
</dict>
|
||||
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>diff.header</string>
|
||||
<key>scope</key>
|
||||
<string>meta.diff, meta.diff.header</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#75715E</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>diff.deleted</string>
|
||||
<key>scope</key>
|
||||
<string>markup.deleted</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#F92672</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>diff.inserted</string>
|
||||
<key>scope</key>
|
||||
<string>markup.inserted</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#A6E22E</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>diff.changed</string>
|
||||
<key>scope</key>
|
||||
<string>markup.changed</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#E6DB74</string>
|
||||
</dict>
|
||||
</dict>
|
||||
|
||||
<dict>
|
||||
<key>scope</key>
|
||||
<string>constant.numeric.line-number.find-in-files - match</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#AE81FFA0</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>scope</key>
|
||||
<string>entity.name.filename.find-in-files</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#E6DB74</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
<key>uuid</key>
|
||||
<string>D8D5E82E-3D5B-46B5-B38E-8C841C21347D</string>
|
||||
</dict>
|
||||
</plist>
|
||||
223
extensions/kusto/themes/Kuskus.KustoExplorer.Dark.tmTheme
Normal file
223
extensions/kusto/themes/Kuskus.KustoExplorer.Dark.tmTheme
Normal file
@@ -0,0 +1,223 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>[Kuskus] Kusto Explorer (Dark)</string>
|
||||
<key>settings</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>background</key>
|
||||
<string>#272822</string>
|
||||
<key>caret</key>
|
||||
<string>#F8F8F0</string>
|
||||
<key>foreground</key>
|
||||
<string>#F8F8F2</string>
|
||||
<key>invisibles</key>
|
||||
<string>#3B3A32</string>
|
||||
<key>lineHighlight</key>
|
||||
<string>#3E3D32</string>
|
||||
<key>selection</key>
|
||||
<string>#49483E</string>
|
||||
<key>findHighlight</key>
|
||||
<string>#FFE792</string>
|
||||
<key>findHighlightForeground</key>
|
||||
<string>#000000</string>
|
||||
<key>selectionBorder</key>
|
||||
<string>#222218</string>
|
||||
<key>activeGuide</key>
|
||||
<string>#9D550FB0</string>
|
||||
|
||||
<key>bracketsForeground</key>
|
||||
<string>#F8F8F2A5</string>
|
||||
<key>bracketsOptions</key>
|
||||
<string>underline</string>
|
||||
|
||||
<key>bracketContentsForeground</key>
|
||||
<string>#F8F8F2A5</string>
|
||||
<key>bracketContentsOptions</key>
|
||||
<string>underline</string>
|
||||
|
||||
<key>tagsOptions</key>
|
||||
<string>stippled_underline</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Comment</string>
|
||||
<key>scope</key>
|
||||
<string>comment</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#60804B</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>String</string>
|
||||
<key>scope</key>
|
||||
<string>string</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#C16E40</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Number</string>
|
||||
<key>scope</key>
|
||||
<string>constant.numeric</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string><!-- NO SPECIAL COLOR --></string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Keyword operators</string>
|
||||
<key>scope</key>
|
||||
<string>keyword.operator.special.kusto</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#44C89E</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Keyword operators</string>
|
||||
<key>scope</key>
|
||||
<string>keyword.operator</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#4E84D4</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Keyword control</string>
|
||||
<key>scope</key>
|
||||
<string>keyword.control</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#4E84D4</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Storage type</string>
|
||||
<key>scope</key>
|
||||
<string>storage.type</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#4E84D4</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<!-- TODO function parameter support in kusto.tmLanguage -->
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Function arguments and parameters</string>
|
||||
<key>scope</key>
|
||||
<string>variable.parameter</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#92CAEA</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Lambda definitions</string>
|
||||
<key>scope</key>
|
||||
<string>entity.function.name.lambda.kusto</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#92CAEA</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Library function</string>
|
||||
<key>scope</key>
|
||||
<string>support.function</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#4E84D4</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Invalid (deprecated, illegal)</string>
|
||||
<key>scope</key>
|
||||
<string>invalid</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>underline</string>
|
||||
<key>foreground</key>
|
||||
<string>#FF0000</string>
|
||||
</dict>
|
||||
</dict>
|
||||
|
||||
<!-- TODO thoughtful diff coloring -->
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>diff.header</string>
|
||||
<key>scope</key>
|
||||
<string>meta.diff, meta.diff.header</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#75715E</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>diff.deleted</string>
|
||||
<key>scope</key>
|
||||
<string>markup.deleted</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#F92672</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>diff.inserted</string>
|
||||
<key>scope</key>
|
||||
<string>markup.inserted</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#A6E22E</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>diff.changed</string>
|
||||
<key>scope</key>
|
||||
<string>markup.changed</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#E6DB74</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
<key>uuid</key>
|
||||
<string>D8D5E82E-3D5B-46B5-B38E-8C841C21347D</string>
|
||||
</dict>
|
||||
</plist>
|
||||
12
extensions/kusto/themes/kuskus-kusto-dark.json
Normal file
12
extensions/kusto/themes/kuskus-kusto-dark.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"tokenColors": "./Kuskus.Dark.tmTheme",
|
||||
"colors": {
|
||||
"editor.background": "#272822",
|
||||
"editorCursor.foreground": "#F8F8F0",
|
||||
"editor.foreground": "#F8F8F2",
|
||||
"editorWhitespace.foreground": "#3B3A32",
|
||||
"editor.lineHighlightBackground": "#3E3D32",
|
||||
"editor.selectionBackground": "#49483E"
|
||||
},
|
||||
"name": "[Kuskus] Kusto (Dark)"
|
||||
}
|
||||
12
extensions/kusto/themes/kuskus-kusto-explorer-dark.json
Normal file
12
extensions/kusto/themes/kuskus-kusto-explorer-dark.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"tokenColors": "./Kuskus.KustoExplorer.Dark.tmTheme",
|
||||
"colors": {
|
||||
"editor.background": "#222224",
|
||||
"editorCursor.foreground": "#F8F8F0",
|
||||
"editor.foreground": "#F8F8F2",
|
||||
"editorWhitespace.foreground": "#3B3A32",
|
||||
"editor.lineHighlightBackground": "#3D4247",
|
||||
"editor.selectionBackground": "#1268AC"
|
||||
},
|
||||
"name": "[Kuskus] Kusto Explorer (Dark)"
|
||||
}
|
||||
12
extensions/kusto/tsconfig.json
Normal file
12
extensions/kusto/tsconfig.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"extends": "../shared.tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./out",
|
||||
"strict": true,
|
||||
"noUnusedParameters": false,
|
||||
"noImplicitAny": false
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
]
|
||||
}
|
||||
677
extensions/kusto/yarn.lock
Normal file
677
extensions/kusto/yarn.lock
Normal file
@@ -0,0 +1,677 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@types/caseless@*":
|
||||
version "0.12.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.2.tgz#f65d3d6389e01eeb458bd54dc8f52b95a9463bc8"
|
||||
integrity sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==
|
||||
|
||||
"@types/kerberos@^1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/kerberos/-/kerberos-1.1.0.tgz#fb1e5bc4f7272d152f67714deb100d5de7cb3e48"
|
||||
integrity sha512-ixpV6PSSMnIVpMNCLQ0gWguC2+pBxc0LeUCv9Ugj54opVSVFXfPNYP6sMa7UHvicYGDXAyHQSAzQC8VYEIgdFQ==
|
||||
|
||||
"@types/node@*":
|
||||
version "12.7.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.2.tgz#c4e63af5e8823ce9cc3f0b34f7b998c2171f0c44"
|
||||
integrity sha512-dyYO+f6ihZEtNPDcWNR1fkoTDf3zAK3lAABDze3mz6POyIercH0lEUawUFXlG8xaQZmm1yEBON/4TsYv/laDYg==
|
||||
|
||||
"@types/request@^2.48.2":
|
||||
version "2.48.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.2.tgz#936374cbe1179d7ed529fc02543deb4597450fed"
|
||||
integrity sha512-gP+PSFXAXMrd5PcD7SqHeUjdGshAI8vKQ3+AvpQr3ht9iQea+59LOKvKITcQI+Lg+1EIkDP6AFSBUJPWG8GDyA==
|
||||
dependencies:
|
||||
"@types/caseless" "*"
|
||||
"@types/node" "*"
|
||||
"@types/tough-cookie" "*"
|
||||
form-data "^2.5.0"
|
||||
|
||||
"@types/through2@^2.0.34":
|
||||
version "2.0.34"
|
||||
resolved "https://registry.yarnpkg.com/@types/through2/-/through2-2.0.34.tgz#9c2a259a238dace2a05a2f8e94b786961bc27ac4"
|
||||
integrity sha512-nhRG8+RuG/L+0fAZBQYaRflXKjTrHOKH8MFTChnf+dNVMxA3wHYYrfj0tztK0W51ABXjGfRCDc0vRkecCOrsow==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/tough-cookie@*":
|
||||
version "2.3.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-2.3.5.tgz#9da44ed75571999b65c37b60c9b2b88db54c585d"
|
||||
integrity sha512-SCcK7mvGi3+ZNz833RRjFIxrn4gI1PPR3NtuIS+6vMkvmsGjosqTJwRt5bAEFLRz+wtJMWv8+uOnZf2hi2QXTg==
|
||||
|
||||
agent-base@4, agent-base@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee"
|
||||
integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==
|
||||
dependencies:
|
||||
es6-promisify "^5.0.0"
|
||||
|
||||
applicationinsights@1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-1.0.6.tgz#bc201810de91cea910dab34e8ad35ecde488edeb"
|
||||
integrity sha512-VQT3kBpJVPw5fCO5n+WUeSx0VHjxFtD7znYbILBlVgOS9/cMDuGFmV2Br3ObzFyZUDGNbEfW36fD1y2/vAiCKw==
|
||||
dependencies:
|
||||
diagnostic-channel "0.2.0"
|
||||
diagnostic-channel-publishers "0.2.1"
|
||||
zone.js "0.7.6"
|
||||
|
||||
asynckit@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
||||
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
|
||||
|
||||
base64-js@^1.0.2:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1"
|
||||
integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==
|
||||
|
||||
bl@^1.0.0:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c"
|
||||
integrity sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==
|
||||
dependencies:
|
||||
readable-stream "^2.3.5"
|
||||
safe-buffer "^5.1.1"
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.11"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
concat-map "0.0.1"
|
||||
|
||||
buffer-alloc-unsafe@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0"
|
||||
integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==
|
||||
|
||||
buffer-alloc@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec"
|
||||
integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==
|
||||
dependencies:
|
||||
buffer-alloc-unsafe "^1.1.0"
|
||||
buffer-fill "^1.0.0"
|
||||
|
||||
buffer-crc32@~0.2.3:
|
||||
version "0.2.13"
|
||||
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
|
||||
integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=
|
||||
|
||||
buffer-fill@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c"
|
||||
integrity sha1-+PeLdniYiO858gXNY39o5wISKyw=
|
||||
|
||||
buffer@^5.2.1:
|
||||
version "5.6.0"
|
||||
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786"
|
||||
integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==
|
||||
dependencies:
|
||||
base64-js "^1.0.2"
|
||||
ieee754 "^1.1.4"
|
||||
|
||||
combined-stream@^1.0.6:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828"
|
||||
integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==
|
||||
dependencies:
|
||||
delayed-stream "~1.0.0"
|
||||
|
||||
commander@^2.8.1:
|
||||
version "2.20.3"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
|
||||
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
|
||||
|
||||
concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||
|
||||
core-util-is@~1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
|
||||
|
||||
"dataprotocol-client@github:Microsoft/sqlops-dataprotocolclient#1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://codeload.github.com/Microsoft/sqlops-dataprotocolclient/tar.gz/61a6e4dd4662a225259b6ba8a7eca215fab0cfdc"
|
||||
dependencies:
|
||||
vscode-languageclient "5.2.1"
|
||||
|
||||
debug@3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
|
||||
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@^3.1.0:
|
||||
version "3.2.6"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
|
||||
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1"
|
||||
integrity sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==
|
||||
dependencies:
|
||||
file-type "^5.2.0"
|
||||
is-stream "^1.1.0"
|
||||
tar-stream "^1.5.2"
|
||||
|
||||
decompress-tarbz2@^4.0.0:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz#3082a5b880ea4043816349f378b56c516be1a39b"
|
||||
integrity sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==
|
||||
dependencies:
|
||||
decompress-tar "^4.1.0"
|
||||
file-type "^6.1.0"
|
||||
is-stream "^1.1.0"
|
||||
seek-bzip "^1.0.5"
|
||||
unbzip2-stream "^1.0.9"
|
||||
|
||||
decompress-targz@^4.0.0:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/decompress-targz/-/decompress-targz-4.1.1.tgz#c09bc35c4d11f3de09f2d2da53e9de23e7ce1eee"
|
||||
integrity sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==
|
||||
dependencies:
|
||||
decompress-tar "^4.1.1"
|
||||
file-type "^5.2.0"
|
||||
is-stream "^1.1.0"
|
||||
|
||||
decompress-unzip@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/decompress-unzip/-/decompress-unzip-4.0.1.tgz#deaaccdfd14aeaf85578f733ae8210f9b4848f69"
|
||||
integrity sha1-3qrM39FK6vhVePczroIQ+bSEj2k=
|
||||
dependencies:
|
||||
file-type "^3.8.0"
|
||||
get-stream "^2.2.0"
|
||||
pify "^2.3.0"
|
||||
yauzl "^2.4.2"
|
||||
|
||||
decompress@^4.2.0:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/decompress/-/decompress-4.2.1.tgz#007f55cc6a62c055afa37c07eb6a4ee1b773f118"
|
||||
integrity sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==
|
||||
dependencies:
|
||||
decompress-tar "^4.0.0"
|
||||
decompress-tarbz2 "^4.0.0"
|
||||
decompress-targz "^4.0.0"
|
||||
decompress-unzip "^4.0.1"
|
||||
graceful-fs "^4.1.10"
|
||||
make-dir "^1.0.0"
|
||||
pify "^2.3.0"
|
||||
strip-dirs "^2.0.0"
|
||||
|
||||
delayed-stream@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
||||
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
|
||||
|
||||
diagnostic-channel-publishers@0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz#8e2d607a8b6d79fe880b548bc58cc6beb288c4f3"
|
||||
integrity sha1-ji1geottef6IC1SLxYzGvrKIxPM=
|
||||
|
||||
diagnostic-channel@0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz#cc99af9612c23fb1fff13612c72f2cbfaa8d5a17"
|
||||
integrity sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=
|
||||
dependencies:
|
||||
semver "^5.3.0"
|
||||
|
||||
end-of-stream@^1.0.0:
|
||||
version "1.4.4"
|
||||
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
|
||||
integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
|
||||
dependencies:
|
||||
once "^1.4.0"
|
||||
|
||||
es6-promise@^4.0.3:
|
||||
version "4.2.8"
|
||||
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
|
||||
integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
|
||||
|
||||
es6-promisify@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203"
|
||||
integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=
|
||||
dependencies:
|
||||
es6-promise "^4.0.3"
|
||||
|
||||
escape-string-regexp@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
|
||||
|
||||
eventemitter2@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-5.0.1.tgz#6197a095d5fb6b57e8942f6fd7eaad63a09c9452"
|
||||
integrity sha1-YZegldX7a1folC9v1+qtY6CclFI=
|
||||
|
||||
fd-slicer@~1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e"
|
||||
integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=
|
||||
dependencies:
|
||||
pend "~1.2.0"
|
||||
|
||||
figures@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962"
|
||||
integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=
|
||||
dependencies:
|
||||
escape-string-regexp "^1.0.5"
|
||||
|
||||
file-type@^3.8.0:
|
||||
version "3.9.0"
|
||||
resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9"
|
||||
integrity sha1-JXoHg4TR24CHvESdEH1SpSZyuek=
|
||||
|
||||
file-type@^5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/file-type/-/file-type-5.2.0.tgz#2ddbea7c73ffe36368dfae49dc338c058c2b8ad6"
|
||||
integrity sha1-LdvqfHP/42No365J3DOMBYwritY=
|
||||
|
||||
file-type@^6.1.0:
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919"
|
||||
integrity sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==
|
||||
|
||||
find-remove@1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/find-remove/-/find-remove-1.2.1.tgz#afd93400d23890e018ea197591e9d850d3d049a2"
|
||||
integrity sha512-zcspBi9mWAyM9YTcVJLkI/x6rbjSDqHijjPa0vTwEmVZnYSmvYMtixDkUnSnuv2xAAkc9fblpkCg91paBIJaLw==
|
||||
dependencies:
|
||||
fmerge "1.2.0"
|
||||
rimraf "2.6.2"
|
||||
|
||||
fmerge@1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/fmerge/-/fmerge-1.2.0.tgz#36e99d2ae255e3ee1af666b4df780553671cf692"
|
||||
integrity sha1-NumdKuJV4+4a9ma033gFU2cc9pI=
|
||||
|
||||
form-data@^2.5.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.0.tgz#094ec359dc4b55e7d62e0db4acd76e89fe874d37"
|
||||
integrity sha512-WXieX3G/8side6VIqx44ablyULoGruSde5PNTxoUyo5CeyAMX6nVWUd0rgist/EuX655cjhUhTo1Fo3tRYqbcA==
|
||||
dependencies:
|
||||
asynckit "^0.4.0"
|
||||
combined-stream "^1.0.6"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
fs-constants@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
|
||||
integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
|
||||
|
||||
fs.realpath@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
|
||||
|
||||
get-stream@^2.2.0:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de"
|
||||
integrity sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=
|
||||
dependencies:
|
||||
object-assign "^4.0.1"
|
||||
pinkie-promise "^2.0.0"
|
||||
|
||||
glob@^7.0.5:
|
||||
version "7.1.3"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1"
|
||||
integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==
|
||||
dependencies:
|
||||
fs.realpath "^1.0.0"
|
||||
inflight "^1.0.4"
|
||||
inherits "2"
|
||||
minimatch "^3.0.4"
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
graceful-fs@^4.1.10:
|
||||
version "4.2.4"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
|
||||
integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==
|
||||
|
||||
http-proxy-agent@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405"
|
||||
integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==
|
||||
dependencies:
|
||||
agent-base "4"
|
||||
debug "3.1.0"
|
||||
|
||||
https-proxy-agent@^2.2.1:
|
||||
version "2.2.4"
|
||||
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b"
|
||||
integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==
|
||||
dependencies:
|
||||
agent-base "^4.3.0"
|
||||
debug "^3.1.0"
|
||||
|
||||
ieee754@^1.1.4:
|
||||
version "1.1.13"
|
||||
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84"
|
||||
integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==
|
||||
|
||||
inflight@^1.0.4:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
||||
integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
|
||||
dependencies:
|
||||
once "^1.3.0"
|
||||
wrappy "1"
|
||||
|
||||
inherits@2:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
||||
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
|
||||
|
||||
inherits@~2.0.3:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
is-natural-number@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8"
|
||||
integrity sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=
|
||||
|
||||
is-stream@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
|
||||
|
||||
isarray@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
|
||||
integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
|
||||
|
||||
make-dir@^1.0.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c"
|
||||
integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==
|
||||
dependencies:
|
||||
pify "^3.0.0"
|
||||
|
||||
mime-db@~1.38.0:
|
||||
version "1.38.0"
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.38.0.tgz#1a2aab16da9eb167b49c6e4df2d9c68d63d8e2ad"
|
||||
integrity sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==
|
||||
|
||||
mime-types@^2.1.12:
|
||||
version "2.1.22"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.22.tgz#fe6b355a190926ab7698c9a0556a11199b2199bd"
|
||||
integrity sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==
|
||||
dependencies:
|
||||
mime-db "~1.38.0"
|
||||
|
||||
minimatch@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
|
||||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
minimist@^1.2.5:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
||||
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
||||
|
||||
mkdirp@^0.5.1:
|
||||
version "0.5.5"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
|
||||
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
|
||||
dependencies:
|
||||
minimist "^1.2.5"
|
||||
|
||||
ms@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
|
||||
|
||||
ms@^2.1.1:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||
|
||||
object-assign@^4.0.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
|
||||
|
||||
once@^1.3.0, once@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||
integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
|
||||
dependencies:
|
||||
wrappy "1"
|
||||
|
||||
os-tmpdir@~1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
|
||||
integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
|
||||
|
||||
path-is-absolute@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
|
||||
|
||||
pend@~1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
|
||||
integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA=
|
||||
|
||||
pify@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
|
||||
integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw=
|
||||
|
||||
pify@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176"
|
||||
integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=
|
||||
|
||||
pinkie-promise@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
|
||||
integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o=
|
||||
dependencies:
|
||||
pinkie "^2.0.0"
|
||||
|
||||
pinkie@^2.0.0:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
|
||||
integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA=
|
||||
|
||||
process-nextick-args@~2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
|
||||
integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
|
||||
|
||||
readable-stream@^2.3.0, readable-stream@^2.3.5:
|
||||
version "2.3.7"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
|
||||
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
|
||||
dependencies:
|
||||
core-util-is "~1.0.0"
|
||||
inherits "~2.0.3"
|
||||
isarray "~1.0.0"
|
||||
process-nextick-args "~2.0.0"
|
||||
safe-buffer "~5.1.1"
|
||||
string_decoder "~1.1.1"
|
||||
util-deprecate "~1.0.1"
|
||||
|
||||
rimraf@2.6.2:
|
||||
version "2.6.2"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
|
||||
integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==
|
||||
dependencies:
|
||||
glob "^7.0.5"
|
||||
|
||||
safe-buffer@^5.1.1:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
||||
|
||||
safe-buffer@~5.1.0, safe-buffer@~5.1.1:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
|
||||
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
|
||||
|
||||
seek-bzip@^1.0.5:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.6.tgz#35c4171f55a680916b52a07859ecf3b5857f21c4"
|
||||
integrity sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==
|
||||
dependencies:
|
||||
commander "^2.8.1"
|
||||
|
||||
semver@^5.3.0:
|
||||
version "5.6.0"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004"
|
||||
integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==
|
||||
|
||||
semver@^5.5.0:
|
||||
version "5.7.0"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b"
|
||||
integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==
|
||||
|
||||
"service-downloader@github:anthonydresser/service-downloader#0.1.6":
|
||||
version "0.1.6"
|
||||
resolved "https://codeload.github.com/anthonydresser/service-downloader/tar.gz/fd4114b145ee2b4f1f7950c23f10f4b1b28a2bfc"
|
||||
dependencies:
|
||||
decompress "^4.2.0"
|
||||
eventemitter2 "^5.0.1"
|
||||
http-proxy-agent "^2.1.0"
|
||||
https-proxy-agent "^2.2.1"
|
||||
mkdirp "^0.5.1"
|
||||
tmp "^0.0.33"
|
||||
|
||||
string_decoder@~1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
|
||||
integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
|
||||
dependencies:
|
||||
safe-buffer "~5.1.0"
|
||||
|
||||
strip-dirs@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-dirs/-/strip-dirs-2.1.0.tgz#4987736264fc344cf20f6c34aca9d13d1d4ed6c5"
|
||||
integrity sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==
|
||||
dependencies:
|
||||
is-natural-number "^4.0.1"
|
||||
|
||||
tar-stream@^1.5.2:
|
||||
version "1.6.2"
|
||||
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555"
|
||||
integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==
|
||||
dependencies:
|
||||
bl "^1.0.0"
|
||||
buffer-alloc "^1.2.0"
|
||||
end-of-stream "^1.0.0"
|
||||
fs-constants "^1.0.0"
|
||||
readable-stream "^2.3.0"
|
||||
to-buffer "^1.1.1"
|
||||
xtend "^4.0.0"
|
||||
|
||||
through@^2.3.8:
|
||||
version "2.3.8"
|
||||
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
|
||||
|
||||
tmp@^0.0.33:
|
||||
version "0.0.33"
|
||||
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
|
||||
integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==
|
||||
dependencies:
|
||||
os-tmpdir "~1.0.2"
|
||||
|
||||
to-buffer@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80"
|
||||
integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==
|
||||
|
||||
unbzip2-stream@^1.0.9:
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7"
|
||||
integrity sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==
|
||||
dependencies:
|
||||
buffer "^5.2.1"
|
||||
through "^2.3.8"
|
||||
|
||||
util-deprecate@~1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
|
||||
|
||||
vscode-extension-telemetry@0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.0.tgz#3cdcb61d03829966bd04b5f11471a1e40d6abaad"
|
||||
integrity sha512-WVCnP+uLxlqB6UD98yQNV47mR5Rf79LFxpuZhSPhEf0Sb4tPZed3a63n003/dchhOwyCTCBuNN4n8XKJkLEI1Q==
|
||||
dependencies:
|
||||
applicationinsights "1.0.6"
|
||||
|
||||
vscode-jsonrpc@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz#a7bf74ef3254d0a0c272fab15c82128e378b3be9"
|
||||
integrity sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==
|
||||
|
||||
vscode-languageclient@5.2.1:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz#7cfc83a294c409f58cfa2b910a8cfeaad0397193"
|
||||
integrity sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==
|
||||
dependencies:
|
||||
semver "^5.5.0"
|
||||
vscode-languageserver-protocol "3.14.1"
|
||||
|
||||
vscode-languageserver-protocol@3.14.1:
|
||||
version "3.14.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz#b8aab6afae2849c84a8983d39a1cf742417afe2f"
|
||||
integrity sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==
|
||||
dependencies:
|
||||
vscode-jsonrpc "^4.0.0"
|
||||
vscode-languageserver-types "3.14.0"
|
||||
|
||||
vscode-languageserver-types@3.14.0:
|
||||
version "3.14.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz#d3b5952246d30e5241592b6dde8280e03942e743"
|
||||
integrity sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==
|
||||
|
||||
vscode-nls@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.0.0.tgz#4001c8a6caba5cedb23a9c5ce1090395c0e44002"
|
||||
integrity sha512-qCfdzcH+0LgQnBpZA53bA32kzp9rpq/f66Som577ObeuDlFIrtbEJ+A/+CCxjIh4G8dpJYNCKIsxpRAHIfsbNw==
|
||||
|
||||
wrappy@1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
||||
|
||||
xtend@^4.0.0:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
|
||||
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
|
||||
|
||||
yauzl@^2.4.2:
|
||||
version "2.10.0"
|
||||
resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"
|
||||
integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=
|
||||
dependencies:
|
||||
buffer-crc32 "~0.2.3"
|
||||
fd-slicer "~1.1.0"
|
||||
|
||||
zone.js@0.7.6:
|
||||
version "0.7.6"
|
||||
resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.7.6.tgz#fbbc39d3e0261d0986f1ba06306eb3aeb0d22009"
|
||||
integrity sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=
|
||||
14
src/sql/azdata.d.ts
vendored
14
src/sql/azdata.d.ts
vendored
@@ -284,9 +284,9 @@ declare module 'azdata' {
|
||||
// Object Explorer interfaces -----------------------------------------------------------------------
|
||||
export interface ObjectExplorerSession {
|
||||
success: boolean;
|
||||
sessionId: string;
|
||||
sessionId?: string;
|
||||
rootNode: NodeInfo;
|
||||
errorMessage: string;
|
||||
errorMessage?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -296,12 +296,12 @@ declare module 'azdata' {
|
||||
export interface NodeInfo {
|
||||
nodePath: string;
|
||||
nodeType: string;
|
||||
nodeSubType: string;
|
||||
nodeSubType?: string;
|
||||
nodeStatus?: string;
|
||||
label: string;
|
||||
isLeaf: boolean;
|
||||
metadata?: ObjectMetadata;
|
||||
errorMessage: string;
|
||||
errorMessage?: string;
|
||||
/**
|
||||
* Optional iconType for the object in the tree. Currently this only supports
|
||||
* an icon name or SqlThemeIcon name, rather than a path to an icon.
|
||||
@@ -1228,7 +1228,7 @@ declare module 'azdata' {
|
||||
}
|
||||
|
||||
export interface ObjectExplorerExpandInfo {
|
||||
sessionId: string;
|
||||
sessionId?: string;
|
||||
nodePath: string;
|
||||
nodes: NodeInfo[];
|
||||
errorMessage?: string;
|
||||
@@ -1236,7 +1236,7 @@ declare module 'azdata' {
|
||||
|
||||
export interface ExpandNodeInfo {
|
||||
sessionId: string;
|
||||
nodePath: string;
|
||||
nodePath: string | undefined;
|
||||
}
|
||||
|
||||
export interface FindNodesInfo {
|
||||
@@ -1299,7 +1299,7 @@ declare module 'azdata' {
|
||||
}
|
||||
|
||||
export interface IconProvider extends DataProvider {
|
||||
getConnectionIconId(connection: IConnectionProfile, serverInfo: ServerInfo): Thenable<string>;
|
||||
getConnectionIconId(connection: IConnectionProfile, serverInfo: ServerInfo): Thenable<string | undefined>;
|
||||
}
|
||||
|
||||
// Admin Services interfaces -----------------------------------------------------------------------
|
||||
|
||||
@@ -219,7 +219,7 @@ export class ObjectExplorerService implements IObjectExplorerService {
|
||||
}
|
||||
await this.closeSession(connection.providerName, session);
|
||||
delete this._activeObjectExplorerNodes[connectionUri];
|
||||
delete this._sessions[session.sessionId];
|
||||
delete this._sessions[session.sessionId!];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,10 +232,10 @@ export class ObjectExplorerService implements IObjectExplorerService {
|
||||
this.logService.error(expandResponse.errorMessage);
|
||||
}
|
||||
|
||||
let sessionStatus = this._sessions[expandResponse.sessionId];
|
||||
let sessionStatus = this._sessions[expandResponse.sessionId!];
|
||||
let foundSession = false;
|
||||
if (sessionStatus) {
|
||||
let nodeStatus = this._sessions[expandResponse.sessionId].nodes[expandResponse.nodePath];
|
||||
let nodeStatus = this._sessions[expandResponse.sessionId!].nodes[expandResponse.nodePath];
|
||||
foundSession = !!nodeStatus;
|
||||
if (foundSession && nodeStatus.expandEmitter) {
|
||||
nodeStatus.expandEmitter.fire(expandResponse);
|
||||
@@ -261,22 +261,22 @@ export class ObjectExplorerService implements IObjectExplorerService {
|
||||
private async handleSessionCreated(session: azdata.ObjectExplorerSession): Promise<void> {
|
||||
let connection: ConnectionProfile | undefined = undefined;
|
||||
let errorMessage: string | undefined = undefined;
|
||||
if (this._sessions[session.sessionId]) {
|
||||
connection = this._sessions[session.sessionId].connection;
|
||||
if (this._sessions[session.sessionId!]) {
|
||||
connection = this._sessions[session.sessionId!].connection;
|
||||
|
||||
try {
|
||||
if (session.success && session.rootNode) {
|
||||
let server = this.toTreeNode(session.rootNode, undefined);
|
||||
server.connection = connection;
|
||||
server.session = session;
|
||||
this._activeObjectExplorerNodes[connection.id] = server;
|
||||
this._activeObjectExplorerNodes[connection!.id] = server;
|
||||
}
|
||||
else {
|
||||
errorMessage = session && session.errorMessage ? session.errorMessage : errSessionCreateFailed;
|
||||
this.logService.error(errorMessage);
|
||||
}
|
||||
// Send on session created about the session to all node providers so they can prepare for node expansion
|
||||
let nodeProviders = this._nodeProviders[connection.providerName];
|
||||
let nodeProviders = this._nodeProviders[connection!.providerName];
|
||||
if (nodeProviders) {
|
||||
const promises = nodeProviders.map(p => p.handleSessionOpen(session));
|
||||
await Promise.all(promises);
|
||||
@@ -284,7 +284,7 @@ export class ObjectExplorerService implements IObjectExplorerService {
|
||||
} catch (error) {
|
||||
this.logService.warn(`cannot handle the session ${session.sessionId} in all nodeProviders`);
|
||||
} finally {
|
||||
this.sendUpdateNodeEvent(connection, errorMessage);
|
||||
this.sendUpdateNodeEvent(connection!, errorMessage);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -296,8 +296,8 @@ export class ObjectExplorerService implements IObjectExplorerService {
|
||||
* Gets called when session is disconnected
|
||||
*/
|
||||
public onSessionDisconnected(handle: number, session: azdata.ObjectExplorerSession): void {
|
||||
if (this._sessions[session.sessionId]) {
|
||||
let connection: ConnectionProfile = this._sessions[session.sessionId].connection;
|
||||
if (this._sessions[session.sessionId!]) {
|
||||
let connection: ConnectionProfile = this._sessions[session.sessionId!].connection;
|
||||
if (connection && this._connectionManagementService.isProfileConnected(connection)) {
|
||||
let uri: string = Utils.generateUri(connection);
|
||||
if (this._serverTreeView?.isObjectExplorerConnectionUri(uri)) {
|
||||
@@ -383,10 +383,10 @@ export class ObjectExplorerService implements IObjectExplorerService {
|
||||
refresh: boolean = false): Promise<azdata.ObjectExplorerExpandInfo> {
|
||||
let self = this;
|
||||
return new Promise<azdata.ObjectExplorerExpandInfo>((resolve, reject) => {
|
||||
if (session.sessionId in self._sessions && self._sessions[session.sessionId]) {
|
||||
if (session.sessionId! in self._sessions && self._sessions[session.sessionId!]) {
|
||||
let newRequest = false;
|
||||
if (!self._sessions[session.sessionId].nodes[nodePath]) {
|
||||
self._sessions[session.sessionId].nodes[nodePath] = {
|
||||
if (!self._sessions[session.sessionId!].nodes[nodePath]) {
|
||||
self._sessions[session.sessionId!].nodes[nodePath] = {
|
||||
expandEmitter: new Emitter<NodeExpandInfoWithProviderId>()
|
||||
};
|
||||
newRequest = true;
|
||||
@@ -402,7 +402,7 @@ export class ObjectExplorerService implements IObjectExplorerService {
|
||||
allProviders.push(...nodeProviders);
|
||||
}
|
||||
|
||||
self._sessions[session.sessionId].nodes[nodePath].expandEmitter.event((expandResult) => {
|
||||
self._sessions[session.sessionId!].nodes[nodePath].expandEmitter.event((expandResult: NodeExpandInfoWithProviderId) => {
|
||||
if (expandResult && expandResult.providerId) {
|
||||
resultMap.set(expandResult.providerId, expandResult);
|
||||
} else {
|
||||
@@ -415,14 +415,14 @@ export class ObjectExplorerService implements IObjectExplorerService {
|
||||
|
||||
// Have to delete it after get all reponses otherwise couldn't find session for not the first response
|
||||
if (newRequest) {
|
||||
delete self._sessions[session.sessionId].nodes[nodePath];
|
||||
delete self._sessions[session.sessionId!].nodes[nodePath];
|
||||
}
|
||||
}
|
||||
});
|
||||
if (newRequest) {
|
||||
allProviders.forEach(provider => {
|
||||
self.callExpandOrRefreshFromProvider(provider, {
|
||||
sessionId: session.sessionId,
|
||||
sessionId: session.sessionId!,
|
||||
nodePath: nodePath
|
||||
}, refresh).then(isExpanding => {
|
||||
if (!isExpanding) {
|
||||
@@ -506,9 +506,12 @@ export class ObjectExplorerService implements IObjectExplorerService {
|
||||
|
||||
public closeSession(providerId: string, session: azdata.ObjectExplorerSession): Promise<azdata.ObjectExplorerCloseSessionResponse | undefined> {
|
||||
// Complete any requests that are still open for the session
|
||||
let sessionStatus = this._sessions[session.sessionId];
|
||||
let sessionStatus = this._sessions[session.sessionId!];
|
||||
if (sessionStatus && sessionStatus.nodes) {
|
||||
entries(sessionStatus.nodes).forEach(([nodePath, nodeStatus]: [string, NodeStatus]) => {
|
||||
entries(sessionStatus.nodes).forEach((entry) => {
|
||||
const nodePath: string = entry[0];
|
||||
const nodeStatus: NodeStatus = entry[1] as NodeStatus;
|
||||
|
||||
if (nodeStatus.expandEmitter) {
|
||||
nodeStatus.expandEmitter.fire({
|
||||
sessionId: session.sessionId,
|
||||
@@ -606,7 +609,7 @@ export class ObjectExplorerService implements IObjectExplorerService {
|
||||
}
|
||||
|
||||
let node = new TreeNode(nodeInfo.nodeType, nodeInfo.label, isLeaf, nodeInfo.nodePath,
|
||||
nodeInfo.nodeSubType, nodeInfo.nodeStatus, parent, nodeInfo.metadata, nodeInfo.iconType, {
|
||||
nodeInfo.nodeSubType!, nodeInfo.nodeStatus, parent, nodeInfo.metadata, nodeInfo.iconType, {
|
||||
getChildren: (treeNode?: TreeNode) => this.getChildren(treeNode),
|
||||
isExpanded: treeNode => this.isExpanded(treeNode),
|
||||
setNodeExpandedState: async (treeNode, expandedState) => await this.setNodeExpandedState(treeNode, expandedState),
|
||||
|
||||
Reference in New Issue
Block a user