@microsoft/vscode-azext-azureauth 5.1.1 → 6.0.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/README.md +9 -79
- package/dist/cjs/src/contracts/AzureAccount.js +7 -0
- package/dist/cjs/src/contracts/AzureSubscriptionProviderRequestOptions.js +48 -0
- package/dist/cjs/src/index.js +13 -10
- package/dist/cjs/src/providers/AzureDevOpsSubscriptionProvider.js +178 -0
- package/dist/cjs/src/providers/AzureSubscriptionProviderBase.js +393 -0
- package/dist/cjs/src/providers/VSCodeAzureSubscriptionProvider.js +269 -0
- package/dist/cjs/src/utils/Limiter.js +41 -0
- package/dist/cjs/src/{NotSignedInError.js → utils/NotSignedInError.js} +3 -2
- package/dist/cjs/src/utils/configuredAzureEnv.js +14 -16
- package/dist/cjs/src/utils/dedupeSubscriptions.js +27 -0
- package/dist/cjs/src/utils/getMetricsForTelemetry.js +47 -0
- package/dist/cjs/src/{getSessionFromVSCode.js → utils/getSessionFromVSCode.js} +5 -2
- package/dist/cjs/src/utils/getSignalForToken.js +29 -0
- package/dist/cjs/src/utils/map/CaselessMap.js +71 -0
- package/dist/cjs/src/utils/map/TwoKeyCaselessMap.js +194 -0
- package/dist/cjs/src/utils/screen.js +62 -0
- package/dist/cjs/src/{signInToTenant.js → utils/signInToTenant.js} +15 -13
- package/dist/cjs/src/utils/tryGetTokenExpiration.js +25 -0
- package/dist/esm/src/contracts/AzureAccount.d.ts +5 -0
- package/dist/esm/src/contracts/AzureAccount.js +6 -0
- package/dist/esm/src/{AzureAuthentication.d.ts → contracts/AzureAuthentication.d.ts} +1 -1
- package/dist/esm/src/{AzureSubscription.d.ts → contracts/AzureSubscription.d.ts} +4 -4
- package/dist/esm/src/contracts/AzureSubscriptionProvider.d.ts +112 -0
- package/dist/esm/src/contracts/AzureSubscriptionProviderRequestOptions.d.ts +103 -0
- package/dist/esm/src/contracts/AzureSubscriptionProviderRequestOptions.js +44 -0
- package/dist/esm/src/contracts/AzureTenant.d.ts +15 -0
- package/dist/esm/src/index.d.ts +13 -10
- package/dist/esm/src/index.js +13 -10
- package/dist/esm/src/providers/AzureDevOpsSubscriptionProvider.d.ts +68 -0
- package/dist/esm/src/providers/AzureDevOpsSubscriptionProvider.js +140 -0
- package/dist/esm/src/providers/AzureSubscriptionProviderBase.d.ts +74 -0
- package/dist/esm/src/providers/AzureSubscriptionProviderBase.js +356 -0
- package/dist/esm/src/providers/VSCodeAzureSubscriptionProvider.d.ts +70 -0
- package/dist/esm/src/providers/VSCodeAzureSubscriptionProvider.js +232 -0
- package/dist/esm/src/utils/Limiter.d.ts +9 -0
- package/dist/esm/src/utils/Limiter.js +37 -0
- package/dist/esm/src/{NotSignedInError.d.ts → utils/NotSignedInError.d.ts} +2 -2
- package/dist/esm/src/{NotSignedInError.js → utils/NotSignedInError.js} +3 -2
- package/dist/esm/src/utils/configuredAzureEnv.d.ts +7 -4
- package/dist/esm/src/utils/configuredAzureEnv.js +14 -16
- package/dist/esm/src/utils/dedupeSubscriptions.d.ts +14 -0
- package/dist/esm/src/utils/dedupeSubscriptions.js +24 -0
- package/dist/esm/src/utils/getMetricsForTelemetry.d.ts +32 -0
- package/dist/esm/src/utils/getMetricsForTelemetry.js +44 -0
- package/dist/esm/src/{getSessionFromVSCode.js → utils/getSessionFromVSCode.js} +5 -2
- package/dist/esm/src/utils/getSignalForToken.d.ts +7 -0
- package/dist/esm/src/utils/getSignalForToken.js +26 -0
- package/dist/esm/src/utils/map/CaselessMap.d.ts +28 -0
- package/dist/esm/src/utils/map/CaselessMap.js +67 -0
- package/dist/esm/src/utils/map/TwoKeyCaselessMap.d.ts +49 -0
- package/dist/esm/src/utils/map/TwoKeyCaselessMap.js +190 -0
- package/dist/esm/src/utils/screen.d.ts +9 -0
- package/dist/esm/src/utils/screen.js +59 -0
- package/dist/esm/src/utils/signInToTenant.d.ts +7 -0
- package/dist/esm/src/{signInToTenant.js → utils/signInToTenant.js} +16 -14
- package/dist/esm/src/utils/tryGetTokenExpiration.d.ts +2 -0
- package/dist/esm/src/utils/tryGetTokenExpiration.js +22 -0
- package/package.json +33 -23
- package/AzureFederatedCredentialsGuide.md +0 -174
- package/dist/cjs/src/AzureDevOpsSubscriptionProvider.js +0 -215
- package/dist/cjs/src/VSCodeAzureSubscriptionProvider.js +0 -395
- package/dist/cjs/src/utils/getUnauthenticatedTenants.js +0 -23
- package/dist/cjs/src/utils/isGetSubscriptionsFilter.js +0 -27
- package/dist/esm/src/AzureDevOpsSubscriptionProvider.d.ts +0 -68
- package/dist/esm/src/AzureDevOpsSubscriptionProvider.js +0 -210
- package/dist/esm/src/AzureSubscriptionProvider.d.ts +0 -82
- package/dist/esm/src/AzureTenant.d.ts +0 -5
- package/dist/esm/src/VSCodeAzureSubscriptionProvider.d.ts +0 -116
- package/dist/esm/src/VSCodeAzureSubscriptionProvider.js +0 -358
- package/dist/esm/src/signInToTenant.d.ts +0 -6
- package/dist/esm/src/utils/getUnauthenticatedTenants.d.ts +0 -9
- package/dist/esm/src/utils/getUnauthenticatedTenants.js +0 -20
- package/dist/esm/src/utils/isGetSubscriptionsFilter.d.ts +0 -14
- package/dist/esm/src/utils/isGetSubscriptionsFilter.js +0 -23
- /package/dist/cjs/src/{AzureAuthentication.js → contracts/AzureAuthentication.js} +0 -0
- /package/dist/cjs/src/{AzureSubscription.js → contracts/AzureSubscription.js} +0 -0
- /package/dist/cjs/src/{AzureSubscriptionProvider.js → contracts/AzureSubscriptionProvider.js} +0 -0
- /package/dist/cjs/src/{AzureTenant.js → contracts/AzureTenant.js} +0 -0
- /package/dist/esm/src/{AzureAuthentication.js → contracts/AzureAuthentication.js} +0 -0
- /package/dist/esm/src/{AzureSubscription.js → contracts/AzureSubscription.js} +0 -0
- /package/dist/esm/src/{AzureSubscriptionProvider.js → contracts/AzureSubscriptionProvider.js} +0 -0
- /package/dist/esm/src/{AzureTenant.js → contracts/AzureTenant.js} +0 -0
- /package/dist/esm/src/{getSessionFromVSCode.d.ts → utils/getSessionFromVSCode.d.ts} +0 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
export class Limiter {
|
|
6
|
+
runningPromises;
|
|
7
|
+
maxDegreeOfParalellism;
|
|
8
|
+
outstandingPromises;
|
|
9
|
+
constructor(maxDegreeOfParalellism) {
|
|
10
|
+
this.maxDegreeOfParalellism = maxDegreeOfParalellism;
|
|
11
|
+
this.outstandingPromises = [];
|
|
12
|
+
this.runningPromises = 0;
|
|
13
|
+
}
|
|
14
|
+
queue(factory) {
|
|
15
|
+
return new Promise((c, e) => {
|
|
16
|
+
this.outstandingPromises.push({ factory, c, e });
|
|
17
|
+
this.consume();
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
consume() {
|
|
21
|
+
while (this.outstandingPromises.length && this.runningPromises < this.maxDegreeOfParalellism) {
|
|
22
|
+
const iLimitedTask = this.outstandingPromises.shift();
|
|
23
|
+
this.runningPromises++;
|
|
24
|
+
const promise = iLimitedTask.factory();
|
|
25
|
+
promise.then(iLimitedTask.c, iLimitedTask.e);
|
|
26
|
+
promise.then(() => this.consumed(), () => this.consumed());
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
consumed() {
|
|
30
|
+
this.runningPromises--;
|
|
31
|
+
if (this.outstandingPromises.length > 0) {
|
|
32
|
+
this.consume();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
|
37
|
+
//# sourceMappingURL=Limiter.js.map
|
|
@@ -6,10 +6,10 @@ export declare class NotSignedInError extends Error {
|
|
|
6
6
|
constructor();
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
|
-
* Tests if an object is a
|
|
9
|
+
* Tests if an object is a {@link NotSignedInError}. This should be used instead of `instanceof`.
|
|
10
10
|
*
|
|
11
11
|
* @param error The object to test
|
|
12
12
|
*
|
|
13
|
-
* @returns True if the object is a NotSignedInError, false otherwise
|
|
13
|
+
* @returns True if the object is a {@link NotSignedInError}, false otherwise
|
|
14
14
|
*/
|
|
15
15
|
export declare function isNotSignedInError(error: unknown): error is NotSignedInError;
|
|
@@ -13,13 +13,14 @@ export class NotSignedInError extends Error {
|
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
|
-
* Tests if an object is a
|
|
16
|
+
* Tests if an object is a {@link NotSignedInError}. This should be used instead of `instanceof`.
|
|
17
17
|
*
|
|
18
18
|
* @param error The object to test
|
|
19
19
|
*
|
|
20
|
-
* @returns True if the object is a NotSignedInError, false otherwise
|
|
20
|
+
* @returns True if the object is a {@link NotSignedInError}, false otherwise
|
|
21
21
|
*/
|
|
22
22
|
export function isNotSignedInError(error) {
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-boolean-literal-compare, @typescript-eslint/no-unnecessary-condition
|
|
23
24
|
return !!error && typeof error === 'object' && error.isNotSignedInError === true;
|
|
24
25
|
}
|
|
25
26
|
//# sourceMappingURL=NotSignedInError.js.map
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import * as azureEnv from '@azure/ms-rest-azure-env';
|
|
2
2
|
import * as vscode from 'vscode';
|
|
3
|
+
declare class ExtendedEnvironment extends azureEnv.Environment {
|
|
4
|
+
readonly isCustomCloud: boolean;
|
|
5
|
+
constructor(parameters: azureEnv.EnvironmentParameters, isCustomCloud: boolean);
|
|
6
|
+
}
|
|
3
7
|
/**
|
|
4
8
|
* Gets the configured Azure environment.
|
|
5
9
|
*
|
|
6
10
|
* @returns The configured Azure environment from the settings in the built-in authentication provider extension
|
|
7
11
|
*/
|
|
8
|
-
export declare function getConfiguredAzureEnv():
|
|
9
|
-
isCustomCloud: boolean;
|
|
10
|
-
};
|
|
12
|
+
export declare function getConfiguredAzureEnv(): ExtendedEnvironment;
|
|
11
13
|
/**
|
|
12
14
|
* Sets the configured Azure cloud.
|
|
13
15
|
*
|
|
@@ -16,9 +18,10 @@ export declare function getConfiguredAzureEnv(): azureEnv.Environment & {
|
|
|
16
18
|
*
|
|
17
19
|
* @param target (Optional) The configuration target to use, by default {@link vscode.ConfigurationTarget.Global}.
|
|
18
20
|
*/
|
|
19
|
-
export declare function setConfiguredAzureEnv(cloud: 'AzureCloud' | 'ChinaCloud' | 'USGovernment' | undefined | azureEnv.EnvironmentParameters, target?: vscode.ConfigurationTarget): Promise<void>;
|
|
21
|
+
export declare function setConfiguredAzureEnv(cloud: 'AzureCloud' | 'ChinaCloud' | 'USGovernment' | undefined | null | azureEnv.EnvironmentParameters, target?: vscode.ConfigurationTarget): Promise<void>;
|
|
20
22
|
/**
|
|
21
23
|
* Gets the ID of the authentication provider configured to be used
|
|
22
24
|
* @returns The provider ID to use, either `'microsoft'` or `'microsoft-sovereign-cloud'`
|
|
23
25
|
*/
|
|
24
26
|
export declare function getConfiguredAuthProviderId(): string;
|
|
27
|
+
export {};
|
|
@@ -14,6 +14,16 @@ var CloudEnvironmentSettingValue;
|
|
|
14
14
|
CloudEnvironmentSettingValue["USGovernment"] = "USGovernment";
|
|
15
15
|
CloudEnvironmentSettingValue["Custom"] = "custom";
|
|
16
16
|
})(CloudEnvironmentSettingValue || (CloudEnvironmentSettingValue = {}));
|
|
17
|
+
class ExtendedEnvironment extends azureEnv.Environment {
|
|
18
|
+
isCustomCloud;
|
|
19
|
+
constructor(parameters, isCustomCloud) {
|
|
20
|
+
super(parameters);
|
|
21
|
+
this.isCustomCloud = isCustomCloud;
|
|
22
|
+
// The Environment constructor only copies required properties. Copy all remaining
|
|
23
|
+
// optional properties (e.g. storageEndpointSuffix, keyVaultDnsSuffix) from the source.
|
|
24
|
+
Object.assign(this, parameters);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
17
27
|
/**
|
|
18
28
|
* Gets the configured Azure environment.
|
|
19
29
|
*
|
|
@@ -23,31 +33,19 @@ export function getConfiguredAzureEnv() {
|
|
|
23
33
|
const authProviderConfig = vscode.workspace.getConfiguration(CustomCloudConfigurationSection);
|
|
24
34
|
const environmentSettingValue = authProviderConfig.get(CloudEnvironmentSettingName);
|
|
25
35
|
if (environmentSettingValue === CloudEnvironmentSettingValue.ChinaCloud) {
|
|
26
|
-
return
|
|
27
|
-
...azureEnv.Environment.ChinaCloud,
|
|
28
|
-
isCustomCloud: false,
|
|
29
|
-
};
|
|
36
|
+
return new ExtendedEnvironment(azureEnv.Environment.ChinaCloud, false);
|
|
30
37
|
}
|
|
31
38
|
else if (environmentSettingValue === CloudEnvironmentSettingValue.USGovernment) {
|
|
32
|
-
return
|
|
33
|
-
...azureEnv.Environment.USGovernment,
|
|
34
|
-
isCustomCloud: false,
|
|
35
|
-
};
|
|
39
|
+
return new ExtendedEnvironment(azureEnv.Environment.USGovernment, false);
|
|
36
40
|
}
|
|
37
41
|
else if (environmentSettingValue === CloudEnvironmentSettingValue.Custom) {
|
|
38
42
|
const customCloud = authProviderConfig.get(CustomEnvironmentSettingName);
|
|
39
43
|
if (customCloud) {
|
|
40
|
-
return
|
|
41
|
-
...new azureEnv.Environment(customCloud),
|
|
42
|
-
isCustomCloud: true,
|
|
43
|
-
};
|
|
44
|
+
return new ExtendedEnvironment(customCloud, true);
|
|
44
45
|
}
|
|
45
46
|
throw new Error(vscode.l10n.t('The custom cloud choice is not configured. Please configure the setting `{0}.{1}`.', CustomCloudConfigurationSection, CustomEnvironmentSettingName));
|
|
46
47
|
}
|
|
47
|
-
return
|
|
48
|
-
...azureEnv.Environment.get(azureEnv.Environment.AzureCloud.name),
|
|
49
|
-
isCustomCloud: false,
|
|
50
|
-
};
|
|
48
|
+
return new ExtendedEnvironment(azureEnv.Environment.AzureCloud, false);
|
|
51
49
|
}
|
|
52
50
|
/**
|
|
53
51
|
* Sets the configured Azure cloud.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { AzureSubscription } from '../contracts/AzureSubscription';
|
|
2
|
+
/**
|
|
3
|
+
* Deduplicates (and sorts) a list of Azure subscriptions.
|
|
4
|
+
* In short, the behavior is that the combination of account + tenant + subscriptionId will be unique.
|
|
5
|
+
* The last appearance of any duplicates will be kept. The resulting list is sorted by subscription name.
|
|
6
|
+
*
|
|
7
|
+
* Please note:
|
|
8
|
+
* - The same tenant may appear under different accounts.
|
|
9
|
+
* - The same subscriptionId may appear under different accounts that share the same tenant.
|
|
10
|
+
* - Rarely, the same subscriptionId may also appear under different accounts + different tenants.
|
|
11
|
+
*
|
|
12
|
+
* @param subscriptions The list of subscriptions to deduplicate
|
|
13
|
+
*/
|
|
14
|
+
export declare function dedupeSubscriptions(subscriptions: AzureSubscription[]): AzureSubscription[];
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
/**
|
|
6
|
+
* Deduplicates (and sorts) a list of Azure subscriptions.
|
|
7
|
+
* In short, the behavior is that the combination of account + tenant + subscriptionId will be unique.
|
|
8
|
+
* The last appearance of any duplicates will be kept. The resulting list is sorted by subscription name.
|
|
9
|
+
*
|
|
10
|
+
* Please note:
|
|
11
|
+
* - The same tenant may appear under different accounts.
|
|
12
|
+
* - The same subscriptionId may appear under different accounts that share the same tenant.
|
|
13
|
+
* - Rarely, the same subscriptionId may also appear under different accounts + different tenants.
|
|
14
|
+
*
|
|
15
|
+
* @param subscriptions The list of subscriptions to deduplicate
|
|
16
|
+
*/
|
|
17
|
+
export function dedupeSubscriptions(subscriptions) {
|
|
18
|
+
const deduped = new Map();
|
|
19
|
+
for (const sub of subscriptions) {
|
|
20
|
+
deduped.set(`${sub.account.id}/${sub.tenantId}/${sub.subscriptionId}`, sub);
|
|
21
|
+
}
|
|
22
|
+
return Array.from(deduped.values()).sort((a, b) => a.name.localeCompare(b.name));
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=dedupeSubscriptions.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { AzureSubscriptionProvider } from '../contracts/AzureSubscriptionProvider';
|
|
2
|
+
/**
|
|
3
|
+
* Telemetry metrics about Azure authentication.
|
|
4
|
+
*/
|
|
5
|
+
export interface AzureAuthTelemetryMetrics {
|
|
6
|
+
/**
|
|
7
|
+
* The total number of accounts. This number is always accurate.
|
|
8
|
+
*/
|
|
9
|
+
totalAccounts: number;
|
|
10
|
+
/**
|
|
11
|
+
* The total number of tenants. This number only includes tenants for signed-in accounts.
|
|
12
|
+
*/
|
|
13
|
+
visibleTenants: number;
|
|
14
|
+
/**
|
|
15
|
+
* The total number of subscriptions, but limited to querying the first 10 account+tenants.
|
|
16
|
+
*/
|
|
17
|
+
visibleSubscriptions: number;
|
|
18
|
+
/**
|
|
19
|
+
* A JSON-stringified list of subscription IDs (up to 25).
|
|
20
|
+
*/
|
|
21
|
+
subscriptionIdList: string;
|
|
22
|
+
/**
|
|
23
|
+
* Whether the subscription ID list is incomplete (i.e. there were more than 25 subscriptions).
|
|
24
|
+
*/
|
|
25
|
+
subscriptionIdListIsIncomplete: boolean;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Gets telemetry metrics about accounts, tenants, and subscriptions.
|
|
29
|
+
* @param subscriptionProvider The subscription provider to use to get the metrics.
|
|
30
|
+
* @throws A NotSignedInError if no accounts are signed in.
|
|
31
|
+
*/
|
|
32
|
+
export declare function getMetricsForTelemetry(subscriptionProvider: AzureSubscriptionProvider): Promise<AzureAuthTelemetryMetrics>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
/**
|
|
6
|
+
* Gets telemetry metrics about accounts, tenants, and subscriptions.
|
|
7
|
+
* @param subscriptionProvider The subscription provider to use to get the metrics.
|
|
8
|
+
* @throws A NotSignedInError if no accounts are signed in.
|
|
9
|
+
*/
|
|
10
|
+
export async function getMetricsForTelemetry(subscriptionProvider) {
|
|
11
|
+
// Get the total number of accounts (requires no web requests)
|
|
12
|
+
// Errors are deliberately not caught here, so if no accounts are signed in, this will throw
|
|
13
|
+
const accounts = await subscriptionProvider.getAccounts();
|
|
14
|
+
const numAccounts = accounts.length;
|
|
15
|
+
// Get the total number of tenants across all accounts (requires one web request per account, which is reasonable)
|
|
16
|
+
let numTenants = 0;
|
|
17
|
+
for (const account of accounts) {
|
|
18
|
+
try {
|
|
19
|
+
const tenants = await subscriptionProvider.getTenantsForAccount(account);
|
|
20
|
+
numTenants += tenants.length;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
continue; // If we can't get tenants for an account, skip it instead of throwing
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// Get as many subscriptions as we can (requires one web request per account+tenant)
|
|
27
|
+
// This is limited to the first 10 account+tenants, thus a max of 10 web requests
|
|
28
|
+
// Errors are deliberately not caught here; none are expected since at least one account is signed in
|
|
29
|
+
const subscriptions = await subscriptionProvider.getAvailableSubscriptions();
|
|
30
|
+
const numSubscriptions = subscriptions.length;
|
|
31
|
+
// Get subscription IDs (up to 25)
|
|
32
|
+
const subscriptionSet = new Set();
|
|
33
|
+
subscriptions.slice(0, 25).forEach(sub => {
|
|
34
|
+
subscriptionSet.add(sub.subscriptionId);
|
|
35
|
+
});
|
|
36
|
+
return {
|
|
37
|
+
totalAccounts: numAccounts,
|
|
38
|
+
visibleTenants: numTenants,
|
|
39
|
+
visibleSubscriptions: numSubscriptions,
|
|
40
|
+
subscriptionIdList: JSON.stringify(Array.from(subscriptionSet)),
|
|
41
|
+
subscriptionIdListIsIncomplete: subscriptions.length > 25,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=getMetricsForTelemetry.js.map
|
|
@@ -3,13 +3,16 @@
|
|
|
3
3
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
5
|
import * as vscode from "vscode";
|
|
6
|
-
import { getConfiguredAuthProviderId, getConfiguredAzureEnv } from "./
|
|
7
|
-
import { isAuthenticationWwwAuthenticateRequest } from "./
|
|
6
|
+
import { getConfiguredAuthProviderId, getConfiguredAzureEnv } from "./configuredAzureEnv";
|
|
7
|
+
import { isAuthenticationWwwAuthenticateRequest } from "./isAuthenticationWwwAuthenticateRequest";
|
|
8
8
|
function ensureEndingSlash(value) {
|
|
9
9
|
return value.endsWith('/') ? value : `${value}/`;
|
|
10
10
|
}
|
|
11
11
|
function getResourceScopes(scopes) {
|
|
12
12
|
if (scopes === undefined || scopes === "" || scopes.length === 0) {
|
|
13
|
+
// For https://github.com/microsoft/vscode-azurefunctions/issues/3913, the default scope was changed from
|
|
14
|
+
// ~'https://management.azure.com/.default' (`AzureEnv.resourceManagerEndpointUrl`) to
|
|
15
|
+
// ~'https://management.core.windows.net/.default' (`AzureEnv.managementEndpointUrl`)
|
|
13
16
|
scopes = ensureEndingSlash(getConfiguredAzureEnv().managementEndpointUrl);
|
|
14
17
|
}
|
|
15
18
|
const arrScopes = (Array.isArray(scopes) ? scopes : [scopes])
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type * as vscode from 'vscode';
|
|
2
|
+
/**
|
|
3
|
+
* Gets an AbortSignal that is tied to the given {@link vscode.CancellationToken}.
|
|
4
|
+
* @param token The token to convert
|
|
5
|
+
* @returns The {@link AbortSignal} or undefined if no token is provided
|
|
6
|
+
*/
|
|
7
|
+
export declare function getSignalForToken(token: vscode.CancellationToken | undefined): AbortSignal | undefined;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
/**
|
|
6
|
+
* Gets an AbortSignal that is tied to the given {@link vscode.CancellationToken}.
|
|
7
|
+
* @param token The token to convert
|
|
8
|
+
* @returns The {@link AbortSignal} or undefined if no token is provided
|
|
9
|
+
*/
|
|
10
|
+
export function getSignalForToken(token) {
|
|
11
|
+
if (!token) {
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
const controller = new AbortController();
|
|
15
|
+
if (token.isCancellationRequested) {
|
|
16
|
+
controller.abort();
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
const disposable = token.onCancellationRequested(() => {
|
|
20
|
+
disposable.dispose();
|
|
21
|
+
controller.abort();
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
return controller.signal;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=getSignalForToken.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export declare class CaselessMap<V> implements Map<string, V> {
|
|
2
|
+
#private;
|
|
3
|
+
clear(): void;
|
|
4
|
+
delete(key: string): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* @important Keys returned **match original case**!
|
|
7
|
+
*/
|
|
8
|
+
forEach(callbackfn: (value: V, key: string, map: Map<string, V>) => void, thisArg?: any): void;
|
|
9
|
+
get(key: string): V | undefined;
|
|
10
|
+
has(key: string): boolean;
|
|
11
|
+
set(key: string, value: V): this;
|
|
12
|
+
get size(): number;
|
|
13
|
+
/**
|
|
14
|
+
* @important Keys returned **match original case**!
|
|
15
|
+
*/
|
|
16
|
+
entries(): MapIterator<[string, V]>;
|
|
17
|
+
/**
|
|
18
|
+
* @important Keys returned **match original case**!
|
|
19
|
+
*/
|
|
20
|
+
keys(): MapIterator<string>;
|
|
21
|
+
values(): MapIterator<V>;
|
|
22
|
+
/**
|
|
23
|
+
* @important Keys returned **match original case**!
|
|
24
|
+
*/
|
|
25
|
+
[Symbol.iterator](): MapIterator<[string, V]>;
|
|
26
|
+
readonly [Symbol.toStringTag]: string;
|
|
27
|
+
private normalizeKey;
|
|
28
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
export class CaselessMap {
|
|
6
|
+
#map = new Map();
|
|
7
|
+
clear() {
|
|
8
|
+
this.#map.clear();
|
|
9
|
+
}
|
|
10
|
+
delete(key) {
|
|
11
|
+
return this.#map.delete(this.normalizeKey(key));
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* @important Keys returned **match original case**!
|
|
15
|
+
*/
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Must exactly match interface
|
|
17
|
+
forEach(callbackfn, thisArg) {
|
|
18
|
+
this.#map.forEach(entry => {
|
|
19
|
+
callbackfn.call(thisArg, entry.value, entry.originalKey, this);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
get(key) {
|
|
23
|
+
return this.#map.get(this.normalizeKey(key))?.value;
|
|
24
|
+
}
|
|
25
|
+
has(key) {
|
|
26
|
+
return this.#map.has(this.normalizeKey(key));
|
|
27
|
+
}
|
|
28
|
+
set(key, value) {
|
|
29
|
+
this.#map.set(this.normalizeKey(key), { originalKey: key, value });
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
32
|
+
get size() {
|
|
33
|
+
return this.#map.size;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* @important Keys returned **match original case**!
|
|
37
|
+
*/
|
|
38
|
+
*entries() {
|
|
39
|
+
for (const [, entry] of this.#map) {
|
|
40
|
+
yield [entry.originalKey, entry.value];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* @important Keys returned **match original case**!
|
|
45
|
+
*/
|
|
46
|
+
*keys() {
|
|
47
|
+
for (const [, entry] of this.#map) {
|
|
48
|
+
yield entry.originalKey;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
*values() {
|
|
52
|
+
for (const [, entry] of this.#map) {
|
|
53
|
+
yield entry.value;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* @important Keys returned **match original case**!
|
|
58
|
+
*/
|
|
59
|
+
[Symbol.iterator]() {
|
|
60
|
+
return this.entries();
|
|
61
|
+
}
|
|
62
|
+
[Symbol.toStringTag] = 'CaselessMap';
|
|
63
|
+
normalizeKey(key) {
|
|
64
|
+
return key.toLowerCase();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=CaselessMap.js.map
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export declare class TwoKeyCaselessMap<V> implements Iterable<[string, string, V]> {
|
|
2
|
+
#private;
|
|
3
|
+
private readonly testMode;
|
|
4
|
+
constructor(testMode?: boolean);
|
|
5
|
+
clear(): void;
|
|
6
|
+
clearByFirstKey(key1: string): void;
|
|
7
|
+
clearBySecondKey(key2: string): void;
|
|
8
|
+
delete(key1: string, key2: string): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* @important Keys returned **match original case**!
|
|
11
|
+
*/
|
|
12
|
+
forEach(callbackfn: (value: V, key1: string, key2: string) => void, thisArg?: any): void;
|
|
13
|
+
get(key1: string, key2: string): V | undefined;
|
|
14
|
+
has(key1: string, key2: string): boolean;
|
|
15
|
+
set(key1: string, key2: string, value: V): this;
|
|
16
|
+
get size(): number;
|
|
17
|
+
/**
|
|
18
|
+
* @important Keys returned **match original case**!
|
|
19
|
+
*/
|
|
20
|
+
entriesByFirstKey(key1: string): MapIterator<[string, V]>;
|
|
21
|
+
/**
|
|
22
|
+
* @important Keys returned **match original case**!
|
|
23
|
+
*/
|
|
24
|
+
entriesBySecondKey(key2: string): MapIterator<[string, V]>;
|
|
25
|
+
/**
|
|
26
|
+
* @important Keys returned **match original case**!
|
|
27
|
+
*/
|
|
28
|
+
entries(): MapIterator<[string, string, V]>;
|
|
29
|
+
/**
|
|
30
|
+
* @important Keys returned **match original case**!
|
|
31
|
+
*/
|
|
32
|
+
keysByFirstKey(key1: string): MapIterator<string>;
|
|
33
|
+
/**
|
|
34
|
+
* @important Keys returned **match original case**!
|
|
35
|
+
*/
|
|
36
|
+
keysBySecondKey(key2: string): MapIterator<string>;
|
|
37
|
+
/**
|
|
38
|
+
* @important Keys returned **match original case**!
|
|
39
|
+
*/
|
|
40
|
+
keys(): MapIterator<[string, string]>;
|
|
41
|
+
valuesByFirstKey(key1: string): MapIterator<V>;
|
|
42
|
+
valuesBySecondKey(key2: string): MapIterator<V>;
|
|
43
|
+
values(): MapIterator<V>;
|
|
44
|
+
/**
|
|
45
|
+
* @important Keys returned **match original case**!
|
|
46
|
+
*/
|
|
47
|
+
[Symbol.iterator](): MapIterator<[string, string, V]>;
|
|
48
|
+
readonly [Symbol.toStringTag]: string;
|
|
49
|
+
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import { CaselessMap } from './CaselessMap';
|
|
6
|
+
export class TwoKeyCaselessMap {
|
|
7
|
+
testMode;
|
|
8
|
+
#map1 = new CaselessMap(); // First map has key1 as the outer key and key2 as the inner key
|
|
9
|
+
#map2 = new CaselessMap(); // Second key map has key2 as the outer key and key1 as the inner key
|
|
10
|
+
#size = 0;
|
|
11
|
+
constructor(testMode = false) {
|
|
12
|
+
this.testMode = testMode;
|
|
13
|
+
}
|
|
14
|
+
clear() {
|
|
15
|
+
this.#map1.clear();
|
|
16
|
+
this.#map2.clear();
|
|
17
|
+
this.#size = 0;
|
|
18
|
+
}
|
|
19
|
+
clearByFirstKey(key1) {
|
|
20
|
+
const innerMap1 = this.#map1.get(key1);
|
|
21
|
+
if (!innerMap1) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
// Decrement size before any deletions
|
|
25
|
+
this.#size -= innerMap1.size;
|
|
26
|
+
// Remove all entries from #map2 that reference this key1
|
|
27
|
+
innerMap1.forEach((_, key2) => {
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- The existence of innerMap1 ensures this is non-null
|
|
29
|
+
const innerMap2 = this.#map2.get(key2);
|
|
30
|
+
innerMap2.delete(key1);
|
|
31
|
+
if (innerMap2.size === 0) {
|
|
32
|
+
this.#map2.delete(key2);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
// Remove the entire inner map from #map1
|
|
36
|
+
this.#map1.delete(key1);
|
|
37
|
+
}
|
|
38
|
+
clearBySecondKey(key2) {
|
|
39
|
+
const innerMap2 = this.#map2.get(key2);
|
|
40
|
+
if (!innerMap2) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
// Decrement size before any deletions
|
|
44
|
+
this.#size -= innerMap2.size;
|
|
45
|
+
// Remove all entries from #map1 that reference this key2
|
|
46
|
+
innerMap2.forEach((_, key1) => {
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- The existence of innerMap2 ensures this is non-null
|
|
48
|
+
const innerMap1 = this.#map1.get(key1);
|
|
49
|
+
innerMap1.delete(key2);
|
|
50
|
+
if (innerMap1.size === 0) {
|
|
51
|
+
this.#map1.delete(key1);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
// Remove the entire inner map from #map2
|
|
55
|
+
this.#map2.delete(key2);
|
|
56
|
+
}
|
|
57
|
+
delete(key1, key2) {
|
|
58
|
+
if (!this.has(key1, key2)) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- The has() check above ensures non-null
|
|
62
|
+
const innerMap1 = this.#map1.get(key1);
|
|
63
|
+
innerMap1.delete(key2);
|
|
64
|
+
if (innerMap1.size === 0) {
|
|
65
|
+
this.#map1.delete(key1);
|
|
66
|
+
}
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- The has() check above ensures non-null
|
|
68
|
+
const innerMap2 = this.#map2.get(key2);
|
|
69
|
+
innerMap2.delete(key1);
|
|
70
|
+
if (innerMap2.size === 0) {
|
|
71
|
+
this.#map2.delete(key2);
|
|
72
|
+
}
|
|
73
|
+
this.#size--;
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* @important Keys returned **match original case**!
|
|
78
|
+
*/
|
|
79
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Must exactly match interface
|
|
80
|
+
forEach(callbackfn, thisArg) {
|
|
81
|
+
this.#map1.forEach((innerMap1, key1) => {
|
|
82
|
+
innerMap1.forEach((value, key2) => {
|
|
83
|
+
callbackfn.call(thisArg, value, key1, key2);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
get(key1, key2) {
|
|
88
|
+
return this.#map1.get(key1)?.get(key2);
|
|
89
|
+
}
|
|
90
|
+
has(key1, key2) {
|
|
91
|
+
const result1 = this.#map1.get(key1)?.has(key2);
|
|
92
|
+
if (this.testMode) {
|
|
93
|
+
const result2 = this.#map2.get(key2)?.has(key1);
|
|
94
|
+
if (!!result1 !== !!result2) {
|
|
95
|
+
throw new Error('Inconsistent state in TwoKeyCaselessMap');
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return result1 ?? false;
|
|
99
|
+
}
|
|
100
|
+
set(key1, key2, value) {
|
|
101
|
+
const alreadyHadEntry = this.has(key1, key2);
|
|
102
|
+
let innerMap1 = this.#map1.get(key1);
|
|
103
|
+
if (!innerMap1) {
|
|
104
|
+
innerMap1 = new CaselessMap();
|
|
105
|
+
this.#map1.set(key1, innerMap1);
|
|
106
|
+
}
|
|
107
|
+
innerMap1.set(key2, value);
|
|
108
|
+
let innerMap2 = this.#map2.get(key2);
|
|
109
|
+
if (!innerMap2) {
|
|
110
|
+
innerMap2 = new CaselessMap();
|
|
111
|
+
this.#map2.set(key2, innerMap2);
|
|
112
|
+
}
|
|
113
|
+
innerMap2.set(key1, value);
|
|
114
|
+
if (!alreadyHadEntry) {
|
|
115
|
+
this.#size++;
|
|
116
|
+
}
|
|
117
|
+
return this;
|
|
118
|
+
}
|
|
119
|
+
get size() {
|
|
120
|
+
return this.#size;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* @important Keys returned **match original case**!
|
|
124
|
+
*/
|
|
125
|
+
entriesByFirstKey(key1) {
|
|
126
|
+
return this.#map1.get(key1)?.entries() ?? emptyIterator();
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* @important Keys returned **match original case**!
|
|
130
|
+
*/
|
|
131
|
+
entriesBySecondKey(key2) {
|
|
132
|
+
return this.#map2.get(key2)?.entries() ?? emptyIterator();
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* @important Keys returned **match original case**!
|
|
136
|
+
*/
|
|
137
|
+
*entries() {
|
|
138
|
+
for (const [key1, innerMap1] of this.#map1) {
|
|
139
|
+
for (const [key2, value] of innerMap1) {
|
|
140
|
+
yield [key1, key2, value];
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* @important Keys returned **match original case**!
|
|
146
|
+
*/
|
|
147
|
+
keysByFirstKey(key1) {
|
|
148
|
+
return this.#map1.get(key1)?.keys() ?? emptyIterator();
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* @important Keys returned **match original case**!
|
|
152
|
+
*/
|
|
153
|
+
keysBySecondKey(key2) {
|
|
154
|
+
return this.#map2.get(key2)?.keys() ?? emptyIterator();
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* @important Keys returned **match original case**!
|
|
158
|
+
*/
|
|
159
|
+
*keys() {
|
|
160
|
+
for (const [key1, innerMap1] of this.#map1) {
|
|
161
|
+
for (const key2 of innerMap1.keys()) {
|
|
162
|
+
yield [key1, key2];
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
valuesByFirstKey(key1) {
|
|
167
|
+
return this.#map1.get(key1)?.values() ?? emptyIterator();
|
|
168
|
+
}
|
|
169
|
+
valuesBySecondKey(key2) {
|
|
170
|
+
return this.#map2.get(key2)?.values() ?? emptyIterator();
|
|
171
|
+
}
|
|
172
|
+
*values() {
|
|
173
|
+
for (const innerMap1 of this.#map1.values()) {
|
|
174
|
+
for (const value of innerMap1.values()) {
|
|
175
|
+
yield value;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* @important Keys returned **match original case**!
|
|
181
|
+
*/
|
|
182
|
+
[Symbol.iterator]() {
|
|
183
|
+
return this.entries();
|
|
184
|
+
}
|
|
185
|
+
[Symbol.toStringTag] = 'TwoKeyCaselessMap';
|
|
186
|
+
}
|
|
187
|
+
function emptyIterator() {
|
|
188
|
+
return [][Symbol.iterator]();
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=TwoKeyCaselessMap.js.map
|