mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-01 09:35:41 -05:00
Fixes how azure auth is handled on the azure pane (#9654)
This commit is contained in:
@@ -196,7 +196,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@azure/arm-resourcegraph": "^2.0.0",
|
||||
"@azure/arm-subscriptions": "1.0.0",
|
||||
"@azure/arm-subscriptions": "^2.0.0",
|
||||
"adal-node": "^0.2.1",
|
||||
"axios": "^0.19.2",
|
||||
"request": "2.88.0",
|
||||
|
||||
@@ -76,7 +76,7 @@ export function registerAzureResourceCommands(appContext: AppContext, tree: Azur
|
||||
const token = tokens[tenant.id].token;
|
||||
const tokenType = tokens[tenant.id].tokenType;
|
||||
|
||||
result.resourceGroups.push(...await service.getResources(subscription, new TokenCredentials(token, tokenType)));
|
||||
result.resourceGroups.push(...await service.getResources(subscription, new TokenCredentials(token, tokenType), account));
|
||||
} catch (err) {
|
||||
const error = new Error(localize('azure.accounts.getResourceGroups.queryError', "Error fetching resource groups for account {0} ({1}) subscription {2} ({3}) tenant {4} : {5}",
|
||||
account.displayInfo.displayName,
|
||||
|
||||
@@ -33,7 +33,7 @@ export interface IAzureResourceCacheService {
|
||||
}
|
||||
|
||||
export interface IAzureResourceTenantService {
|
||||
getTenantId(subscription: azureResource.AzureResourceSubscription): Promise<string>;
|
||||
getTenantId(subscription: azureResource.AzureResourceSubscription, account: Account, credential: msRest.ServiceClientCredentials): Promise<string>;
|
||||
}
|
||||
|
||||
export interface IAzureResourceNodeWithProviderId {
|
||||
@@ -42,5 +42,5 @@ export interface IAzureResourceNodeWithProviderId {
|
||||
}
|
||||
|
||||
export interface IAzureResourceService<T extends azureResource.AzureResource> {
|
||||
getResources(subscription: azureResource.AzureResourceSubscription, credential: msRest.ServiceClientCredentials): Promise<T[]>;
|
||||
getResources(subscription: azureResource.AzureResourceSubscription, credential: msRest.ServiceClientCredentials, account: Account): Promise<T[]>;
|
||||
}
|
||||
|
||||
@@ -9,14 +9,15 @@ import { IAzureResourceService } from '../../interfaces';
|
||||
import { serversQuery, DbServerGraphData } from '../databaseServer/databaseServerService';
|
||||
import { ResourceGraphClient } from '@azure/arm-resourcegraph';
|
||||
import { queryGraphResources, GraphData } from '../resourceTreeDataProviderBase';
|
||||
import { Account } from 'azdata';
|
||||
|
||||
interface DatabaseGraphData extends GraphData {
|
||||
kind: string;
|
||||
}
|
||||
export class AzureResourceDatabaseService implements IAzureResourceService<azureResource.AzureResourceDatabase> {
|
||||
public async getResources(subscription: azureResource.AzureResourceSubscription, credential: ServiceClientCredentials): Promise<azureResource.AzureResourceDatabase[]> {
|
||||
public async getResources(subscription: azureResource.AzureResourceSubscription, credential: ServiceClientCredentials, account: Account): Promise<azureResource.AzureResourceDatabase[]> {
|
||||
const databases: azureResource.AzureResourceDatabase[] = [];
|
||||
const resourceClient = new ResourceGraphClient(credential);
|
||||
const resourceClient = new ResourceGraphClient(credential, { baseUri: account.properties.providerSettings.settings.armResource.endpoint });
|
||||
|
||||
// Query servers and databases in parallel (start both promises before waiting on the 1st)
|
||||
let serverQueryPromise = queryGraphResources<GraphData>(resourceClient, subscription.id, serversQuery);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { TreeItem, ExtensionNodeType } from 'azdata';
|
||||
import { TreeItem, ExtensionNodeType, Account } from 'azdata';
|
||||
import { TreeItemCollapsibleState, ExtensionContext } from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
const localize = nls.loadMessageBundle();
|
||||
@@ -27,7 +27,7 @@ export class AzureResourceDatabaseTreeDataProvider extends ResourceTreeDataProvi
|
||||
) {
|
||||
super(databaseService, apiWrapper);
|
||||
}
|
||||
protected getTreeItemForResource(database: azureResource.AzureResourceDatabase): TreeItem {
|
||||
protected getTreeItemForResource(database: azureResource.AzureResourceDatabase, account: Account): TreeItem {
|
||||
return {
|
||||
id: `databaseServer_${database.serverFullName}.database_${database.name}`,
|
||||
label: `${database.name} (${database.serverName})`,
|
||||
@@ -44,13 +44,14 @@ export class AzureResourceDatabaseTreeDataProvider extends ResourceTreeDataProvi
|
||||
databaseName: database.name,
|
||||
userName: database.loginName,
|
||||
password: '',
|
||||
authenticationType: 'SqlLogin',
|
||||
authenticationType: 'AzureMFA',
|
||||
savePassword: true,
|
||||
groupFullName: '',
|
||||
groupId: '',
|
||||
providerName: 'MSSQL',
|
||||
saveProfile: false,
|
||||
options: {}
|
||||
options: {},
|
||||
azureAccount: account.key.accountId
|
||||
},
|
||||
childProvider: 'MSSQL',
|
||||
type: ExtensionNodeType.Database
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ExtensionNodeType, TreeItem } from 'azdata';
|
||||
import { ExtensionNodeType, TreeItem, Account } from 'azdata';
|
||||
import { TreeItemCollapsibleState, ExtensionContext } from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
const localize = nls.loadMessageBundle();
|
||||
@@ -28,7 +28,7 @@ export class AzureResourceDatabaseServerTreeDataProvider extends ResourceTreeDat
|
||||
}
|
||||
|
||||
|
||||
protected getTreeItemForResource(databaseServer: azureResource.AzureResourceDatabaseServer): TreeItem {
|
||||
protected getTreeItemForResource(databaseServer: azureResource.AzureResourceDatabaseServer, account: Account): TreeItem {
|
||||
return {
|
||||
id: `databaseServer_${databaseServer.id ? databaseServer.id : databaseServer.name}`,
|
||||
label: databaseServer.name,
|
||||
@@ -43,15 +43,16 @@ export class AzureResourceDatabaseServerTreeDataProvider extends ResourceTreeDat
|
||||
connectionName: undefined,
|
||||
serverName: databaseServer.fullName,
|
||||
databaseName: databaseServer.defaultDatabaseName,
|
||||
userName: databaseServer.loginName,
|
||||
userName: '',
|
||||
password: '',
|
||||
authenticationType: 'SqlLogin',
|
||||
authenticationType: 'AzureMFA',
|
||||
savePassword: true,
|
||||
groupFullName: '',
|
||||
groupId: '',
|
||||
providerName: 'MSSQL',
|
||||
saveProfile: false,
|
||||
options: {}
|
||||
options: {},
|
||||
azureAccount: account.key.accountId
|
||||
},
|
||||
childProvider: 'MSSQL',
|
||||
type: ExtensionNodeType.Server
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ExtensionNodeType, TreeItem } from 'azdata';
|
||||
import { ExtensionNodeType, TreeItem, Account } from 'azdata';
|
||||
import { TreeItemCollapsibleState, ExtensionContext } from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
const localize = nls.loadMessageBundle();
|
||||
@@ -28,7 +28,7 @@ export class PostgresServerArcTreeDataProvider extends ResourceTreeDataProviderB
|
||||
}
|
||||
|
||||
|
||||
protected getTreeItemForResource(databaseServer: azureResource.AzureResourceDatabaseServer): TreeItem {
|
||||
protected getTreeItemForResource(databaseServer: azureResource.AzureResourceDatabaseServer, account: Account): TreeItem {
|
||||
return {
|
||||
id: `databaseServer_${databaseServer.id ? databaseServer.id : databaseServer.name}`,
|
||||
label: databaseServer.name,
|
||||
@@ -45,7 +45,7 @@ export class PostgresServerArcTreeDataProvider extends ResourceTreeDataProviderB
|
||||
databaseName: databaseServer.defaultDatabaseName,
|
||||
userName: `${databaseServer.loginName}@${databaseServer.fullName}`,
|
||||
password: '',
|
||||
authenticationType: 'SqlLogin',
|
||||
authenticationType: 'AzureMFA',
|
||||
savePassword: true,
|
||||
groupFullName: '',
|
||||
groupId: '',
|
||||
@@ -54,7 +54,8 @@ export class PostgresServerArcTreeDataProvider extends ResourceTreeDataProviderB
|
||||
options: {
|
||||
// Set default for SSL or will get error complaining about it not being set correctly
|
||||
'sslmode': 'require'
|
||||
}
|
||||
},
|
||||
azureAccount: account.key.accountId
|
||||
},
|
||||
childProvider: 'PGSQL',
|
||||
type: ExtensionNodeType.Server
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ExtensionNodeType, TreeItem } from 'azdata';
|
||||
import { ExtensionNodeType, TreeItem, Account } from 'azdata';
|
||||
import { TreeItemCollapsibleState, ExtensionContext } from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
const localize = nls.loadMessageBundle();
|
||||
@@ -28,7 +28,7 @@ export class PostgresServerTreeDataProvider extends ResourceTreeDataProviderBase
|
||||
}
|
||||
|
||||
|
||||
protected getTreeItemForResource(databaseServer: azureResource.AzureResourceDatabaseServer): TreeItem {
|
||||
protected getTreeItemForResource(databaseServer: azureResource.AzureResourceDatabaseServer, account: Account): TreeItem {
|
||||
return {
|
||||
id: `databaseServer_${databaseServer.id ? databaseServer.id : databaseServer.name}`,
|
||||
label: databaseServer.name,
|
||||
@@ -45,7 +45,7 @@ export class PostgresServerTreeDataProvider extends ResourceTreeDataProviderBase
|
||||
databaseName: databaseServer.defaultDatabaseName,
|
||||
userName: `${databaseServer.loginName}@${databaseServer.fullName}`,
|
||||
password: '',
|
||||
authenticationType: 'SqlLogin',
|
||||
authenticationType: 'AzureMFA',
|
||||
savePassword: true,
|
||||
groupFullName: '',
|
||||
groupId: '',
|
||||
@@ -54,7 +54,8 @@ export class PostgresServerTreeDataProvider extends ResourceTreeDataProviderBase
|
||||
options: {
|
||||
// Set default for SSL or will get error complaining about it not being set correctly
|
||||
'sslmode': 'require'
|
||||
}
|
||||
},
|
||||
azureAccount: account.key.accountId
|
||||
},
|
||||
childProvider: 'PGSQL',
|
||||
type: ExtensionNodeType.Server
|
||||
|
||||
@@ -36,7 +36,7 @@ export abstract class ResourceTreeDataProviderBase<T extends azureResource.Azure
|
||||
account: element.account,
|
||||
subscription: element.subscription,
|
||||
tenantId: element.tenantId,
|
||||
treeItem: this.getTreeItemForResource(resource)
|
||||
treeItem: this.getTreeItemForResource(resource, element.account)
|
||||
}).sort((a, b) => a.treeItem.label.localeCompare(b.treeItem.label));
|
||||
} catch (error) {
|
||||
console.log(AzureResourceErrorMessageUtil.getErrorMessage(error));
|
||||
@@ -48,11 +48,11 @@ export abstract class ResourceTreeDataProviderBase<T extends azureResource.Azure
|
||||
const tokens = await this._apiWrapper.getSecurityToken(element.account, azdata.AzureResource.ResourceManagement);
|
||||
const credential = new msRest.TokenCredentials(tokens[element.tenantId].token, tokens[element.tenantId].tokenType);
|
||||
|
||||
const resources: T[] = await this._resourceService.getResources(element.subscription, credential) || <T[]>[];
|
||||
const resources: T[] = await this._resourceService.getResources(element.subscription, credential, element.account) || <T[]>[];
|
||||
return resources;
|
||||
}
|
||||
|
||||
protected abstract getTreeItemForResource(resource: T): azdata.TreeItem;
|
||||
protected abstract getTreeItemForResource(resource: T, account: azdata.Account): azdata.TreeItem;
|
||||
|
||||
protected abstract createContainerNode(): azureResource.IAzureResourceNode;
|
||||
}
|
||||
@@ -121,9 +121,9 @@ export abstract class ResourceServiceBase<T extends GraphData, U extends azureRe
|
||||
*/
|
||||
protected abstract get query(): string;
|
||||
|
||||
public async getResources(subscription: azureResource.AzureResourceSubscription, credential: msRest.ServiceClientCredentials): Promise<U[]> {
|
||||
public async getResources(subscription: azureResource.AzureResourceSubscription, credential: msRest.ServiceClientCredentials, account: azdata.Account): Promise<U[]> {
|
||||
const convertedResources: U[] = [];
|
||||
const resourceClient = new ResourceGraphClient(credential);
|
||||
const resourceClient = new ResourceGraphClient(credential, { baseUri: account.properties.providerSettings.settings.armResource.endpoint });
|
||||
let graphResources = await queryGraphResources<T>(resourceClient, subscription.id, this.query);
|
||||
let ids = new Set<string>();
|
||||
graphResources.forEach((res) => {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ExtensionNodeType, TreeItem } from 'azdata';
|
||||
import { ExtensionNodeType, TreeItem, Account } from 'azdata';
|
||||
import { TreeItemCollapsibleState, ExtensionContext } from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
const localize = nls.loadMessageBundle();
|
||||
@@ -28,7 +28,7 @@ export class SqlInstanceTreeDataProvider extends ResourceTreeDataProviderBase<az
|
||||
}
|
||||
|
||||
|
||||
protected getTreeItemForResource(databaseServer: azureResource.AzureResourceDatabaseServer): TreeItem {
|
||||
protected getTreeItemForResource(databaseServer: azureResource.AzureResourceDatabaseServer, account: Account): TreeItem {
|
||||
return {
|
||||
id: `sqlInstance_${databaseServer.id ? databaseServer.id : databaseServer.name}`,
|
||||
label: databaseServer.name,
|
||||
@@ -45,13 +45,14 @@ export class SqlInstanceTreeDataProvider extends ResourceTreeDataProviderBase<az
|
||||
databaseName: databaseServer.defaultDatabaseName,
|
||||
userName: databaseServer.loginName,
|
||||
password: '',
|
||||
authenticationType: 'SqlLogin',
|
||||
authenticationType: 'AzureMFA',
|
||||
savePassword: true,
|
||||
groupFullName: '',
|
||||
groupId: '',
|
||||
providerName: 'MSSQL',
|
||||
saveProfile: false,
|
||||
options: {}
|
||||
options: {},
|
||||
azureAccount: account.key.accountId
|
||||
},
|
||||
childProvider: 'MSSQL',
|
||||
type: ExtensionNodeType.Server
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ExtensionNodeType, TreeItem } from 'azdata';
|
||||
import { ExtensionNodeType, TreeItem, Account } from 'azdata';
|
||||
import { TreeItemCollapsibleState, ExtensionContext } from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
const localize = nls.loadMessageBundle();
|
||||
@@ -28,7 +28,7 @@ export class SqlInstanceArcTreeDataProvider extends ResourceTreeDataProviderBase
|
||||
}
|
||||
|
||||
|
||||
protected getTreeItemForResource(databaseServer: azureResource.AzureResourceDatabaseServer): TreeItem {
|
||||
protected getTreeItemForResource(databaseServer: azureResource.AzureResourceDatabaseServer, account: Account): TreeItem {
|
||||
return {
|
||||
id: `sqlInstance_${databaseServer.id ? databaseServer.id : databaseServer.name}`,
|
||||
label: databaseServer.name,
|
||||
@@ -45,13 +45,14 @@ export class SqlInstanceArcTreeDataProvider extends ResourceTreeDataProviderBase
|
||||
databaseName: databaseServer.defaultDatabaseName,
|
||||
userName: databaseServer.loginName,
|
||||
password: '',
|
||||
authenticationType: 'SqlLogin',
|
||||
authenticationType: 'AzureMFA',
|
||||
savePassword: true,
|
||||
groupFullName: '',
|
||||
groupId: '',
|
||||
providerName: 'MSSQL',
|
||||
saveProfile: false,
|
||||
options: {}
|
||||
options: {},
|
||||
azureAccount: account.key.accountId
|
||||
},
|
||||
childProvider: 'MSSQL',
|
||||
type: ExtensionNodeType.Server
|
||||
|
||||
@@ -4,17 +4,16 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Account } from 'azdata';
|
||||
import { ServiceClientCredentials } from '@azure/ms-rest-js';
|
||||
import { SubscriptionClient } from '@azure/arm-subscriptions';
|
||||
|
||||
import { azureResource } from '../azure-resource';
|
||||
import { IAzureResourceSubscriptionService } from '../interfaces';
|
||||
|
||||
export class AzureResourceSubscriptionService implements IAzureResourceSubscriptionService {
|
||||
public async getSubscriptions(account: Account, credential: ServiceClientCredentials): Promise<azureResource.AzureResourceSubscription[]> {
|
||||
public async getSubscriptions(account: Account, credential: any): Promise<azureResource.AzureResourceSubscription[]> {
|
||||
const subscriptions: azureResource.AzureResourceSubscription[] = [];
|
||||
|
||||
const subClient = new SubscriptionClient(credential);
|
||||
const subClient = new SubscriptionClient(credential, { baseUri: account.properties.providerSettings.settings.armResource.endpoint });
|
||||
const subs = await subClient.subscriptions.list();
|
||||
subs.forEach((sub) => subscriptions.push({
|
||||
id: sub.subscriptionId,
|
||||
|
||||
@@ -2,29 +2,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 request from 'request';
|
||||
import { SubscriptionClient } from '@azure/arm-subscriptions';
|
||||
|
||||
import { azureResource } from '../azure-resource';
|
||||
import { IAzureResourceTenantService } from '../interfaces';
|
||||
import { Account } from 'azdata';
|
||||
|
||||
export class AzureResourceTenantService implements IAzureResourceTenantService {
|
||||
public async getTenantId(subscription: azureResource.AzureResourceSubscription): Promise<string> {
|
||||
const requestPromisified = new Promise<string>((resolve, reject) => {
|
||||
const url = `https://management.azure.com/subscriptions/${subscription.id}?api-version=2014-04-01`;
|
||||
request(url, function (error, response, body) {
|
||||
if (response.statusCode === 401) {
|
||||
const tenantIdRegEx = /authorization_uri="https:\/\/login\.windows\.net\/([0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12})"/;
|
||||
const teantIdString = response.headers['www-authenticate'];
|
||||
if (tenantIdRegEx.test(teantIdString)) {
|
||||
resolve(tenantIdRegEx.exec(teantIdString)[1]);
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
public async getTenantId(subscription: azureResource.AzureResourceSubscription, account: Account, credentials: any): Promise<string> {
|
||||
const subClient = new SubscriptionClient(credentials, { baseUri: account.properties.providerSettings.settings.armResource.endpoint });
|
||||
|
||||
return await requestPromisified;
|
||||
const result = await subClient.subscriptions.get(subscription.id);
|
||||
return result.subscriptionId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,11 +42,10 @@ export class AzureResourceAccountTreeNode extends AzureResourceContainerTreeNode
|
||||
public async getChildren(): Promise<TreeNode[]> {
|
||||
try {
|
||||
let subscriptions: azureResource.AzureResourceSubscription[] = [];
|
||||
const tokens = await this.appContext.apiWrapper.getSecurityToken(this.account, AzureResource.ResourceManagement);
|
||||
|
||||
if (this._isClearingCache) {
|
||||
try {
|
||||
const tokens = await this.appContext.apiWrapper.getSecurityToken(this.account, AzureResource.ResourceManagement);
|
||||
|
||||
for (const tenant of this.account.properties.tenants) {
|
||||
const token = tokens[tenant.id].token;
|
||||
const tokenType = tokens[tenant.id].tokenType;
|
||||
@@ -56,7 +55,6 @@ export class AzureResourceAccountTreeNode extends AzureResourceContainerTreeNode
|
||||
} catch (error) {
|
||||
throw new AzureResourceCredentialError(localize('azure.resource.tree.accountTreeNode.credentialError', "Failed to get credential for account {0}. Please refresh the account.", this.account.key.accountId), error);
|
||||
}
|
||||
|
||||
this.updateCache<azureResource.AzureResourceSubscription[]>(subscriptions);
|
||||
|
||||
this._isClearingCache = false;
|
||||
@@ -82,7 +80,8 @@ export class AzureResourceAccountTreeNode extends AzureResourceContainerTreeNode
|
||||
return [AzureResourceMessageTreeNode.create(AzureResourceAccountTreeNode.noSubscriptionsLabel, this)];
|
||||
} else {
|
||||
let subTreeNodes = await Promise.all(subscriptions.map(async (subscription) => {
|
||||
const tenantId = await this._tenantService.getTenantId(subscription);
|
||||
const token = tokens[subscription.id];
|
||||
const tenantId = await this._tenantService.getTenantId(subscription, this.account, new TokenCredentials(token.token, token.tokenType));
|
||||
|
||||
return new AzureResourceSubscriptionTreeNode(this.account, subscription, tenantId, this.appContext, this.treeChangeHandler, this);
|
||||
}));
|
||||
|
||||
@@ -37,13 +37,16 @@ export class AzureResourceTreeProvider implements TreeDataProvider<TreeNode>, IA
|
||||
private hookAccountService(appContext: AppContext): void {
|
||||
this.accountService = appContext.getService<IAzureResourceAccountService>(AzureResourceServiceNames.accountService);
|
||||
if (this.accountService) {
|
||||
this.accountService.onDidChangeAccounts((e: azdata.DidChangeAccountsParams) => {
|
||||
this.accountService.onDidChangeAccounts(async (e: azdata.DidChangeAccountsParams) => {
|
||||
// This event sends it per provider, we need to make sure we get all the azure related accounts
|
||||
let accounts = await this.accountService.getAccounts();
|
||||
accounts = accounts.filter(a => a.key.providerId.startsWith('azure'));
|
||||
// the onDidChangeAccounts event will trigger in many cases where the accounts didn't actually change
|
||||
// the notifyNodeChanged event triggers a refresh which triggers a getChildren which can trigger this callback
|
||||
// this below check short-circuits the infinite callback loop
|
||||
this.setSystemInitialized();
|
||||
if (!equals(e.accounts, this.accounts)) {
|
||||
this.accounts = e.accounts;
|
||||
if (!equals(accounts, this.accounts)) {
|
||||
this.accounts = accounts;
|
||||
this.notifyNodeChanged(undefined);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -104,7 +104,7 @@ describe('AzureResourceDatabaseTreeDataProvider.getChildren', function (): void
|
||||
mockExtensionContext = TypeMoq.Mock.ofType<vscode.ExtensionContext>();
|
||||
|
||||
mockApiWrapper.setup((o) => o.getSecurityToken(mockAccount, azdata.AzureResource.ResourceManagement)).returns(() => Promise.resolve(mockTokens));
|
||||
mockDatabaseService.setup((o) => o.getResources(mockSubscription, TypeMoq.It.isAny())).returns(() => Promise.resolve(mockDatabases));
|
||||
mockDatabaseService.setup((o) => o.getResources(mockSubscription, TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve(mockDatabases));
|
||||
mockExtensionContext.setup((o) => o.asAbsolutePath(TypeMoq.It.isAnyString())).returns(() => TypeMoq.It.isAnyString());
|
||||
});
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ describe('AzureResourceDatabaseServerTreeDataProvider.getChildren', function ():
|
||||
mockExtensionContext = TypeMoq.Mock.ofType<vscode.ExtensionContext>();
|
||||
|
||||
mockApiWrapper.setup((o) => o.getSecurityToken(mockAccount, azdata.AzureResource.ResourceManagement)).returns(() => Promise.resolve(mockTokens));
|
||||
mockDatabaseServerService.setup((o) => o.getResources(mockSubscription, TypeMoq.It.isAny())).returns(() => Promise.resolve(mockDatabaseServers));
|
||||
mockDatabaseServerService.setup((o) => o.getResources(mockSubscription, TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve(mockDatabaseServers));
|
||||
mockExtensionContext.setup((o) => o.asAbsolutePath(TypeMoq.It.isAnyString())).returns(() => TypeMoq.It.isAnyString());
|
||||
});
|
||||
|
||||
|
||||
@@ -76,10 +76,13 @@ const mockSubscriptions = [mockSubscription1, mockSubscription2];
|
||||
const mockFilteredSubscriptions = [mockSubscription1];
|
||||
|
||||
const mockTokens: { [key: string]: any } = {};
|
||||
mockTokens[mockTenantId] = {
|
||||
token: 'mock_token',
|
||||
tokenType: 'Bearer'
|
||||
};
|
||||
|
||||
[mockSubscription1.id, mockSubscription2.id, mockTenantId].forEach(s => {
|
||||
mockTokens[s] = {
|
||||
token: 'mock_token',
|
||||
tokenType: 'Bearer'
|
||||
};
|
||||
});
|
||||
|
||||
const mockCredential = new TokenCredentials(mockTokens[mockTenantId].token, mockTokens[mockTenantId].tokenType);
|
||||
|
||||
@@ -108,7 +111,7 @@ describe('AzureResourceAccountTreeNode.info', function (): void {
|
||||
mockCacheService.setup((o) => o.generateKey(TypeMoq.It.isAnyString())).returns(() => generateGuid());
|
||||
mockCacheService.setup((o) => o.get(TypeMoq.It.isAnyString())).returns(() => mockSubscriptionCache);
|
||||
mockCacheService.setup((o) => o.update(TypeMoq.It.isAnyString(), TypeMoq.It.isAny())).returns(() => mockSubscriptionCache = mockSubscriptions);
|
||||
mockTenantService.setup((o) => o.getTenantId(TypeMoq.It.isAny())).returns(() => Promise.resolve(mockTenantId));
|
||||
mockTenantService.setup((o) => o.getTenantId(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve(mockTenantId));
|
||||
});
|
||||
|
||||
it('Should be correct when created.', async function (): Promise<void> {
|
||||
@@ -196,7 +199,7 @@ describe('AzureResourceAccountTreeNode.getChildren', function (): void {
|
||||
mockCacheService.setup((o) => o.generateKey(TypeMoq.It.isAnyString())).returns(() => generateGuid());
|
||||
mockCacheService.setup((o) => o.get(TypeMoq.It.isAnyString())).returns(() => mockSubscriptionCache);
|
||||
mockCacheService.setup((o) => o.update(TypeMoq.It.isAnyString(), TypeMoq.It.isAny())).returns(() => mockSubscriptionCache = mockSubscriptions);
|
||||
mockTenantService.setup((o) => o.getTenantId(TypeMoq.It.isAny())).returns(() => Promise.resolve(mockTenantId));
|
||||
mockTenantService.setup((o) => o.getTenantId(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve(mockTenantId));
|
||||
});
|
||||
|
||||
it('Should load subscriptions from scratch and update cache when it is clearing cache.', async function (): Promise<void> {
|
||||
@@ -207,7 +210,6 @@ describe('AzureResourceAccountTreeNode.getChildren', function (): void {
|
||||
|
||||
const children = await accountTreeNode.getChildren();
|
||||
|
||||
mockApiWrapper.verify((o) => o.getSecurityToken(mockAccount, azdata.AzureResource.ResourceManagement), TypeMoq.Times.once());
|
||||
mockSubscriptionService.verify((o) => o.getSubscriptions(mockAccount, mockCredential), TypeMoq.Times.once());
|
||||
mockCacheService.verify((o) => o.get(TypeMoq.It.isAnyString()), TypeMoq.Times.exactly(0));
|
||||
mockCacheService.verify((o) => o.update(TypeMoq.It.isAnyString(), TypeMoq.It.isAny()), TypeMoq.Times.once());
|
||||
@@ -242,7 +244,7 @@ describe('AzureResourceAccountTreeNode.getChildren', function (): void {
|
||||
await accountTreeNode.getChildren();
|
||||
const children = await accountTreeNode.getChildren();
|
||||
|
||||
mockApiWrapper.verify((o) => o.getSecurityToken(mockAccount, azdata.AzureResource.ResourceManagement), TypeMoq.Times.once());
|
||||
|
||||
mockSubscriptionService.verify((o) => o.getSubscriptions(mockAccount, mockCredential), TypeMoq.Times.once());
|
||||
mockCacheService.verify((o) => o.get(TypeMoq.It.isAnyString()), TypeMoq.Times.once());
|
||||
mockCacheService.verify((o) => o.update(TypeMoq.It.isAnyString(), TypeMoq.It.isAny()), TypeMoq.Times.once());
|
||||
@@ -331,11 +333,11 @@ describe('AzureResourceAccountTreeNode.clearCache', function (): void {
|
||||
mockAppContext.registerService<IAzureResourceSubscriptionFilterService>(AzureResourceServiceNames.subscriptionFilterService, mockSubscriptionFilterService.object);
|
||||
mockAppContext.registerService<IAzureResourceTenantService>(AzureResourceServiceNames.tenantService, mockTenantService.object);
|
||||
|
||||
mockApiWrapper.setup((o) => o.getSecurityToken(mockAccount, azdata.AzureResource.ResourceManagement)).returns(() => Promise.resolve(mockTokens));
|
||||
mockApiWrapper.setup((o,) => o.getSecurityToken(mockAccount, azdata.AzureResource.ResourceManagement)).returns(() => Promise.resolve(mockTokens));
|
||||
mockCacheService.setup((o) => o.generateKey(TypeMoq.It.isAnyString())).returns(() => generateGuid());
|
||||
mockCacheService.setup((o) => o.get(TypeMoq.It.isAnyString())).returns(() => mockSubscriptionCache);
|
||||
mockCacheService.setup((o) => o.update(TypeMoq.It.isAnyString(), TypeMoq.It.isAny())).returns(() => mockSubscriptionCache = mockSubscriptions);
|
||||
mockTenantService.setup((o) => o.getTenantId(TypeMoq.It.isAny())).returns(() => Promise.resolve(mockTenantId));
|
||||
mockTenantService.setup((o) => o.getTenantId(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve(mockTenantId));
|
||||
});
|
||||
|
||||
it('Should clear cache.', async function (): Promise<void> {
|
||||
|
||||
@@ -11,16 +11,16 @@
|
||||
"@azure/ms-rest-js" "^1.8.1"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@azure/arm-subscriptions@1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@azure/arm-subscriptions/-/arm-subscriptions-1.0.0.tgz#ab65a5cd4d8b8c878ff6621428f29137b84eb1d6"
|
||||
integrity sha512-DoZFcF+ePkGhrxQ4X/LxBoWipqpkZIt9g+itXJ4HaQNExn0hNO27Cs6kNZYpIdCs5Zu+2DbjRs2i8OqG3QbE9w==
|
||||
"@azure/arm-subscriptions@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@azure/arm-subscriptions/-/arm-subscriptions-2.0.0.tgz#4202740b7f65a9d0f16f7903579a615f5de45a92"
|
||||
integrity sha512-+ys2glK5YgwZ9KhwWblfAQIPABtiB5OdKEpPOpcvr7B5ygYTwZuSUNObX9MRu/MyiRo1zDlUvlxHltBphq/bLQ==
|
||||
dependencies:
|
||||
"@azure/ms-rest-azure-js" "^1.1.0"
|
||||
"@azure/ms-rest-js" "^1.1.0"
|
||||
tslib "^1.9.3"
|
||||
"@azure/ms-rest-azure-js" "^2.0.1"
|
||||
"@azure/ms-rest-js" "^2.0.4"
|
||||
tslib "^1.10.0"
|
||||
|
||||
"@azure/ms-rest-azure-js@^1.1.0", "@azure/ms-rest-azure-js@^1.3.2":
|
||||
"@azure/ms-rest-azure-js@^1.3.2":
|
||||
version "1.3.8"
|
||||
resolved "https://registry.yarnpkg.com/@azure/ms-rest-azure-js/-/ms-rest-azure-js-1.3.8.tgz#96b518223d3baa2496b2981bc07288b3d887486e"
|
||||
integrity sha512-AHLfDTCyIH6wBK6+CpImI6sc9mLZ17ZgUrTx3Rhwv+3Mb3Z73BxormkarfR6Stb6scrBYitxJ27FXyndXlGAYg==
|
||||
@@ -28,7 +28,15 @@
|
||||
"@azure/ms-rest-js" "^1.8.10"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@azure/ms-rest-js@^1.1.0", "@azure/ms-rest-js@^1.8.1", "@azure/ms-rest-js@^1.8.10":
|
||||
"@azure/ms-rest-azure-js@^2.0.1":
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@azure/ms-rest-azure-js/-/ms-rest-azure-js-2.0.1.tgz#fa1b38f039b3ee48a9e086a88c8a5b5b7776491c"
|
||||
integrity sha512-5e+A710O7gRFISoV4KI/ZyLQbKmjXxQZ1L8Z/sx7jSUQqmswjTnN4yyIZxs5JzfLVkobU0rXxbi5/LVzaI8QXQ==
|
||||
dependencies:
|
||||
"@azure/ms-rest-js" "^2.0.4"
|
||||
tslib "^1.10.0"
|
||||
|
||||
"@azure/ms-rest-js@^1.8.1", "@azure/ms-rest-js@^1.8.10":
|
||||
version "1.8.13"
|
||||
resolved "https://registry.yarnpkg.com/@azure/ms-rest-js/-/ms-rest-js-1.8.13.tgz#ed0cd86469697378cd39d79d5589e877a3bc87a6"
|
||||
integrity sha512-jAa6Y2XrvwbEqkaEXDHK+ReNo0WnCPS+LgQ1dRAJUUNxK4CghF5u+SXsVtPENritilVE7FVteqsLOtlhTk+haA==
|
||||
@@ -42,6 +50,22 @@
|
||||
uuid "^3.2.1"
|
||||
xml2js "^0.4.19"
|
||||
|
||||
"@azure/ms-rest-js@^2.0.4":
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@azure/ms-rest-js/-/ms-rest-js-2.0.5.tgz#7ac1043b7b8c99bb8c5b09ada96b858b02db8e75"
|
||||
integrity sha512-zj9/JOSsbaJleZz9k9RXKJMBPA2NBUgsus5iZxGlhK+pDeb8M2ps+lkKhJSwLnlTUj5CvrcN3PZDF2b2nSYCQQ==
|
||||
dependencies:
|
||||
"@types/node-fetch" "^2.3.7"
|
||||
"@types/tunnel" "0.0.1"
|
||||
abort-controller "^3.0.0"
|
||||
form-data "^2.5.0"
|
||||
node-fetch "^2.6.0"
|
||||
tough-cookie "^3.0.1"
|
||||
tslib "^1.10.0"
|
||||
tunnel "0.0.6"
|
||||
uuid "^3.3.2"
|
||||
xml2js "^0.4.19"
|
||||
|
||||
"@types/caseless@*":
|
||||
version "0.12.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.2.tgz#f65d3d6389e01eeb458bd54dc8f52b95a9463bc8"
|
||||
@@ -59,6 +83,14 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.5.tgz#8a4accfc403c124a0bafe8a9fc61a05ec1032073"
|
||||
integrity sha512-lAVp+Kj54ui/vLUFxsJTMtWvZraZxum3w3Nwkble2dNuV5VnPA+Mi2oGX9XYJAaIvZi3tn3cbjS/qcJXRb6Bww==
|
||||
|
||||
"@types/node-fetch@^2.3.7":
|
||||
version "2.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.5.tgz#cd264e20a81f4600a6c52864d38e7fef72485e92"
|
||||
integrity sha512-IWwjsyYjGw+em3xTvWVQi5MgYKbRs0du57klfTaZkv/B24AEQ/p/IopNeqIYNy3EsfHOpg8ieQSDomPcsYMHpA==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
form-data "^3.0.0"
|
||||
|
||||
"@types/node@*":
|
||||
version "10.14.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.4.tgz#1c586b991457cbb58fef51bc4e0cfcfa347714b5"
|
||||
@@ -96,6 +128,13 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/tunnel@0.0.1":
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/tunnel/-/tunnel-0.0.1.tgz#0d72774768b73df26f25df9184273a42da72b19c"
|
||||
integrity sha512-AOqu6bQu5MSWwYvehMXLukFHnupHrpZ8nvgae5Ggie9UwzDR1CCwoXgSSWNZJuyOlCdfdsWMA5F2LlmvyoTv8A==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
abbrev@1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
|
||||
@@ -106,6 +145,13 @@ abbrev@1.0.x:
|
||||
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135"
|
||||
integrity sha1-kbR5JYinc4wl813W9jdSovh3YTU=
|
||||
|
||||
abort-controller@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392"
|
||||
integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==
|
||||
dependencies:
|
||||
event-target-shim "^5.0.0"
|
||||
|
||||
adal-node@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/adal-node/-/adal-node-0.2.1.tgz#19e401bd579977448c1a77ce0e5b4c9accdc334e"
|
||||
@@ -306,6 +352,13 @@ combined-stream@^1.0.6, combined-stream@~1.0.6:
|
||||
dependencies:
|
||||
delayed-stream "~1.0.0"
|
||||
|
||||
combined-stream@^1.0.8:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
|
||||
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
|
||||
dependencies:
|
||||
delayed-stream "~1.0.0"
|
||||
|
||||
commander@2.15.1:
|
||||
version "2.15.1"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f"
|
||||
@@ -465,6 +518,11 @@ esutils@^2.0.2:
|
||||
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
|
||||
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
|
||||
|
||||
event-target-shim@^5.0.0:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789"
|
||||
integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==
|
||||
|
||||
extend-shallow@^1.1.2:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-1.1.4.tgz#19d6bf94dfc09d76ba711f39b872d21ff4dd9071"
|
||||
@@ -514,7 +572,7 @@ forever-agent@~0.6.1:
|
||||
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
|
||||
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
|
||||
|
||||
form-data@^2.3.2:
|
||||
form-data@^2.3.2, form-data@^2.5.0:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4"
|
||||
integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==
|
||||
@@ -523,6 +581,15 @@ form-data@^2.3.2:
|
||||
combined-stream "^1.0.6"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
form-data@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682"
|
||||
integrity sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==
|
||||
dependencies:
|
||||
asynckit "^0.4.0"
|
||||
combined-stream "^1.0.8"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
form-data@~2.3.2:
|
||||
version "2.3.3"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
|
||||
@@ -662,6 +729,11 @@ inherits@2, inherits@~2.0.1:
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
||||
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
|
||||
|
||||
ip-regex@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9"
|
||||
integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=
|
||||
|
||||
is-buffer@^2.0.2:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623"
|
||||
@@ -905,6 +977,11 @@ neo-async@^2.6.0:
|
||||
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c"
|
||||
integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==
|
||||
|
||||
node-fetch@^2.6.0:
|
||||
version "2.6.0"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd"
|
||||
integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==
|
||||
|
||||
nopt@3.x:
|
||||
version "3.0.6"
|
||||
resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9"
|
||||
@@ -1235,6 +1312,15 @@ tough-cookie@^2.4.3:
|
||||
psl "^1.1.28"
|
||||
punycode "^2.1.1"
|
||||
|
||||
tough-cookie@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-3.0.1.tgz#9df4f57e739c26930a018184887f4adb7dca73b2"
|
||||
integrity sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==
|
||||
dependencies:
|
||||
ip-regex "^2.1.0"
|
||||
psl "^1.1.28"
|
||||
punycode "^2.1.1"
|
||||
|
||||
tough-cookie@~2.4.3:
|
||||
version "2.4.3"
|
||||
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781"
|
||||
@@ -1243,6 +1329,11 @@ tough-cookie@~2.4.3:
|
||||
psl "^1.1.24"
|
||||
punycode "^1.4.1"
|
||||
|
||||
tslib@^1.10.0:
|
||||
version "1.11.1"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35"
|
||||
integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==
|
||||
|
||||
tslib@^1.9.2, tslib@^1.9.3:
|
||||
version "1.10.0"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"
|
||||
|
||||
Reference in New Issue
Block a user