diff --git a/extensions/mssql/src/azureBlob/azureBlobService.ts b/extensions/mssql/src/azureBlob/azureBlobService.ts index 2a605d436e..9f50a8793b 100644 --- a/extensions/mssql/src/azureBlob/azureBlobService.ts +++ b/extensions/mssql/src/azureBlob/azureBlobService.ts @@ -19,7 +19,7 @@ export class AzureBlobService implements mssql.IAzureBlobService { undefined, e => { this.client.logFailedRequest(contracts.CreateSasRequest.type, e); - return Promise.resolve(undefined); + return Promise.reject(e); } ); } diff --git a/extensions/mssql/src/dashboard/bookExtensions.ts b/extensions/mssql/src/dashboard/bookExtensions.ts index 4c843eed9f..d5bb905112 100644 --- a/extensions/mssql/src/dashboard/bookExtensions.ts +++ b/extensions/mssql/src/dashboard/bookExtensions.ts @@ -96,7 +96,7 @@ class AzdataExtensionBookContributionProvider extends Disposable implements Book vscode.extensions.onDidChange(async () => { const currentContributions = this.getCurrentContributions(); const existingContributions = this._contributions || undefined; - if (!arrays.equals(existingContributions, currentContributions, BookContributions.equal)) { + if (!existingContributions || !arrays.equals(existingContributions, currentContributions, BookContributions.equal)) { await this.unregisterCommands(); this._contributions = currentContributions; await this.registerCommands(); diff --git a/extensions/mssql/src/sqlAssessment/sqlAssessmentService.ts b/extensions/mssql/src/sqlAssessment/sqlAssessmentService.ts index 6a91807f5e..a6c19985f8 100644 --- a/extensions/mssql/src/sqlAssessment/sqlAssessmentService.ts +++ b/extensions/mssql/src/sqlAssessment/sqlAssessmentService.ts @@ -30,38 +30,35 @@ export class SqlAssessmentService implements mssql.ISqlAssessmentService { private constructor(context: AppContext, protected readonly client: SqlOpsDataClient) { context.registerService(constants.SqlAssessmentService, this); } - async assessmentInvoke(ownerUri: string, targetType: azdata.sqlAssessment.SqlAssessmentTargetType): Promise { + async assessmentInvoke(ownerUri: string, targetType: azdata.sqlAssessment.SqlAssessmentTargetType): Promise { let params: contracts.SqlAssessmentParams = { ownerUri: ownerUri, targetType: targetType }; try { - return this.client.sendRequest(contracts.SqlAssessmentInvokeRequest.type, params); + return await this.client.sendRequest(contracts.SqlAssessmentInvokeRequest.type, params); } catch (e) { this.client.logFailedRequest(contracts.SqlAssessmentInvokeRequest.type, e); + throw e; } - - return undefined; } - async getAssessmentItems(ownerUri: string, targetType: azdata.sqlAssessment.SqlAssessmentTargetType): Promise { + async getAssessmentItems(ownerUri: string, targetType: azdata.sqlAssessment.SqlAssessmentTargetType): Promise { let params: contracts.SqlAssessmentParams = { ownerUri: ownerUri, targetType: targetType }; try { - return this.client.sendRequest(contracts.GetSqlAssessmentItemsRequest.type, params); + return await this.client.sendRequest(contracts.GetSqlAssessmentItemsRequest.type, params); } catch (e) { this.client.logFailedRequest(contracts.GetSqlAssessmentItemsRequest.type, e); + throw e; } - - return undefined; } - async generateAssessmentScript(items: azdata.SqlAssessmentResultItem[], targetServerName: string, targetDatabaseName: string, taskExecutionMode: azdata.TaskExecutionMode): Promise { + async generateAssessmentScript(items: azdata.SqlAssessmentResultItem[], targetServerName: string, targetDatabaseName: string, taskExecutionMode: azdata.TaskExecutionMode): Promise { let params: contracts.GenerateSqlAssessmentScriptParams = { items: items, targetServerName: targetServerName, targetDatabaseName: targetDatabaseName, taskExecutionMode: taskExecutionMode }; try { - return this.client.sendRequest(contracts.GenerateSqlAssessmentScriptRequest.type, params); + return await this.client.sendRequest(contracts.GenerateSqlAssessmentScriptRequest.type, params); } catch (e) { this.client.logFailedRequest(contracts.GenerateSqlAssessmentScriptRequest.type, e); + throw e; } - - return undefined; } } diff --git a/extensions/mssql/src/sqlNotebook/sqlNotebookController.ts b/extensions/mssql/src/sqlNotebook/sqlNotebookController.ts index 0282381f48..b6b9af7e6f 100644 --- a/extensions/mssql/src/sqlNotebook/sqlNotebookController.ts +++ b/extensions/mssql/src/sqlNotebook/sqlNotebookController.ts @@ -32,8 +32,8 @@ export class SqlNotebookController implements vscode.Disposable { private readonly _connProvider: azdata.ConnectionProvider; private readonly _connectionLabelItem: vscode.StatusBarItem; - private _queryCompleteHandler: QueryCompletionHandler; - private _queryMessageHandler: QueryMessageHandler; + private _queryCompleteHandler: QueryCompletionHandler | undefined; + private _queryMessageHandler: QueryMessageHandler | undefined; private _activeCellUri: string; constructor() { @@ -84,7 +84,7 @@ export class SqlNotebookController implements vscode.Disposable { } } - private async handleActiveEditorChanged(editor: vscode.TextEditor): Promise { + private async handleActiveEditorChanged(editor: vscode.TextEditor | undefined): Promise { let notebook = editor?.document.notebook; if (!notebook) { // Hide status bar item if the current editor isn't a notebook @@ -133,19 +133,19 @@ export class SqlNotebookController implements vscode.Disposable { private updateCellConnection(notebookUri: vscode.Uri, connection: azdata.connection.Connection): void { let docUri = vscode.window.activeTextEditor?.document.uri; - if (docUri?.scheme === this._cellUriScheme && docUri?.path === notebookUri.path) { + if (docUri && docUri.scheme === this._cellUriScheme && docUri.path === notebookUri.path) { if (this._activeCellUri) { this._connProvider.disconnect(this._activeCellUri).then(() => undefined, error => console.log(error)); } this._activeCellUri = docUri.toString(); // Delay connecting in case user is clicking between cells a lot setTimeout(() => { - if (this._activeCellUri === docUri.toString()) { + if (this._activeCellUri === docUri!.toString()) { let profile = this.getConnectionProfile(connection); - this._connProvider.connect(docUri.toString(), profile).then( + this._connProvider.connect(docUri!.toString(), profile).then( connected => { if (!connected) { - console.log(`Failed to update cell connection for cell: ${docUri.toString()}`); + console.log(`Failed to update cell connection for cell: ${docUri!.toString()}`); } }, error => { @@ -157,7 +157,7 @@ export class SqlNotebookController implements vscode.Disposable { } private async changeConnection(notebook?: vscode.NotebookDocument): Promise { - let connection: azdata.connection.Connection; + let connection: azdata.connection.Connection | undefined; let notebookUri = notebook?.uri ?? vscode.window.activeTextEditor?.document.notebook?.uri; if (notebookUri) { connection = await azdata.connection.openConnectionDialog(['MSSQL']); @@ -207,7 +207,7 @@ export class SqlNotebookController implements vscode.Disposable { return; } - let cancelHandler: vscode.Disposable; + let cancelHandler: vscode.Disposable | undefined; try { const ownerUri = await azdata.connection.getUriForConnection(connection.connectionId); await this._queryProvider.runQueryString(ownerUri, cell.document.getText()); @@ -221,7 +221,7 @@ export class SqlNotebookController implements vscode.Disposable { break; } - for (let resultSummary of batchSummary.resultSetSummaries) { + for (let resultSummary of batchSummary.resultSetSummaries || []) { if (execution.token.isCancellationRequested) { break; } @@ -302,9 +302,7 @@ export class SqlNotebookController implements vscode.Disposable { ]); execution.end(false, Date.now()); } finally { - if (cancelHandler) { - cancelHandler.dispose(); - } + cancelHandler?.dispose(); this._queryCompleteHandler = undefined; this._queryMessageHandler = undefined; } diff --git a/extensions/mssql/src/sqlToolsServer.ts b/extensions/mssql/src/sqlToolsServer.ts index 898dcd407b..bd8485442d 100644 --- a/extensions/mssql/src/sqlToolsServer.ts +++ b/extensions/mssql/src/sqlToolsServer.ts @@ -51,7 +51,7 @@ export class SqlToolsServer { private client: SqlOpsDataClient; private config: IConfig; private disposables = new Array<{ dispose: () => void }>(); - public installDirectory: string | undefined = undefined; + public installDirectory: string; public async start(context: AppContext): Promise { try { @@ -134,7 +134,7 @@ export class SqlToolsServer { const rawConfig = await fs.readFile(path.join(configDir, 'config.json')); this.config = JSON.parse(rawConfig.toString()); this.config.installDirectory = path.join(configDir, this.config.installDirectory); - this.config.proxy = vscode.workspace.getConfiguration('http').get('proxy'); + this.config.proxy = vscode.workspace.getConfiguration('http').get('proxy', ''); this.config.strictSSL = vscode.workspace.getConfiguration('http').get('proxyStrictSSL', true); return getOrDownloadServer(this.config, handleServerProviderEvent); } diff --git a/extensions/mssql/src/utils.ts b/extensions/mssql/src/utils.ts index 3f5fcd9861..e4837b3132 100644 --- a/extensions/mssql/src/utils.ts +++ b/extensions/mssql/src/utils.ts @@ -6,7 +6,6 @@ import * as azdata from 'azdata'; import * as vscode from 'vscode'; import * as path from 'path'; -import * as crypto from 'crypto'; import * as os from 'os'; import * as findRemoveSync from 'find-remove'; import { promises as fs } from 'fs'; @@ -36,7 +35,7 @@ export const isLinux = os.platform() === 'linux'; export function getAppDataPath() { let platform = process.platform; switch (platform) { - case 'win32': return process.env['APPDATA'] || path.join(process.env['USERPROFILE'], 'AppData', 'Roaming'); + case 'win32': return process.env['APPDATA'] || path.join(process.env['USERPROFILE'] || '', 'AppData', 'Roaming'); case 'darwin': return path.join(os.homedir(), 'Library', 'Application Support'); case 'linux': return process.env['XDG_CONFIG_HOME'] || path.join(os.homedir(), '.config'); default: throw new Error('Platform not supported'); @@ -79,7 +78,7 @@ export function getAzureCoreExtConfiguration(config: string = azureExtensionConf return vscode.workspace.getConfiguration(config); } -export function getConfigLogFilesRemovalLimit(): number { +export function getConfigLogFilesRemovalLimit(): number | undefined { let config = getConfiguration(); if (config) { return Number((config[configLogFilesRemovalLimit]).toFixed(0)); @@ -88,7 +87,7 @@ export function getConfigLogFilesRemovalLimit(): number { } } -export function getConfigLogRetentionSeconds(): number { +export function getConfigLogRetentionSeconds(): number | undefined { let config = getConfiguration(); if (config) { return Number((config[configLogRetentionMinutes] * 60).toFixed(0)); @@ -131,7 +130,7 @@ export function getConfigPiiLogging(): boolean { export function getConfigPreloadDatabaseModel(): boolean { let config = getConfiguration(); if (config) { - return config.get(tableDesignerPreloadConfig); + return config.get(tableDesignerPreloadConfig, false); } else { return false; } @@ -150,15 +149,13 @@ export function getParallelMessageProcessingConfig(): boolean { return false; } const setting = config.inspect(parallelMessageProcessingConfig); - return (azdata.env.quality === azdata.env.AppQuality.dev && setting.globalValue === undefined && setting.workspaceValue === undefined) ? true : config[parallelMessageProcessingConfig]; + return (azdata.env.quality === azdata.env.AppQuality.dev && setting?.globalValue === undefined && setting?.workspaceValue === undefined) ? true : config[parallelMessageProcessingConfig]; } export function getAzureAuthenticationLibraryConfig(): string { const config = getAzureCoreExtConfiguration(); if (config) { - return config.has(azureAuthenticationLibraryConfig) - ? config.get(azureAuthenticationLibraryConfig) - : 'MSAL'; // default Auth library + return config.get(azureAuthenticationLibraryConfig, 'MSAL'); // default Auth library } else { return 'MSAL'; @@ -168,9 +165,7 @@ export function getAzureAuthenticationLibraryConfig(): string { export function getEnableSqlAuthenticationProviderConfig(): boolean { const config = getConfiguration(); if (config) { - return config.has(enableSqlAuthenticationProviderConfig) - ? config.get(enableSqlAuthenticationProviderConfig) - : false; // disabled by default + return config.get(enableSqlAuthenticationProviderConfig, false); // disabled by default } else { return false; @@ -215,70 +210,6 @@ export function ensure(target: { [key: string]: any }, key: string): any { return target[key]; } -export interface IPackageInfo { - name: string; - version: string; - aiKey: string; -} - -export function getPackageInfo(packageJson: any): IPackageInfo { - if (packageJson) { - return { - name: packageJson.name, - version: packageJson.version, - aiKey: packageJson.aiKey - }; - } - return undefined; -} - -export function generateUserId(): Promise { - return new Promise(resolve => { - try { - let interfaces = os.networkInterfaces(); - let mac; - for (let key of Object.keys(interfaces)) { - let item = interfaces[key][0]; - if (!item.internal) { - mac = item.mac; - break; - } - } - if (mac) { - resolve(crypto.createHash('sha256').update(mac + os.homedir(), 'utf8').digest('hex')); - } else { - resolve(generateGuid()); - } - } catch (err) { - resolve(generateGuid()); // fallback - } - }); -} - -export function generateGuid(): string { - let hexValues: string[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F']; - // c.f. rfc4122 (UUID version 4 = xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx) - let oct: string = ''; - let tmp: number; - /* tslint:disable:no-bitwise */ - for (let a: number = 0; a < 4; a++) { - tmp = (4294967296 * Math.random()) | 0; - oct += hexValues[tmp & 0xF] + - hexValues[tmp >> 4 & 0xF] + - hexValues[tmp >> 8 & 0xF] + - hexValues[tmp >> 12 & 0xF] + - hexValues[tmp >> 16 & 0xF] + - hexValues[tmp >> 20 & 0xF] + - hexValues[tmp >> 24 & 0xF] + - hexValues[tmp >> 28 & 0xF]; - } - - // 'Set the two most significant bits (bits 6 and 7) of the clock_seq_hi_and_reserved to zero and one, respectively' - let clockSequenceHi: string = hexValues[8 + (Math.random() * 4) | 0]; - return oct.substr(0, 8) + '-' + oct.substr(9, 4) + '-4' + oct.substr(13, 3) + '-' + clockSequenceHi + oct.substr(16, 3) + '-' + oct.substr(19, 12); - /* tslint:enable:no-bitwise */ -} - export function verifyPlatform(): Thenable { if (os.platform() === 'darwin' && parseFloat(os.release()) < 16) { return Promise.resolve(false); @@ -320,7 +251,7 @@ export function isObjectExplorerContext(object: any): object is azdata.ObjectExp } export function getUserHome(): string { - return process.env.HOME || process.env.USERPROFILE; + return process.env.HOME || process.env.USERPROFILE || ''; } export function isValidNumber(maybeNumber: any) {