mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Clean up some of the extensions (#8267)
* 💄
* prune unused code
* more cleanup
* remove abunch of used code
This commit is contained in:
@@ -996,7 +996,6 @@
|
||||
"error-ex": "^1.3.2",
|
||||
"figures": "^2.0.0",
|
||||
"find-remove": "1.2.1",
|
||||
"fs-extra": "^3.0.1",
|
||||
"kerberos": "^1.1.3",
|
||||
"request": "^2.88.0",
|
||||
"request-promise": "^4.2.2",
|
||||
@@ -1004,14 +1003,16 @@
|
||||
"stream-meter": "^1.0.4",
|
||||
"through2": "^3.0.1",
|
||||
"tough-cookie": "^3.0.1",
|
||||
"uri-js": "^4.2.2",
|
||||
"vscode-extension-telemetry": "0.1.0",
|
||||
"vscode-languageclient": "5.2.1",
|
||||
"vscode-nls": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bytes": "^3.0.0",
|
||||
"@types/kerberos": "^1.1.0",
|
||||
"@types/request": "^2.48.2",
|
||||
"@types/request-promise": "^4.1.44",
|
||||
"@types/stream-meter": "^0.0.22",
|
||||
"@types/through2": "^2.0.34"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ export class ApiWrapper {
|
||||
|
||||
public openTextDocument(uri: vscode.Uri): Thenable<vscode.TextDocument>;
|
||||
public openTextDocument(options: { language?: string; content?: string; }): Thenable<vscode.TextDocument>;
|
||||
public openTextDocument(uriOrOptions): Thenable<vscode.TextDocument> {
|
||||
public openTextDocument(uriOrOptions: any): Thenable<vscode.TextDocument> {
|
||||
return vscode.workspace.openTextDocument(uriOrOptions);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import * as constants from '../constants';
|
||||
import * as contracts from '../contracts';
|
||||
|
||||
@@ -2,18 +2,18 @@
|
||||
* 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';
|
||||
import * as azdata from 'azdata';
|
||||
|
||||
import * as types from './types';
|
||||
import * as Constants from './constants';
|
||||
|
||||
export enum BuiltInCommands {
|
||||
enum BuiltInCommands {
|
||||
SetContext = 'setContext',
|
||||
}
|
||||
|
||||
export enum ContextKeys {
|
||||
enum ContextKeys {
|
||||
ISCLOUD = 'mssql:iscloud',
|
||||
EDITIONID = 'mssql:engineedition',
|
||||
ISCLUSTER = 'mssql:iscluster',
|
||||
@@ -26,7 +26,7 @@ const isCloudEditions = [
|
||||
11
|
||||
];
|
||||
|
||||
export function setCommandContext(key: ContextKeys | string, value: any) {
|
||||
function setCommandContext(key: ContextKeys | string, value: any) {
|
||||
return vscode.commands.executeCommand(BuiltInCommands.SetContext, key, value);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,13 +30,13 @@ const resolveBookResources = (extension: vscode.Extension<any>, books: BookContr
|
||||
return result;
|
||||
};
|
||||
|
||||
export interface BookContribution {
|
||||
interface BookContribution {
|
||||
name: string;
|
||||
path: string;
|
||||
when?: string;
|
||||
}
|
||||
|
||||
export namespace BookContributions {
|
||||
namespace BookContributions {
|
||||
|
||||
export function merge(a: BookContribution[], b: BookContribution[]): BookContribution[] {
|
||||
if (!a) {
|
||||
|
||||
@@ -2,6 +2,5 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
export default require('error-ex')('EscapeException');
|
||||
|
||||
@@ -290,7 +290,7 @@ export function parseAclList(aclString: string): AclEntry[] {
|
||||
* assumes the string has already been checked for validity.
|
||||
* @param aclString The string representation of the ACL entry
|
||||
*/
|
||||
export function parseAclEntry(aclString: string): AclEntry {
|
||||
function parseAclEntry(aclString: string): AclEntry {
|
||||
const parts: string[] = aclString.split(':');
|
||||
let i = 0;
|
||||
const scope: AclEntryScope = parts.length === 4 && parts[i++] === 'default' ? AclEntryScope.default : AclEntryScope.access;
|
||||
|
||||
@@ -15,19 +15,20 @@ import { PermissionStatus, AclEntry, parseAclList, PermissionType, parseAclPermi
|
||||
import { Mount } from './mount';
|
||||
import { everyoneName, ownerPostfix, owningGroupPostfix } from '../localizedConstants';
|
||||
import { FileStatus, parseHdfsFileType } from './fileStatus';
|
||||
import { Readable, Transform } from 'stream';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
const ErrorMessageInvalidDataStructure = localize('webhdfs.invalidDataStructure', "Invalid Data Structure");
|
||||
|
||||
const emitError = (instance, err) => {
|
||||
const isErrorEmitted = instance.errorEmitted;
|
||||
const emitError = (instance: request.Request | Transform, err: any) => {
|
||||
const isErrorEmitted = (instance as any).errorEmitted;
|
||||
|
||||
if (!isErrorEmitted) {
|
||||
instance.emit('error', err);
|
||||
instance.emit('finish');
|
||||
}
|
||||
|
||||
instance.errorEmitted = true;
|
||||
(instance as any).errorEmitted = true;
|
||||
};
|
||||
|
||||
export class WebHDFS {
|
||||
@@ -41,7 +42,7 @@ export class WebHDFS {
|
||||
}
|
||||
|
||||
let missingProps = ['host', 'port', 'path']
|
||||
.filter(p => !opts.hasOwnProperty(p) || !opts[p]);
|
||||
.filter((p: keyof IHdfsOptions) => !opts.hasOwnProperty(p) || !opts[p]);
|
||||
if (missingProps && missingProps.length > 0) {
|
||||
throw new Error(localize('webhdfs.missingProperties',
|
||||
"Unable to create WebHDFS client due to missing options: ${0}", missingProps.join(', ')));
|
||||
@@ -224,7 +225,7 @@ export class WebHDFS {
|
||||
);
|
||||
this.ensureCookie(requestParams);
|
||||
// Add a wrapper to handle unauthorized requests by adding kerberos auth steps
|
||||
let handler = (error, response) => {
|
||||
let handler = (error: any, response: request.Response) => {
|
||||
if (error && error.statusCode === 401 && this._requestParams.isKerberos) {
|
||||
this.requestWithKerberosSync(requestParams, callback);
|
||||
} else {
|
||||
@@ -234,7 +235,7 @@ export class WebHDFS {
|
||||
this.doSendRequest(requestParams, handler);
|
||||
}
|
||||
|
||||
private ensureCookie(requestParams: { headers?: {} }) {
|
||||
private ensureCookie(requestParams: { headers?: { [key: string]: string } }) {
|
||||
if (this._authCookie && this._authCookie.expiryTime() > Date.now()) {
|
||||
requestParams.headers = requestParams.headers || {};
|
||||
requestParams.headers['cookie'] = `${this._authCookie.key}=${this._authCookie.value}`;
|
||||
@@ -242,7 +243,7 @@ export class WebHDFS {
|
||||
}
|
||||
|
||||
private doSendRequest(requestParams: any, callback: (error: HdfsError, response: any) => void): void {
|
||||
request(requestParams, (error, response, body) => {
|
||||
request(requestParams, (error: any, response: request.Response, body: any) => {
|
||||
if (error || this.isError(response)) {
|
||||
let hdfsError = this.parseError(response, body, error);
|
||||
callback(hdfsError, response);
|
||||
@@ -486,7 +487,7 @@ export class WebHDFS {
|
||||
// Unknown type - just ignore since we don't currently support the other types
|
||||
return;
|
||||
}
|
||||
e.getAllPermissions().forEach( sp => {
|
||||
e.getAllPermissions().forEach(sp => {
|
||||
targetEntry.addPermission(sp.scope, sp.permission);
|
||||
});
|
||||
});
|
||||
@@ -727,7 +728,7 @@ export class WebHDFS {
|
||||
cb();
|
||||
}
|
||||
});
|
||||
let handleErr = (err) => {
|
||||
let handleErr = (err: any) => {
|
||||
replyStream.emit('error', err);
|
||||
replyStream.end();
|
||||
};
|
||||
@@ -735,7 +736,7 @@ export class WebHDFS {
|
||||
// After redirect, create valid stream to correct location
|
||||
// and pipe the intermediate stream to it, unblocking the data flow
|
||||
params.headers['content-type'] = 'application/octet-stream';
|
||||
let upload = request(params, (err, res, bo) => {
|
||||
let upload = request(params, (err: any, res: request.Response, bo: any) => {
|
||||
if (err || this.isError(res)) {
|
||||
emitError(replyStream, this.parseError(res, bo, err));
|
||||
replyStream.end();
|
||||
@@ -760,11 +761,11 @@ export class WebHDFS {
|
||||
private doCreateWriteStream(params: any): fs.WriteStream {
|
||||
|
||||
let canResume: boolean = true;
|
||||
let stream = undefined;
|
||||
let req = request(params, (error, response, body) => {
|
||||
let stream: Readable;
|
||||
let req = request(params, (error: any, response: request.Response, body: any) => {
|
||||
// Handle redirect only if there was not an error (e.g. res is defined)
|
||||
if (response && this.isRedirect(response)) {
|
||||
let upload = request(Object.assign(params, { url: response.headers.location }), (err, res, bo) => {
|
||||
let upload = request(Object.assign(params, { url: response.headers.location }), (err: any, res: request.Response, bo: any) => {
|
||||
if (err || this.isError(res)) {
|
||||
emitError(req, this.parseError(res, bo, err));
|
||||
req.end();
|
||||
@@ -784,7 +785,7 @@ export class WebHDFS {
|
||||
emitError(req, this.parseError(response, body, error));
|
||||
}
|
||||
});
|
||||
req.on('pipe', (src) => {
|
||||
req.on('pipe', (src: Readable) => {
|
||||
// Pause read stream
|
||||
stream = src;
|
||||
stream.pause();
|
||||
@@ -794,7 +795,7 @@ export class WebHDFS {
|
||||
canResume = false;
|
||||
stream.on('resume', () => {
|
||||
if (!canResume) {
|
||||
stream._readableState.flowing = false;
|
||||
(stream as any)._readableState.flowing = false; // i guess we are unsafely accessing this
|
||||
}
|
||||
});
|
||||
// Unpipe initial request
|
||||
@@ -845,7 +846,7 @@ export class WebHDFS {
|
||||
// Else, must add kerberos token and handle redirects
|
||||
params.followRedirect = false;
|
||||
let replyStream = through();
|
||||
let handleErr = (err) => {
|
||||
let handleErr = (err: any) => {
|
||||
replyStream.emit('error', err);
|
||||
replyStream.end();
|
||||
};
|
||||
@@ -960,7 +961,7 @@ export class WebHDFS {
|
||||
this.unlink(path, recursive, callback);
|
||||
}
|
||||
|
||||
public static createClient(opts, requestParams): WebHDFS {
|
||||
public static createClient(opts: IHdfsOptions, requestParams: IRequestParams): WebHDFS {
|
||||
return new WebHDFS(
|
||||
Object.assign(
|
||||
{
|
||||
|
||||
@@ -181,8 +181,8 @@ async function handleNewNotebookTask(oeContext?: azdata.ObjectExplorerContext, p
|
||||
|
||||
async function handleOpenNotebookTask(profile: azdata.IConnectionProfile): Promise<void> {
|
||||
let notebookFileTypeName = localize('notebookFileType', "Notebooks");
|
||||
let filter = {};
|
||||
filter[notebookFileTypeName] = 'ipynb';
|
||||
let filter: { [key: string]: string[] } = {};
|
||||
filter[notebookFileTypeName] = ['ipynb'];
|
||||
let uris = await vscode.window.showOpenDialog({
|
||||
filters: filter,
|
||||
canSelectFiles: true,
|
||||
|
||||
@@ -15,12 +15,12 @@ import * as utils from '../utils';
|
||||
import * as constants from '../constants';
|
||||
import { AppContext } from '../appContext';
|
||||
|
||||
export interface ICommandContextParsingOptions {
|
||||
interface ICommandContextParsingOptions {
|
||||
editor: boolean;
|
||||
uri: boolean;
|
||||
}
|
||||
|
||||
export interface ICommandBaseContext {
|
||||
interface ICommandBaseContext {
|
||||
command: string;
|
||||
editor?: vscode.TextEditor;
|
||||
uri?: vscode.Uri;
|
||||
@@ -30,7 +30,7 @@ export interface ICommandUnknownContext extends ICommandBaseContext {
|
||||
type: 'unknown';
|
||||
}
|
||||
|
||||
export interface ICommandUriContext extends ICommandBaseContext {
|
||||
interface ICommandUriContext extends ICommandBaseContext {
|
||||
type: 'uri';
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ export interface ICommandObjectExplorerContext extends ICommandBaseContext {
|
||||
explorerContext: azdata.ObjectExplorerContext;
|
||||
}
|
||||
|
||||
export type CommandContext = ICommandObjectExplorerContext | ICommandViewContext | ICommandUriContext | ICommandUnknownContext;
|
||||
type CommandContext = ICommandObjectExplorerContext | ICommandViewContext | ICommandUriContext | ICommandUnknownContext;
|
||||
|
||||
function isTextEditor(editor: any): editor is vscode.TextEditor {
|
||||
if (editor === undefined) { return false; }
|
||||
@@ -189,4 +189,4 @@ export function registerSearchServerCommand(appContext: AppContext): void {
|
||||
appContext.apiWrapper.registerCommand('mssql.clearSearchServerResult', () => {
|
||||
vscode.commands.executeCommand('registeredServers.clearSearchServerResult');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,10 +106,11 @@ export interface IFileSource {
|
||||
exists(path: string): Promise<boolean>;
|
||||
}
|
||||
|
||||
export interface IHttpAuthentication {
|
||||
interface IHttpAuthentication {
|
||||
user: string;
|
||||
pass: string;
|
||||
}
|
||||
|
||||
export interface IHdfsOptions {
|
||||
host?: string;
|
||||
port?: number;
|
||||
@@ -176,7 +177,7 @@ export class FileSourceFactory {
|
||||
}
|
||||
}
|
||||
|
||||
export class HdfsFileSource implements IFileSource {
|
||||
class HdfsFileSource implements IFileSource {
|
||||
private mounts: Map<string, Mount>;
|
||||
constructor(private client: WebHDFS) {
|
||||
}
|
||||
@@ -240,7 +241,7 @@ export class HdfsFileSource implements IFileSource {
|
||||
public readFile(path: string, maxBytes?: number): Promise<Buffer> {
|
||||
return new Promise((resolve, reject) => {
|
||||
let error: HdfsError = undefined;
|
||||
let remoteFileStream = this.client.createReadStream(path);
|
||||
let remoteFileStream: fs.ReadStream | meter.StreamMeter = this.client.createReadStream(path);
|
||||
remoteFileStream.on('error', (err) => {
|
||||
error = <HdfsError>err;
|
||||
reject(error);
|
||||
|
||||
@@ -71,8 +71,8 @@ export class UploadFilesCommand extends ProgressCommand {
|
||||
try {
|
||||
let folderNode = await getNode<FolderNode>(context, this.appContext);
|
||||
const allFilesFilter = localize('allFiles', "All Files");
|
||||
let filter = {};
|
||||
filter[allFilesFilter] = '*';
|
||||
let filter: { [key: string]: string[] } = {};
|
||||
filter[allFilesFilter] = ['*'];
|
||||
if (folderNode) {
|
||||
let options: vscode.OpenDialogOptions = {
|
||||
canSelectFiles: true,
|
||||
@@ -175,7 +175,7 @@ export class MkDirCommand extends ProgressCommand {
|
||||
}).then(confirmed => <string>confirmed);
|
||||
}
|
||||
|
||||
private async mkDir(fileName, folderNode: FolderNode, cancelToken: vscode.CancellationTokenSource): Promise<void> {
|
||||
private async mkDir(fileName: string, folderNode: FolderNode, cancelToken: vscode.CancellationTokenSource): Promise<void> {
|
||||
await folderNode.mkdir(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import * as nls from 'vscode-nls';
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
import * as Constants from '../constants';
|
||||
import { IFileSource, IHdfsOptions, IFile, File, FileSourceFactory, FileType } from './fileSources';
|
||||
import { IFileSource, IFile, File, FileType } from './fileSources';
|
||||
import { CancelableStream } from './cancelableStream';
|
||||
import { TreeNode } from './treeNodes';
|
||||
import * as utils from '../utils';
|
||||
@@ -28,53 +28,6 @@ export class TreeDataContext {
|
||||
}
|
||||
}
|
||||
|
||||
export class HdfsProvider implements vscode.TreeDataProvider<TreeNode>, ITreeChangeHandler {
|
||||
static readonly NoConnectionsMessage = 'No connections added';
|
||||
static readonly ConnectionsLabel = 'Connections';
|
||||
|
||||
private connections: ConnectionNode[];
|
||||
private _onDidChangeTreeData = new vscode.EventEmitter<TreeNode>();
|
||||
private context: TreeDataContext;
|
||||
|
||||
constructor(extensionContext: vscode.ExtensionContext) {
|
||||
this.connections = [];
|
||||
this.context = new TreeDataContext(extensionContext, this);
|
||||
}
|
||||
|
||||
public get onDidChangeTreeData(): vscode.Event<TreeNode> {
|
||||
return this._onDidChangeTreeData.event;
|
||||
}
|
||||
|
||||
getTreeItem(element: TreeNode): vscode.TreeItem | Thenable<vscode.TreeItem> {
|
||||
return element.getTreeItem();
|
||||
}
|
||||
|
||||
getChildren(element?: TreeNode): vscode.ProviderResult<TreeNode[]> {
|
||||
if (element) {
|
||||
return element.getChildren(false);
|
||||
} else {
|
||||
return this.connections.length > 0 ? this.connections : [ErrorNode.create(HdfsProvider.NoConnectionsMessage, element)];
|
||||
}
|
||||
}
|
||||
|
||||
addConnection(displayName: string, fileSource: IFileSource): void {
|
||||
if (!this.connections.find(c => c.getDisplayName() === displayName)) {
|
||||
this.connections.push(new ConnectionNode(this.context, displayName, fileSource));
|
||||
this._onDidChangeTreeData.fire();
|
||||
}
|
||||
}
|
||||
|
||||
public async addHdfsConnection(options: IHdfsOptions): Promise<void> {
|
||||
let displayName = `${options.user}@${options.host}:${options.port}`;
|
||||
let fileSource = await FileSourceFactory.instance.createHdfsFileSource(options);
|
||||
this.addConnection(displayName, fileSource);
|
||||
}
|
||||
|
||||
notifyNodeChanged(node: TreeNode): void {
|
||||
this._onDidChangeTreeData.fire(node);
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class HdfsFileSourceNode extends TreeNode {
|
||||
constructor(protected context: TreeDataContext, protected _path: string, public readonly fileSource: IFileSource, protected mountStatus?: MountStatus) {
|
||||
super();
|
||||
@@ -362,7 +315,7 @@ export class FileNode extends HdfsFileSourceNode implements IFileNode {
|
||||
}
|
||||
}
|
||||
|
||||
export class ErrorNode extends TreeNode {
|
||||
class ErrorNode extends TreeNode {
|
||||
static messageNum: number = 0;
|
||||
|
||||
private _nodePathValue: string;
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
* 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 * as nls from 'vscode-nls';
|
||||
@@ -72,7 +70,7 @@ export class MssqlObjectExplorerNodeProvider extends ProviderBase implements azd
|
||||
|
||||
private async doExpandNode(nodeInfo: azdata.ExpandNodeInfo, isRefresh: boolean = false): Promise<boolean> {
|
||||
let session = this.sessionMap.get(nodeInfo.sessionId);
|
||||
let response = {
|
||||
let response: azdata.ObjectExplorerExpandInfo = {
|
||||
sessionId: nodeInfo.sessionId,
|
||||
nodePath: nodeInfo.nodePath,
|
||||
errorMessage: undefined,
|
||||
@@ -235,7 +233,7 @@ export class MssqlObjectExplorerNodeProvider extends ProviderBase implements azd
|
||||
}
|
||||
}
|
||||
|
||||
export class SqlClusterSession {
|
||||
class SqlClusterSession {
|
||||
private _rootNode: SqlClusterRootNode;
|
||||
|
||||
constructor(
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
import { window } from 'vscode';
|
||||
import PromptFactory from './factory';
|
||||
import EscapeException from '../escapeException';
|
||||
import { IQuestion, IPrompter, IPromptCallback } from './question';
|
||||
import { IQuestion, IPrompter } 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: any): any {
|
||||
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
|
||||
@@ -46,7 +46,7 @@ export default class CodeAdapter implements IPrompter {
|
||||
return PromptFactory.createPrompt(question, ignoreFocusOut);
|
||||
}).then(prompt => {
|
||||
if (!question.shouldPrompt || question.shouldPrompt(answers) === true) {
|
||||
return prompt.render().then(result => {
|
||||
return prompt.render().then((result: T) => {
|
||||
answers[question.name] = result;
|
||||
|
||||
if (question.onAnswered) {
|
||||
@@ -67,14 +67,4 @@ export default class CodeAdapter implements IPrompter {
|
||||
window.showErrorMessage(err.message);
|
||||
});
|
||||
}
|
||||
|
||||
// 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) {
|
||||
callback(answers);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
'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;
|
||||
}, []);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
// This code is originally from https://github.com/DonJayamanne/bowerVSCode
|
||||
// License: https://github.com/DonJayamanne/bowerVSCode/blob/master/LICENSE
|
||||
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
'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;
|
||||
}
|
||||
}
|
||||
@@ -1,33 +1,22 @@
|
||||
'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';
|
||||
import { IQuestion } from './question';
|
||||
|
||||
export default class PromptFactory {
|
||||
|
||||
public static createPrompt(question: any, ignoreFocusOut?: boolean): Prompt {
|
||||
switch (question.type || 'input') {
|
||||
case 'string':
|
||||
public static createPrompt(question: IQuestion, ignoreFocusOut?: boolean): Prompt {
|
||||
switch (question.type) {
|
||||
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}`);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
// This code is originally from https://github.com/DonJayamanne/bowerVSCode
|
||||
// License: https://github.com/DonJayamanne/bowerVSCode/blob/master/LICENSE
|
||||
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
'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];
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
// This code is originally from https://github.com/DonJayamanne/bowerVSCode
|
||||
// License: https://github.com/DonJayamanne/bowerVSCode/blob/master/LICENSE
|
||||
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
'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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,15 @@
|
||||
'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';
|
||||
import { IQuestion } from './question';
|
||||
|
||||
abstract class Prompt {
|
||||
|
||||
protected _question: any;
|
||||
protected _question: IQuestion;
|
||||
protected _ignoreFocusOut?: boolean;
|
||||
|
||||
constructor(question: any, ignoreFocusOut?: boolean) {
|
||||
constructor(question: IQuestion, ignoreFocusOut?: boolean) {
|
||||
this._question = question;
|
||||
this._ignoreFocusOut = ignoreFocusOut ? ignoreFocusOut : false;
|
||||
}
|
||||
|
||||
@@ -3,15 +3,12 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import vscode = require('vscode');
|
||||
import * as vscode from '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
|
||||
@@ -40,19 +37,11 @@ export interface IQuestion {
|
||||
}
|
||||
|
||||
// Pair used to display simple choices to the user
|
||||
export interface INameValueChoice {
|
||||
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 interface IPrompter {
|
||||
promptSingle<T>(question: IQuestion, ignoreFocusOut?: boolean): Promise<T>;
|
||||
/**
|
||||
@@ -61,10 +50,5 @@ export interface IPrompter {
|
||||
* @returns Map of question IDs to results, or undefined if
|
||||
* the user canceled the question session
|
||||
*/
|
||||
prompt<T>(questions: IQuestion[], ignoreFocusOut?: boolean): Promise<{ [questionId: string]: any }>;
|
||||
promptCallback(questions: IQuestion[], callback: IPromptCallback): void;
|
||||
}
|
||||
|
||||
export interface IPromptCallback {
|
||||
(answers: { [id: string]: any }): void;
|
||||
prompt(questions: IQuestion[], ignoreFocusOut?: boolean): Promise<{ [questionId: string]: any }>;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
export const serviceName = 'AzureResourceProvider';
|
||||
export const providerId = 'azureresourceProvider';
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { RequestType } from 'vscode-languageclient';
|
||||
import * as azdata from 'azdata';
|
||||
@@ -25,7 +24,7 @@ export interface CreateFirewallRuleParams {
|
||||
securityTokenMappings: {};
|
||||
}
|
||||
|
||||
export interface CreateFirewallRuleResponse {
|
||||
interface CreateFirewallRuleResponse {
|
||||
result: boolean;
|
||||
errorMessage: string;
|
||||
}
|
||||
@@ -36,7 +35,7 @@ export interface HandleFirewallRuleParams {
|
||||
connectionTypeId: string;
|
||||
}
|
||||
|
||||
export interface HandleFirewallRuleResponse {
|
||||
interface HandleFirewallRuleResponse {
|
||||
result: boolean;
|
||||
ipAddress: string;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import { IConfig, ServerProvider } from 'service-downloader';
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import * as nls from 'vscode-nls';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
* 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 * as nls from 'vscode-nls';
|
||||
|
||||
@@ -38,7 +38,7 @@ export class SparkJobSubmissionModel {
|
||||
private readonly _sqlClusterConnection: SqlClusterConnection,
|
||||
private readonly _dialog: azdata.window.Dialog,
|
||||
private readonly _appContext: AppContext,
|
||||
requestService?: (args: any) => any) {
|
||||
requestService?: typeof import('request-promise')) {
|
||||
|
||||
if (!this._sqlClusterConnection || !this._dialog || !this._appContext) {
|
||||
throw new Error(localize('sparkJobSubmission.SparkJobSubmissionModelInitializeError',
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as os from 'os';
|
||||
import * as nls from 'vscode-nls';
|
||||
const localize = nls.loadMessageBundle();
|
||||
@@ -12,12 +10,13 @@ import * as constants from '../../../constants';
|
||||
import { SqlClusterConnection } from '../../../objectExplorerNodeProvider/connection';
|
||||
import * as utils from '../../../utils';
|
||||
import * as auth from '../../../util/auth';
|
||||
import { Options } from 'request-promise';
|
||||
|
||||
export class SparkJobSubmissionService {
|
||||
private _requestPromise: (args: any) => any;
|
||||
private _requestPromise: typeof import('request-promise');
|
||||
|
||||
constructor(
|
||||
requestService?: (args: any) => any) {
|
||||
requestService?: typeof import('request-promise')) {
|
||||
if (requestService) {
|
||||
// this is to fake the request service for test.
|
||||
this._requestPromise = requestService;
|
||||
@@ -33,7 +32,7 @@ export class SparkJobSubmissionService {
|
||||
// Get correct authentication headers
|
||||
let headers = await this.getAuthenticationHeaders(submissionArgs);
|
||||
|
||||
let options = {
|
||||
let options: Options = {
|
||||
uri: livyUrl,
|
||||
method: 'POST',
|
||||
json: true,
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
* 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 { AppContext } from '../appContext';
|
||||
|
||||
@@ -1,217 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as childProcess from 'child_process';
|
||||
import * as fs from 'fs-extra';
|
||||
import * as path from 'path';
|
||||
import * as azdata from 'azdata';
|
||||
import * as vscode from 'vscode';
|
||||
import * as which from 'which';
|
||||
import * as constants from '../constants';
|
||||
import * as nls from 'vscode-nls';
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
export function getDropdownValue(dropdownValue: string | azdata.CategoryValue): string {
|
||||
if (typeof (dropdownValue) === 'string') {
|
||||
return <string>dropdownValue;
|
||||
} else {
|
||||
return dropdownValue ? (<azdata.CategoryValue>dropdownValue).name : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export function getServerAddressFromName(connection: azdata.ConnectionInfo | string): string {
|
||||
// Strip TDS port number from the server URI
|
||||
if ((<azdata.ConnectionInfo>connection).options && (<azdata.ConnectionInfo>connection).options[constants.hostPropName]) {
|
||||
return (<azdata.ConnectionInfo>connection).options[constants.hostPropName].split(',')[0].split(':')[0];
|
||||
} else if ((<azdata.ConnectionInfo>connection).options && (<azdata.ConnectionInfo>connection).options['server']) {
|
||||
return (<azdata.ConnectionInfo>connection).options['server'].split(',')[0].split(':')[0];
|
||||
} else {
|
||||
return (<string>connection).split(',')[0].split(':')[0];
|
||||
}
|
||||
}
|
||||
|
||||
export function getKnoxUrl(host: string, port: string): string {
|
||||
return `https://${host}:${port}/gateway`;
|
||||
}
|
||||
|
||||
export function getLivyUrl(serverName: string, port: string): string {
|
||||
return this.getKnoxUrl(serverName, port) + '/default/livy/v1/';
|
||||
}
|
||||
|
||||
export function getTemplatePath(extensionPath: string, templateName: string): string {
|
||||
return path.join(extensionPath, 'resources', templateName);
|
||||
}
|
||||
export function shellWhichResolving(cmd: string): Promise<string> {
|
||||
return new Promise<string>(resolve => {
|
||||
which(cmd, async (err, foundPath) => {
|
||||
if (err) {
|
||||
resolve(undefined);
|
||||
} else {
|
||||
// NOTE: Using realpath b/c some system installs are symlinked from */bin
|
||||
resolve(await fs.promises.realpath(foundPath));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export async function mkDir(dirPath: string, outputChannel?: vscode.OutputChannel): Promise<void> {
|
||||
if (!await fs.exists(dirPath)) {
|
||||
if (outputChannel) {
|
||||
outputChannel.appendLine(localize('mkdirOutputMsg', "... Creating {0}", dirPath));
|
||||
}
|
||||
await fs.ensureDir(dirPath);
|
||||
}
|
||||
}
|
||||
|
||||
export function getErrorMessage(error: Error | string): string {
|
||||
return (error instanceof Error) ? error.message : error;
|
||||
}
|
||||
|
||||
// COMMAND EXECUTION HELPERS ///////////////////////////////////////////////
|
||||
export function executeBufferedCommand(cmd: string, options: childProcess.ExecOptions, outputChannel?: vscode.OutputChannel): Thenable<string> {
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
if (outputChannel) {
|
||||
outputChannel.appendLine(` > ${cmd}`);
|
||||
}
|
||||
|
||||
let child = childProcess.exec(cmd, options, (err, stdout) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(stdout);
|
||||
}
|
||||
});
|
||||
|
||||
// Add listeners to print stdout and stderr if an output channel was provided
|
||||
if (outputChannel) {
|
||||
child.stdout.on('data', data => { outputDataChunk(data, outputChannel, ' stdout: '); });
|
||||
child.stderr.on('data', data => { outputDataChunk(data, outputChannel, ' stderr: '); });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function executeExitCodeCommand(cmd: string, outputChannel?: vscode.OutputChannel): Thenable<number> {
|
||||
return new Promise<number>((resolve, reject) => {
|
||||
if (outputChannel) {
|
||||
outputChannel.appendLine(` > ${cmd}`);
|
||||
}
|
||||
|
||||
let child = childProcess.spawn(cmd, [], { shell: true, detached: false });
|
||||
|
||||
// Add listeners for the process to exit
|
||||
child.on('error', reject);
|
||||
child.on('exit', (code: number) => { resolve(code); });
|
||||
|
||||
// Add listeners to print stdout and stderr if an output channel was provided
|
||||
if (outputChannel) {
|
||||
child.stdout.on('data', data => { outputDataChunk(data, outputChannel, ' stdout: '); });
|
||||
child.stderr.on('data', data => { outputDataChunk(data, outputChannel, ' stderr: '); });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function executeStreamedCommand(cmd: string, outputChannel?: vscode.OutputChannel): Thenable<void> {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
// Start the command
|
||||
if (outputChannel) {
|
||||
outputChannel.appendLine(` > ${cmd}`);
|
||||
}
|
||||
let child = childProcess.spawn(cmd, [], { shell: true, detached: false });
|
||||
|
||||
// Add listeners to resolve/reject the promise on exit
|
||||
child.on('error', reject);
|
||||
child.on('exit', (code: number) => {
|
||||
if (code === 0) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(localize('executeCommandProcessExited', "Process exited with code {0}", code));
|
||||
}
|
||||
});
|
||||
|
||||
// Add listeners to print stdout and stderr if an output channel was provided
|
||||
if (outputChannel) {
|
||||
child.stdout.on('data', data => { outputDataChunk(data, outputChannel, ' stdout: '); });
|
||||
child.stderr.on('data', data => { outputDataChunk(data, outputChannel, ' stderr: '); });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function isObjectExplorerContext(object: any): object is azdata.ObjectExplorerContext {
|
||||
return 'connectionProfile' in object && 'isConnectionNode' in object;
|
||||
}
|
||||
|
||||
export function getUserHome(): string {
|
||||
return process.env.HOME || process.env.USERPROFILE;
|
||||
}
|
||||
|
||||
export enum Platform {
|
||||
Mac,
|
||||
Linux,
|
||||
Windows,
|
||||
Others
|
||||
}
|
||||
|
||||
export function getOSPlatform(): Platform {
|
||||
switch (process.platform) {
|
||||
case 'win32':
|
||||
return Platform.Windows;
|
||||
case 'darwin':
|
||||
return Platform.Mac;
|
||||
case 'linux':
|
||||
return Platform.Linux;
|
||||
default:
|
||||
return Platform.Others;
|
||||
}
|
||||
}
|
||||
|
||||
export function getOSPlatformId(): string {
|
||||
let platformId = undefined;
|
||||
switch (process.platform) {
|
||||
case 'win32':
|
||||
platformId = 'win-x64';
|
||||
break;
|
||||
case 'darwin':
|
||||
platformId = 'osx';
|
||||
break;
|
||||
default:
|
||||
platformId = 'linux-x64';
|
||||
break;
|
||||
}
|
||||
return platformId;
|
||||
}
|
||||
|
||||
// PRIVATE HELPERS /////////////////////////////////////////////////////////
|
||||
function outputDataChunk(data: string | Buffer, outputChannel: vscode.OutputChannel, header: string): void {
|
||||
data.toString().split(/\r?\n/)
|
||||
.forEach(line => {
|
||||
outputChannel.appendLine(header + line);
|
||||
});
|
||||
}
|
||||
|
||||
export function clone<T>(obj: T): T {
|
||||
if (!obj || typeof obj !== 'object') {
|
||||
return obj;
|
||||
}
|
||||
if (obj instanceof RegExp) {
|
||||
// See https://github.com/Microsoft/TypeScript/issues/10990
|
||||
return obj as any;
|
||||
}
|
||||
const result = (Array.isArray(obj)) ? <any>[] : <any>{};
|
||||
Object.keys(obj).forEach(key => {
|
||||
if (obj[key] && typeof obj[key] === 'object') {
|
||||
result[key] = clone(obj[key]);
|
||||
} else {
|
||||
result[key] = obj[key];
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
export function isValidNumber(maybeNumber: any) {
|
||||
return maybeNumber !== undefined
|
||||
&& maybeNumber !== null
|
||||
&& maybeNumber !== ''
|
||||
&& !isNaN(Number(maybeNumber.toString()));
|
||||
}
|
||||
@@ -26,7 +26,7 @@ export interface ITelemetryEventMeasures {
|
||||
/**
|
||||
* Filters error paths to only include source files. Exported to support testing
|
||||
*/
|
||||
export function FilterErrorPath(line: string): string {
|
||||
function FilterErrorPath(line: string): string {
|
||||
if (line) {
|
||||
let values: string[] = line.split('/out/');
|
||||
if (values.length <= 1) {
|
||||
|
||||
19
extensions/mssql/src/typings/bufferStreamReader.d.ts
vendored
Normal file
19
extensions/mssql/src/typings/bufferStreamReader.d.ts
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
declare module 'buffer-stream-reader' {
|
||||
import * as fs from 'fs';
|
||||
|
||||
class BufferStreamReader {
|
||||
constructor(stream: string | Buffer);
|
||||
pipe(pipe: fs.WriteStream): void
|
||||
}
|
||||
|
||||
namespace BufferStreamReader {
|
||||
interface FindRemoveOptions {
|
||||
age?: {
|
||||
seconds?: number;
|
||||
};
|
||||
limit?: number;
|
||||
}
|
||||
}
|
||||
|
||||
export = BufferStreamReader;
|
||||
}
|
||||
17
extensions/mssql/src/typings/findRemove.d.ts
vendored
Normal file
17
extensions/mssql/src/typings/findRemove.d.ts
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
declare module 'find-remove' {
|
||||
namespace findRemove {
|
||||
interface FindRemoveApi {
|
||||
(path: string, options: FindRemoveOptions): JSON;
|
||||
}
|
||||
|
||||
interface FindRemoveOptions {
|
||||
age?: {
|
||||
seconds?: number;
|
||||
};
|
||||
limit?: number;
|
||||
}
|
||||
}
|
||||
|
||||
const findRemove: findRemove.FindRemoveApi;
|
||||
export = findRemove;
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
export function disposeAll(disposables: vscode.Disposable[]) {
|
||||
function disposeAll(disposables: vscode.Disposable[]) {
|
||||
while (disposables.length) {
|
||||
const item = disposables.pop();
|
||||
if (item) {
|
||||
@@ -39,4 +39,4 @@ export abstract class Disposable {
|
||||
protected get isDisposed() {
|
||||
return this._isDisposed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ export function getCommonLaunchArgsAndCleanupOldLogFiles(logPath: string, fileNa
|
||||
return launchArgs;
|
||||
}
|
||||
|
||||
export function ensure(target: object, key: string): any {
|
||||
export function ensure(target: { [key: string]: any }, key: string): any {
|
||||
if (target[key] === void 0) {
|
||||
target[key] = {} as any;
|
||||
}
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
"compilerOptions": {
|
||||
"outDir": "./out",
|
||||
"strict": false,
|
||||
"noUnusedParameters": false,
|
||||
"noImplicitAny": false
|
||||
"noUnusedParameters": false
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
|
||||
@@ -2,6 +2,16 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@types/bluebird@*":
|
||||
version "3.5.28"
|
||||
resolved "https://registry.yarnpkg.com/@types/bluebird/-/bluebird-3.5.28.tgz#04c1a520ff076649236bc8ca21198542ce2bdb09"
|
||||
integrity sha512-0Vk/kqkukxPKSzP9c8WJgisgGDx5oZDbsLLWIP5t70yThO/YleE+GEm2S1GlRALTaack3O7U5OS5qEm7q2kciA==
|
||||
|
||||
"@types/bytes@^3.0.0":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/bytes/-/bytes-3.0.0.tgz#549eeacd0a8fecfaa459334583a4edcee738e6db"
|
||||
integrity sha512-ZF43+CIIlzngQe8/Zo7L1kpY9W8O6rO006VDz3c5iM21ddtXWxCEyOXyft+q4pVF2tGqvrVuVrEDH1+gJEi1fQ==
|
||||
|
||||
"@types/caseless@*":
|
||||
version "0.12.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.2.tgz#f65d3d6389e01eeb458bd54dc8f52b95a9463bc8"
|
||||
@@ -17,6 +27,24 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.2.tgz#c4e63af5e8823ce9cc3f0b34f7b998c2171f0c44"
|
||||
integrity sha512-dyYO+f6ihZEtNPDcWNR1fkoTDf3zAK3lAABDze3mz6POyIercH0lEUawUFXlG8xaQZmm1yEBON/4TsYv/laDYg==
|
||||
|
||||
"@types/request-promise@^4.1.44":
|
||||
version "4.1.44"
|
||||
resolved "https://registry.yarnpkg.com/@types/request-promise/-/request-promise-4.1.44.tgz#05b59cd18445832fae16b68d5bb3d4621b549485"
|
||||
integrity sha512-RId7eFsUKxfal1LirDDIcOp9u3MM3NXFDBcC3sqIMcmu7f4U6DsCEMD8RbLZtnPrQlN5Jc79di/WPsIEDO4keg==
|
||||
dependencies:
|
||||
"@types/bluebird" "*"
|
||||
"@types/request" "*"
|
||||
|
||||
"@types/request@*":
|
||||
version "2.48.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.3.tgz#970b8ed2317568c390361d29c555a95e74bd6135"
|
||||
integrity sha512-3Wo2jNYwqgXcIz/rrq18AdOZUQB8cQ34CXZo+LUwPJNpvRAL86+Kc2wwI8mqpz9Cr1V+enIox5v+WZhy/p3h8w==
|
||||
dependencies:
|
||||
"@types/caseless" "*"
|
||||
"@types/node" "*"
|
||||
"@types/tough-cookie" "*"
|
||||
form-data "^2.5.0"
|
||||
|
||||
"@types/request@^2.48.2":
|
||||
version "2.48.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.2.tgz#936374cbe1179d7ed529fc02543deb4597450fed"
|
||||
@@ -27,6 +55,13 @@
|
||||
"@types/tough-cookie" "*"
|
||||
form-data "^2.5.0"
|
||||
|
||||
"@types/stream-meter@^0.0.22":
|
||||
version "0.0.22"
|
||||
resolved "https://registry.yarnpkg.com/@types/stream-meter/-/stream-meter-0.0.22.tgz#6602f644ea0f5468cae13931ee6611a3a03fbab1"
|
||||
integrity sha512-gqqudd3q69aEmixGIL1p2qN1AySZ+UJ2j6y70ZXZBg8/SmzTM1MvkOKvmuelKNIpPS8bKml6Gw03pfbnI8YpwQ==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/through2@^2.0.34":
|
||||
version "2.0.34"
|
||||
resolved "https://registry.yarnpkg.com/@types/through2/-/through2-2.0.34.tgz#9c2a259a238dace2a05a2f8e94b786961bc27ac4"
|
||||
@@ -534,15 +569,6 @@ fs-constants@^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-extra@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-3.0.1.tgz#3794f378c58b342ea7dbbb23095109c4b3b62291"
|
||||
integrity sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=
|
||||
dependencies:
|
||||
graceful-fs "^4.1.2"
|
||||
jsonfile "^3.0.0"
|
||||
universalify "^0.1.0"
|
||||
|
||||
fs.realpath@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
@@ -594,7 +620,7 @@ glob@^7.0.5:
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
graceful-fs@^4.1.10, graceful-fs@^4.1.2, graceful-fs@^4.1.6:
|
||||
graceful-fs@^4.1.10:
|
||||
version "4.1.15"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
|
||||
integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==
|
||||
@@ -742,13 +768,6 @@ json-stringify-safe@~5.0.1:
|
||||
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
|
||||
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
|
||||
|
||||
jsonfile@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-3.0.1.tgz#a5ecc6f65f53f662c4415c7675a0331d0992ec66"
|
||||
integrity sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=
|
||||
optionalDependencies:
|
||||
graceful-fs "^4.1.6"
|
||||
|
||||
jsprim@^1.2.2:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
|
||||
@@ -1320,11 +1339,6 @@ unbzip2-stream@^1.0.9:
|
||||
buffer "^5.2.1"
|
||||
through "^2.3.8"
|
||||
|
||||
universalify@^0.1.0:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
|
||||
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
|
||||
|
||||
uri-js@^4.2.2:
|
||||
version "4.2.2"
|
||||
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
|
||||
|
||||
Reference in New Issue
Block a user