diff --git a/ui/index.d.ts b/ui/index.d.ts index 29f1fc3116..d807e1a262 100644 --- a/ui/index.d.ts +++ b/ui/index.d.ts @@ -4,11 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import type { SubscriptionModels } from '@azure/arm-resources-subscriptions'; -import type { ExtendedLocation } from '@azure/arm-resources/esm/models'; -import type { ResourceManagementModels } from '@azure/arm-resources'; -import type { StorageManagementModels } from '@azure/arm-storage'; +import type { ExtendedLocation, ResourceGroup } from '@azure/arm-resources'; +import type * as coreClient from '@azure/core-client'; +import type { PagedAsyncIterableIterator } from "@azure/core-paging"; import type { Environment } from '@azure/ms-rest-azure-env'; import type { HttpOperationResponse, RequestPrepareOptions, ServiceClient } from '@azure/ms-rest-js'; +import type { StorageAccount } from '@azure/arm-storage'; import { Disposable, Event, ExtensionContext, FileChangeEvent, FileChangeType, FileStat, FileSystemProvider, FileType, InputBoxOptions, MarkdownString, MessageItem, MessageOptions, OpenDialogOptions, OutputChannel, Progress, QuickPickItem, QuickPickOptions, TextDocumentShowOptions, ThemeIcon, TreeDataProvider, TreeItem, Uri } from 'vscode'; import { TargetPopulation } from 'vscode-tas-client'; import { AzureExtensionApi, AzureExtensionApiProvider } from './api'; @@ -139,12 +140,19 @@ export abstract class SubscriptionTreeItemBase extends AzExtParentTreeItem { constructor(parent: AzExtParentTreeItem, subscription: ISubscriptionContext); } +/** + * Loose type to use for T1 and T2 versions of "@azure/ms-rest-js". The Azure Account extension returns + * credentials that will satisfy both T1 and T2 requirements + */ +export type AzExtServiceClientCredentials = AzExtServiceClientCredentialsT1 & AzExtServiceClientCredentialsT2; + /** * Loose interface to allow for the use of different versions of "@azure/ms-rest-js" * There's several cases where we don't control which "credentials" interface gets used, causing build errors even though the functionality itself seems to be compatible * For example: https://github.com/Azure/azure-sdk-for-js/issues/10045 + * Used specifically for T1 Azure SDKs */ -export interface AzExtServiceClientCredentials { +export interface AzExtServiceClientCredentialsT1 { /** * Signs a request with the Authentication header. * @@ -154,6 +162,25 @@ export interface AzExtServiceClientCredentials { signRequest(webResource: any): Promise; } +/** + * Loose interface to allow for the use of different versions of "@azure/ms-rest-js" + * Used specifically for T2 Azure SDKs + */ +export interface AzExtServiceClientCredentialsT2 { + + /** + * Gets the token provided by this credential. + * + * This method is called automatically by Azure SDK client libraries. You may call this method + * directly, but you must also handle token caching and token refreshing. + * + * @param scopes - The list of scopes for which the token will have access. + * @param options - The options used to configure any requests this + * TokenCredential implementation might make. + */ + getToken(scopes?: string | string[], options?: any): Promise; +} + /** * Information specific to the Subscription */ @@ -1162,13 +1189,13 @@ export interface IResourceGroupWizardContext extends ILocationWizardContext, IRe * If an existing resource group is picked, this value will be defined after `ResourceGroupListStep.prompt` occurs * If a new resource group is picked, this value will be defined after the `execute` phase of the 'create' subwizard */ - resourceGroup?: ResourceManagementModels.ResourceGroup; + resourceGroup?: ResourceGroup; /** * The task used to get existing resource groups. * By specifying this in the context, we can ensure that Azure is only queried once for the entire wizard */ - resourceGroupsTask?: Promise; + resourceGroupsTask?: Promise; newResourceGroupName?: string; @@ -1185,7 +1212,7 @@ export declare class ResourceGroupListStep(wizardContext: T): Promise; + public static getResourceGroups(wizardContext: T): Promise; /** * Checks existing resource groups in the wizard's subscription to see if the name is available. @@ -1218,7 +1245,7 @@ export interface IStorageAccountWizardContext extends IResourceGroupWizardContex * If an existing storage account is picked, this value will be defined after `StorageAccountListStep.prompt` occurs * If a new storage account is picked, this value will be defined after the `execute` phase of the 'create' subwizard */ - storageAccount?: StorageManagementModels.StorageAccount; + storageAccount?: StorageAccount; newStorageAccountName?: string; } @@ -1409,7 +1436,11 @@ export interface IMinimumServiceClientOptions { requestPolicyFactories?: any[] | ((defaultRequestPolicyFactories: any[]) => (void | any[])); } -export type AzExtGenericClientInfo = AzExtServiceClientCredentials | { credentials: AzExtServiceClientCredentials; environment: Environment; } | undefined; +/** + * Credential type to be used for creating generic http rest clients + */ +export type AzExtGenericCredentials = AzExtServiceClientCredentialsT1 | AzExtServiceClientCredentialsT2 | AzExtServiceClientCredentials; +export type AzExtGenericClientInfo = AzExtGenericCredentials | { credentials: AzExtGenericCredentials; environment: Environment; } | undefined; /** * Creates a generic http rest client (i.e. for non-Azure calls or for Azure calls that the available sdks don't support), ensuring best practices are followed. For example: @@ -1650,3 +1681,7 @@ export declare namespace AzExtFsExtra { export function writeFile(resource: Uri | string, contents: string): Promise; export function pathExists(resource: Uri | string): Promise; } + +export declare namespace uiUtils { + export function listAllIterator(list: (options?: coreClient.OperationOptions) => PagedAsyncIterableIterator, options?: coreClient.OperationOptions) +} diff --git a/ui/package-lock.json b/ui/package-lock.json index eb7f3c6672..d068f25a90 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -1,18 +1,18 @@ { "name": "vscode-azureextensionui", - "version": "0.49.3", + "version": "0.50.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "vscode-azureextensionui", - "version": "0.49.3", + "version": "0.50.0", "license": "MIT", "dependencies": { - "@azure/arm-resources": "^4.0.0", + "@azure/arm-resources": "^5.0.0", "@azure/arm-resources-profile-2020-09-01-hybrid": "^1.0.0", "@azure/arm-resources-subscriptions": "^1.0.0", - "@azure/arm-storage": "^15.0.0", + "@azure/arm-storage": "^17.0.0", "@azure/arm-storage-profile-2020-09-01-hybrid": "^1.0.0", "@azure/ms-rest-azure-env": "^2.0.0", "@azure/ms-rest-js": "^2.2.1", @@ -64,14 +64,20 @@ "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" }, "node_modules/@azure/arm-resources": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@azure/arm-resources/-/arm-resources-4.2.2.tgz", - "integrity": "sha512-Oic1OcEwgex3X1KkhP9UM/E/taIaS9oID7PL/CZ8knD7qtVNSRvTxP3uvD3ZpH9NYBYXngJsX5xyRu66iFN+rA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@azure/arm-resources/-/arm-resources-5.0.0.tgz", + "integrity": "sha512-eKICohMfZcW0d7tsxS29Z/bznvfUMCu+khJhDJfDlKLqfmqBun6CxBTDeWcNbuckDRxalJ0gZJp5hidC9+Msiw==", "dependencies": { - "@azure/core-auth": "^1.1.4", - "@azure/ms-rest-azure-js": "^2.1.0", - "@azure/ms-rest-js": "^2.2.0", - "tslib": "^1.10.0" + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-client": "^1.0.0", + "@azure/core-lro": "^2.2.0", + "@azure/core-paging": "^1.2.0", + "@azure/core-rest-pipeline": "^1.1.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" } }, "node_modules/@azure/arm-resources-profile-2020-09-01-hybrid": { @@ -96,14 +102,26 @@ "tslib": "^1.10.0" } }, + "node_modules/@azure/arm-resources/node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + }, "node_modules/@azure/arm-storage": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/@azure/arm-storage/-/arm-storage-15.3.0.tgz", - "integrity": "sha512-djN2tmEzvC4lNEYrk3PAXkf5ZcebGDqPZSh/cYKOleumD4eop5EpMX8d5LcSO/9EcSfPpCzutRg0AleMaPQ9Mg==", + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@azure/arm-storage/-/arm-storage-17.0.0.tgz", + "integrity": "sha512-WS9eT3/vDQ7a1z/8K5BkPhoAi0ilo94yCSws4KyWq6UIA3RaXBDpYYAlN0TOxad9rPeOnWXWcB9gLw3DmjZ4wg==", "dependencies": { - "@azure/ms-rest-azure-js": "^2.0.1", - "@azure/ms-rest-js": "^2.0.4", - "tslib": "^1.10.0" + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-client": "^1.0.0", + "@azure/core-lro": "^2.2.0", + "@azure/core-paging": "^1.2.0", + "@azure/core-rest-pipeline": "^1.1.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" } }, "node_modules/@azure/arm-storage-profile-2020-09-01-hybrid": { @@ -117,6 +135,16 @@ "tslib": "^1.10.0" } }, + "node_modules/@azure/arm-storage/node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + }, + "node_modules/@azure/core-asynciterator-polyfill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@azure/core-asynciterator-polyfill/-/core-asynciterator-polyfill-1.0.0.tgz", + "integrity": "sha512-kmv8CGrPfN9SwMwrkiBK9VTQYxdFQEGe0BmQk+M8io56P9KNzpAxcWE/1fxJj7uouwN4kXF0BHW8DNlgx+wtCg==" + }, "node_modules/@azure/core-auth": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.3.2.tgz", @@ -134,6 +162,134 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" }, + "node_modules/@azure/core-client": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.4.0.tgz", + "integrity": "sha512-6v1pn4ubNSeI56PUgj2NLR/nfoMfkjYmrtNX0YdXrjxSajKcf/TZc/QJtTFj4wHIvYqU/Yn/g/Zb+MNhFZ5c+Q==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-asynciterator-polyfill": "^1.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-rest-pipeline": "^1.4.0", + "@azure/core-tracing": "1.0.0-preview.13", + "@azure/logger": "^1.0.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/core-client/node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + }, + "node_modules/@azure/core-lro": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.2.3.tgz", + "integrity": "sha512-UMdlR9NsqDCLTba3EUbRjfMF4gDmWvld196JmUjbz9WWhJ2XT00OR5MXeWiR+vmGT+ETiO4hHFCi2/eGO5YVtg==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-tracing": "1.0.0-preview.13", + "@azure/logger": "^1.0.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/core-lro/node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + }, + "node_modules/@azure/core-paging": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.2.1.tgz", + "integrity": "sha512-UtH5iMlYsvg+nQYIl4UHlvvSrsBjOlRF4fs0j7mxd3rWdAStrKYrh2durOpHs5C9yZbVhsVDaisoyaf/lL1EVA==", + "dependencies": { + "@azure/core-asynciterator-polyfill": "^1.0.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/core-paging/node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + }, + "node_modules/@azure/core-rest-pipeline": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.4.0.tgz", + "integrity": "sha512-M2uL9PbvhJIEMRoUad3EnXCHWLN/i0W7D7MQJ9rnIDW7iLVCteUiegdqNa2Cr1/7he/ysEXYiwaXiHmfack/6g==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-tracing": "1.0.0-preview.13", + "@azure/logger": "^1.0.0", + "form-data": "^4.0.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "tslib": "^2.2.0", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/core-rest-pipeline/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@azure/core-rest-pipeline/node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + }, + "node_modules/@azure/core-tracing": { + "version": "1.0.0-preview.13", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz", + "integrity": "sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ==", + "dependencies": { + "@opentelemetry/api": "^1.0.1", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/core-tracing/node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + }, + "node_modules/@azure/logger": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.0.3.tgz", + "integrity": "sha512-aK4s3Xxjrx3daZr3VylxejK3vG5ExXck5WOHDJ8in/k9AqlfIyFMMT1uG7u8mNjX+QRILTIn0/Xgschfh/dQ9g==", + "dependencies": { + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/logger/node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + }, "node_modules/@azure/ms-rest-azure-env": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@azure/ms-rest-azure-env/-/ms-rest-azure-env-2.0.0.tgz", @@ -433,11 +589,18 @@ "node": ">=10" } }, + "node_modules/@opentelemetry/api": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.0.4.tgz", + "integrity": "sha512-BuJuXRSJNQ3QoKA6GWWDyuLpOUck+9hAXNMCnrloc1aWVoy6Xq6t9PUV08aBZ4Lutqq2LEHM486bpZqoViScog==", + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true, "engines": { "node": ">= 6" } @@ -1047,7 +1210,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, "dependencies": { "debug": "4" }, @@ -1941,7 +2103,6 @@ "version": "4.3.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -3559,7 +3720,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dev": true, "dependencies": { "@tootallnate/once": "1", "agent-base": "6", @@ -3573,7 +3733,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dev": true, "dependencies": { "agent-base": "6", "debug": "4" @@ -4761,8 +4920,7 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/nanoid": { "version": "3.2.0", @@ -7295,14 +7453,24 @@ } }, "@azure/arm-resources": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@azure/arm-resources/-/arm-resources-4.2.2.tgz", - "integrity": "sha512-Oic1OcEwgex3X1KkhP9UM/E/taIaS9oID7PL/CZ8knD7qtVNSRvTxP3uvD3ZpH9NYBYXngJsX5xyRu66iFN+rA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@azure/arm-resources/-/arm-resources-5.0.0.tgz", + "integrity": "sha512-eKICohMfZcW0d7tsxS29Z/bznvfUMCu+khJhDJfDlKLqfmqBun6CxBTDeWcNbuckDRxalJ0gZJp5hidC9+Msiw==", "requires": { - "@azure/core-auth": "^1.1.4", - "@azure/ms-rest-azure-js": "^2.1.0", - "@azure/ms-rest-js": "^2.2.0", - "tslib": "^1.10.0" + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-client": "^1.0.0", + "@azure/core-lro": "^2.2.0", + "@azure/core-paging": "^1.2.0", + "@azure/core-rest-pipeline": "^1.1.0", + "tslib": "^2.2.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } } }, "@azure/arm-resources-profile-2020-09-01-hybrid": { @@ -7328,13 +7496,24 @@ } }, "@azure/arm-storage": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/@azure/arm-storage/-/arm-storage-15.3.0.tgz", - "integrity": "sha512-djN2tmEzvC4lNEYrk3PAXkf5ZcebGDqPZSh/cYKOleumD4eop5EpMX8d5LcSO/9EcSfPpCzutRg0AleMaPQ9Mg==", + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@azure/arm-storage/-/arm-storage-17.0.0.tgz", + "integrity": "sha512-WS9eT3/vDQ7a1z/8K5BkPhoAi0ilo94yCSws4KyWq6UIA3RaXBDpYYAlN0TOxad9rPeOnWXWcB9gLw3DmjZ4wg==", "requires": { - "@azure/ms-rest-azure-js": "^2.0.1", - "@azure/ms-rest-js": "^2.0.4", - "tslib": "^1.10.0" + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-client": "^1.0.0", + "@azure/core-lro": "^2.2.0", + "@azure/core-paging": "^1.2.0", + "@azure/core-rest-pipeline": "^1.1.0", + "tslib": "^2.2.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } } }, "@azure/arm-storage-profile-2020-09-01-hybrid": { @@ -7348,6 +7527,11 @@ "tslib": "^1.10.0" } }, + "@azure/core-asynciterator-polyfill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@azure/core-asynciterator-polyfill/-/core-asynciterator-polyfill-1.0.0.tgz", + "integrity": "sha512-kmv8CGrPfN9SwMwrkiBK9VTQYxdFQEGe0BmQk+M8io56P9KNzpAxcWE/1fxJj7uouwN4kXF0BHW8DNlgx+wtCg==" + }, "@azure/core-auth": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.3.2.tgz", @@ -7364,6 +7548,125 @@ } } }, + "@azure/core-client": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.4.0.tgz", + "integrity": "sha512-6v1pn4ubNSeI56PUgj2NLR/nfoMfkjYmrtNX0YdXrjxSajKcf/TZc/QJtTFj4wHIvYqU/Yn/g/Zb+MNhFZ5c+Q==", + "requires": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-asynciterator-polyfill": "^1.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-rest-pipeline": "^1.4.0", + "@azure/core-tracing": "1.0.0-preview.13", + "@azure/logger": "^1.0.0", + "tslib": "^2.2.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@azure/core-lro": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.2.3.tgz", + "integrity": "sha512-UMdlR9NsqDCLTba3EUbRjfMF4gDmWvld196JmUjbz9WWhJ2XT00OR5MXeWiR+vmGT+ETiO4hHFCi2/eGO5YVtg==", + "requires": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-tracing": "1.0.0-preview.13", + "@azure/logger": "^1.0.0", + "tslib": "^2.2.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@azure/core-paging": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.2.1.tgz", + "integrity": "sha512-UtH5iMlYsvg+nQYIl4UHlvvSrsBjOlRF4fs0j7mxd3rWdAStrKYrh2durOpHs5C9yZbVhsVDaisoyaf/lL1EVA==", + "requires": { + "@azure/core-asynciterator-polyfill": "^1.0.0", + "tslib": "^2.2.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@azure/core-rest-pipeline": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.4.0.tgz", + "integrity": "sha512-M2uL9PbvhJIEMRoUad3EnXCHWLN/i0W7D7MQJ9rnIDW7iLVCteUiegdqNa2Cr1/7he/ysEXYiwaXiHmfack/6g==", + "requires": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-tracing": "1.0.0-preview.13", + "@azure/logger": "^1.0.0", + "form-data": "^4.0.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "tslib": "^2.2.0", + "uuid": "^8.3.0" + }, + "dependencies": { + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@azure/core-tracing": { + "version": "1.0.0-preview.13", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz", + "integrity": "sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ==", + "requires": { + "@opentelemetry/api": "^1.0.1", + "tslib": "^2.2.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@azure/logger": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.0.3.tgz", + "integrity": "sha512-aK4s3Xxjrx3daZr3VylxejK3vG5ExXck5WOHDJ8in/k9AqlfIyFMMT1uG7u8mNjX+QRILTIn0/Xgschfh/dQ9g==", + "requires": { + "tslib": "^2.2.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, "@azure/ms-rest-azure-env": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@azure/ms-rest-azure-env/-/ms-rest-azure-env-2.0.0.tgz", @@ -7612,11 +7915,15 @@ } } }, + "@opentelemetry/api": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.0.4.tgz", + "integrity": "sha512-BuJuXRSJNQ3QoKA6GWWDyuLpOUck+9hAXNMCnrloc1aWVoy6Xq6t9PUV08aBZ4Lutqq2LEHM486bpZqoViScog==" + }, "@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" }, "@types/eslint": { "version": "8.2.0", @@ -8111,7 +8418,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, "requires": { "debug": "4" } @@ -8784,7 +9090,6 @@ "version": "4.3.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, "requires": { "ms": "2.1.2" } @@ -10040,7 +10345,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dev": true, "requires": { "@tootallnate/once": "1", "agent-base": "6", @@ -10051,7 +10355,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dev": true, "requires": { "agent-base": "6", "debug": "4" @@ -10940,8 +11243,7 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "nanoid": { "version": "3.2.0", diff --git a/ui/package.json b/ui/package.json index 47a57ef884..6bd341e3d1 100644 --- a/ui/package.json +++ b/ui/package.json @@ -1,7 +1,7 @@ { "name": "vscode-azureextensionui", "author": "Microsoft Corporation", - "version": "0.49.3", + "version": "0.50.0", "description": "Common UI tools for developing Azure extensions for VS Code", "tags": [ "azure", @@ -32,10 +32,10 @@ "test": "node ./out/test/runTest.js" }, "dependencies": { - "@azure/arm-resources": "^4.0.0", + "@azure/arm-resources": "^5.0.0", "@azure/arm-resources-profile-2020-09-01-hybrid": "^1.0.0", "@azure/arm-resources-subscriptions": "^1.0.0", - "@azure/arm-storage": "^15.0.0", + "@azure/arm-storage": "^17.0.0", "@azure/arm-storage-profile-2020-09-01-hybrid": "^1.0.0", "@azure/ms-rest-azure-env": "^2.0.0", "@azure/ms-rest-js": "^2.2.1", diff --git a/ui/src/GenericServiceClient.ts b/ui/src/GenericServiceClient.ts index 1846402c70..0fd61ba2ed 100644 --- a/ui/src/GenericServiceClient.ts +++ b/ui/src/GenericServiceClient.ts @@ -8,7 +8,7 @@ import * as vscode from 'vscode'; import * as types from '../index'; export class GenericServiceClient extends ServiceClient { - constructor(credentials: types.AzExtServiceClientCredentials | undefined, options: types.IMinimumServiceClientOptions) { + constructor(credentials: types.AzExtGenericCredentials | undefined, options: types.IMinimumServiceClientOptions) { super(credentials, options); this.baseUri = options.baseUri?.endsWith('/') ? options.baseUri.slice(0, -1) : options.baseUri; } diff --git a/ui/src/azure-account.api.d.ts b/ui/src/azure-account.api.d.ts index e59ccfd90f..45bda97beb 100644 --- a/ui/src/azure-account.api.d.ts +++ b/ui/src/azure-account.api.d.ts @@ -4,40 +4,61 @@ *--------------------------------------------------------------------------------------------*/ import type { SubscriptionModels } from '@azure/arm-resources-subscriptions'; -import type { Environment } from '@azure/ms-rest-azure-env'; -import type { TokenCredentialsBase } from '@azure/ms-rest-nodeauth'; -import { Event } from 'vscode'; +import { TokenCredential } from '@azure/core-auth'; +import { Environment } from '@azure/ms-rest-azure-env'; +import { TokenCredentialsBase } from '@azure/ms-rest-nodeauth'; +import { ReadStream } from 'fs'; +import { CancellationToken, Event, Progress, Terminal } from 'vscode'; export type AzureLoginStatus = 'Initializing' | 'LoggingIn' | 'LoggedIn' | 'LoggedOut'; -export interface AzureAccount { - readonly status: AzureLoginStatus; - readonly onStatusChanged: Event; - readonly waitForLogin: () => Promise; - readonly sessions: AzureSession[]; - readonly onSessionsChanged: Event; - readonly subscriptions: AzureSubscription[]; - readonly onSubscriptionsChanged: Event; - readonly waitForSubscriptions: () => Promise; - readonly filters: AzureResourceFilter[]; - readonly onFiltersChanged: Event; - readonly waitForFilters: () => Promise; +export interface AzureAccountExtensionApi { + readonly apiVersion: string; + readonly status: AzureLoginStatus; + readonly filters: AzureResourceFilter[]; + readonly sessions: AzureSession[]; + readonly subscriptions: AzureSubscription[]; + readonly onStatusChanged: Event; + readonly onFiltersChanged: Event; + readonly onSessionsChanged: Event; + readonly onSubscriptionsChanged: Event; + readonly waitForFilters: () => Promise; + readonly waitForLogin: () => Promise; + readonly waitForSubscriptions: () => Promise; + createCloudShell(os: 'Linux' | 'Windows'): CloudShell; } export interface AzureSession { - readonly environment: Environment; - readonly userId: string; - readonly tenantId: string; - - /** - * The credentials object for azure-sdk-for-js modules https://github.com/azure/azure-sdk-for-js - */ - readonly credentials2: TokenCredentialsBase; + readonly environment: Environment; + readonly userId: string; + readonly tenantId: string; + + /** + * The credentials object for azure-sdk-for-js modules https://github.com/azure/azure-sdk-for-js + */ + readonly credentials2: TokenCredentialsBase & TokenCredential; } export interface AzureSubscription { - readonly session: AzureSession; - readonly subscription: SubscriptionModels.Subscription; + readonly session: AzureSession; + readonly subscription: SubscriptionModels.Subscription; } export type AzureResourceFilter = AzureSubscription; + +export type CloudShellStatus = 'Connecting' | 'Connected' | 'Disconnected'; + +export interface UploadOptions { + contentLength?: number; + progress?: Progress<{ message?: string; increment?: number }>; + token?: CancellationToken; +} + +export interface CloudShell { + readonly status: CloudShellStatus; + readonly onStatusChanged: Event; + readonly waitForConnection: () => Promise; + readonly terminal: Promise; + readonly session: Promise; + readonly uploadFile: (filename: string, stream: ReadStream, options?: UploadOptions) => Promise; +} diff --git a/ui/src/constants.ts b/ui/src/constants.ts index b2cf8b49a7..6099e0f260 100644 --- a/ui/src/constants.ts +++ b/ui/src/constants.ts @@ -8,6 +8,7 @@ import { localize } from "./localize"; export const resourcesProvider: string = 'Microsoft.Resources'; export const storageProvider: string = 'Microsoft.Storage'; +export const storageProviderType = "Microsoft.Storage/storageAccounts"; export const learnMore: string = localize('learnMore', "Learn more"); export namespace AzExtQuickInputButtons { diff --git a/ui/src/createAzureClient.ts b/ui/src/createAzureClient.ts index 13daa66e6d..2a78675be7 100644 --- a/ui/src/createAzureClient.ts +++ b/ui/src/createAzureClient.ts @@ -79,7 +79,7 @@ interface IGenericClientOptions { } export async function createGenericClient(context: types.IActionContext, clientInfo: types.AzExtGenericClientInfo, options?: IGenericClientOptions): Promise { - let credentials: types.AzExtServiceClientCredentials | undefined; + let credentials: types.AzExtGenericCredentials | undefined; let baseUri: string | undefined; if (clientInfo && 'credentials' in clientInfo) { credentials = clientInfo.credentials; @@ -98,7 +98,7 @@ export async function createGenericClient(context: types.IActionContext, clientI }); } -function addAzExtFactories(context: types.IActionContext, credentials: types.AzExtServiceClientCredentials | undefined, defaultFactories: RequestPolicyFactory[]): RequestPolicyFactory[] { +function addAzExtFactories(context: types.IActionContext, credentials: types.AzExtGenericCredentials | undefined, defaultFactories: RequestPolicyFactory[]): RequestPolicyFactory[] { // NOTE: Factories at the end of the array are executed first, and we want these to happen before the deserialization factory defaultFactories.push( { @@ -212,8 +212,8 @@ class StatusCodePolicy extends BaseRequestPolicy { * this policy will make sure those credentials get masked in the error message */ class MaskCredentialsPolicy extends BaseRequestPolicy { - private _credentials: types.AzExtServiceClientCredentials | undefined; - constructor(nextPolicy: RequestPolicy, requestPolicyOptions: RequestPolicyOptions, credentials: types.AzExtServiceClientCredentials | undefined,) { + private _credentials: types.AzExtGenericCredentials | undefined; + constructor(nextPolicy: RequestPolicy, requestPolicyOptions: RequestPolicyOptions, credentials: types.AzExtGenericCredentials | undefined,) { super(nextPolicy, requestPolicyOptions); this._credentials = credentials; } diff --git a/ui/src/index.ts b/ui/src/index.ts index 260b04e950..6499ecbe13 100644 --- a/ui/src/index.ts +++ b/ui/src/index.ts @@ -27,6 +27,7 @@ export * from './tree/AzureAccountTreeItemBase'; export * from './tree/GenericTreeItem'; export * from './tree/SubscriptionTreeItemBase'; export * from './utils/AzExtFsExtra'; +export * from './utils/uiUtils'; export * from './wizard/AzureNameStep'; export * from './wizard/AzureWizard'; export * from './wizard/AzureWizardExecuteStep'; diff --git a/ui/src/tree/AzureAccountTreeItemBase.ts b/ui/src/tree/AzureAccountTreeItemBase.ts index 2afc86fe08..57821a6f8d 100644 --- a/ui/src/tree/AzureAccountTreeItemBase.ts +++ b/ui/src/tree/AzureAccountTreeItemBase.ts @@ -6,7 +6,7 @@ import * as semver from 'semver'; import { commands, Disposable, Extension, extensions, MessageItem, ProgressLocation, ThemeIcon, window } from 'vscode'; import * as types from '../../index'; -import { AzureAccount, AzureLoginStatus, AzureResourceFilter } from '../azure-account.api'; +import { AzureAccountExtensionApi, AzureLoginStatus, AzureResourceFilter } from '../azure-account.api'; import { UserCancelledError } from '../errors'; import { localize } from '../localize'; import { addExtensionValueToMask } from '../masking'; @@ -18,6 +18,7 @@ import { AzExtTreeItem } from './AzExtTreeItem'; import { GenericTreeItem } from './GenericTreeItem'; import { getIconPath } from './IconPath'; import { SubscriptionTreeItemBase } from './SubscriptionTreeItemBase'; +import { DeviceTokenCredentials } from '@azure/ms-rest-nodeauth'; const signInLabel: string = localize('signInLabel', 'Sign in to Azure...'); const createAccountLabel: string = localize('createAccountLabel', 'Create a Free Azure Account...'); @@ -28,7 +29,7 @@ const selectSubscriptionsCommandId: string = 'azure-account.selectSubscriptions' const azureAccountExtensionId: string = 'ms-vscode.azure-account'; const extensionOpenCommand: string = 'extension.open'; -type AzureAccountResult = AzureAccount | 'notInstalled' | 'needsUpdate'; +type AzureAccountResult = AzureAccountExtensionApi | 'notInstalled' | 'needsUpdate'; const minAccountExtensionVersion: string = '0.9.0'; export abstract class AzureAccountTreeItemBase extends AzExtParentTreeItem implements types.AzureAccountTreeItemBase { @@ -42,9 +43,9 @@ export abstract class AzureAccountTreeItemBase extends AzExtParentTreeItem imple private _azureAccountTask: Promise; private _subscriptionTreeItems: SubscriptionTreeItemBase[] | undefined; - private _testAccount: AzureAccount | undefined; + private _testAccount: AzureAccountExtensionApi | undefined; - constructor(parent?: AzExtParentTreeItem, testAccount?: AzureAccount) { + constructor(parent?: AzExtParentTreeItem, testAccount?: AzureAccountExtensionApi) { super(parent); this._testAccount = testAccount; this._azureAccountTask = this.loadAzureAccount(testAccount); @@ -124,15 +125,20 @@ export abstract class AzureAccountTreeItemBase extends AzExtParentTreeItem imple filter.subscription.displayName, filter.session.userId, filter.session.tenantId, - filter.session.credentials2.clientId, - filter.session.credentials2.domain ); + + // these properties don't exist on TokenCredentials + if (filter.session.credentials2 instanceof DeviceTokenCredentials) { + addExtensionValueToMask( + filter.session.credentials2.clientId, + filter.session.credentials2.domain); + } // filter.subscription.id is the The fully qualified ID of the subscription (For example, /subscriptions/00000000-0000-0000-0000-000000000000) and should be used as the tree item's id for the purposes of OpenInPortal // filter.subscription.subscriptionId is just the guid and is used in all other cases when creating clients for managing Azure resources const subscriptionId: string = nonNullProp(filter.subscription, 'subscriptionId'); return await this.createSubscriptionTreeItem({ - credentials: filter.session.credentials2, + credentials: filter.session.credentials2, subscriptionDisplayName: nonNullProp(filter.subscription, 'displayName'), subscriptionId, subscriptionPath: nonNullProp(filter.subscription, 'id'), @@ -190,9 +196,9 @@ export abstract class AzureAccountTreeItemBase extends AzExtParentTreeItem imple } } - private async loadAzureAccount(azureAccount: AzureAccount | undefined): Promise { + private async loadAzureAccount(azureAccount: AzureAccountExtensionApi | undefined): Promise { if (!azureAccount) { - const extension: Extension | undefined = extensions.getExtension(azureAccountExtensionId); + const extension: Extension | undefined = extensions.getExtension(azureAccountExtensionId); if (extension) { try { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access diff --git a/ui/src/utils/uiUtils.ts b/ui/src/utils/uiUtils.ts index bb29dd4155..9f2a3cbdb5 100644 --- a/ui/src/utils/uiUtils.ts +++ b/ui/src/utils/uiUtils.ts @@ -3,6 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { PagedAsyncIterableIterator } from "@azure/core-paging"; +import * as coreClient from '@azure/core-client'; + export namespace uiUtils { export interface IPartialList extends Array { nextLink?: string; @@ -20,4 +23,13 @@ export namespace uiUtils { return all; } + + export async function listAllIterator(list: (options?: coreClient.OperationOptions) => PagedAsyncIterableIterator, options?: coreClient.OperationOptions): Promise { + const resources: T[] = []; + for await (const r of list(options)) { + resources.push(r); + } + + return resources; + } } diff --git a/ui/src/wizard/LocationListStep.ts b/ui/src/wizard/LocationListStep.ts index 88ad703c61..ae282f70fc 100644 --- a/ui/src/wizard/LocationListStep.ts +++ b/ui/src/wizard/LocationListStep.ts @@ -3,8 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -// eslint-disable-next-line import/no-internal-modules -import { ExtendedLocation } from '@azure/arm-resources/esm/models'; +import { ExtendedLocation } from '@azure/arm-resources'; import * as types from '../../index'; import { createResourcesClient, createSubscriptionsClient } from '../clients'; import { resourcesProvider } from '../constants'; diff --git a/ui/src/wizard/ResourceGroupCreateStep.ts b/ui/src/wizard/ResourceGroupCreateStep.ts index 0d9c665aa1..d7a74b1c49 100644 --- a/ui/src/wizard/ResourceGroupCreateStep.ts +++ b/ui/src/wizard/ResourceGroupCreateStep.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import type { ResourceManagementClient } from '@azure/arm-resources'; +import type { ResourceGroup, ResourceManagementClient } from '@azure/arm-resources'; import { MessageItem, Progress } from 'vscode'; import * as types from '../../index'; import { createResourcesClient } from '../clients'; @@ -11,6 +11,7 @@ import { resourcesProvider } from '../constants'; import { ext } from '../extensionVariables'; import { localize } from '../localize'; import { parseError } from '../parseError'; +import { uiUtils } from '../utils/uiUtils'; import { AzureWizardExecuteStep } from './AzureWizardExecuteStep'; import { LocationListStep } from './LocationListStep'; import { ResourceGroupListStep } from './ResourceGroupListStep'; @@ -42,7 +43,8 @@ export class ResourceGroupCreateStep this._suppressCreate = suppressCreate; } - public static async getResourceGroups(wizardContext: T): Promise { + public static async getResourceGroups(wizardContext: T): Promise { if (wizardContext.resourceGroupsTask === undefined) { const client: ResourceManagementClient = await createResourcesClient(wizardContext); - wizardContext.resourceGroupsTask = uiUtils.listAll(client.resourceGroups, client.resourceGroups.list()); + wizardContext.resourceGroupsTask = uiUtils.listAllIterator(client.resourceGroups.list); } return await wizardContext.resourceGroupsTask; } public static async isNameAvailable(wizardContext: T, name: string): Promise { - const resourceGroupsTask: Promise = ResourceGroupListStep.getResourceGroups(wizardContext); - return !(await resourceGroupsTask).some((rg: ResourceManagementModels.ResourceGroup) => rg.name !== undefined && rg.name.toLowerCase() === name.toLowerCase()); + const resourceGroupsTask: Promise = ResourceGroupListStep.getResourceGroups(wizardContext); + return !(await resourceGroupsTask).some((rg: ResourceGroup) => rg.name !== undefined && rg.name.toLowerCase() === name.toLowerCase()); } public async prompt(wizardContext: T): Promise { @@ -67,8 +67,8 @@ export class ResourceGroupListStep return !wizardContext.resourceGroup && !wizardContext.newResourceGroupName; } - private async getQuickPicks(wizardContext: T): Promise[]> { - const picks: types.IAzureQuickPickItem[] = []; + private async getQuickPicks(wizardContext: T): Promise[]> { + const picks: types.IAzureQuickPickItem[] = []; if (!this._suppressCreate) { picks.push({ @@ -78,7 +78,7 @@ export class ResourceGroupListStep }); } - const resourceGroups: ResourceManagementModels.ResourceGroup[] = (await ResourceGroupListStep.getResourceGroups(wizardContext)).sort((a, b) => { + const resourceGroups: ResourceGroup[] = (await ResourceGroupListStep.getResourceGroups(wizardContext)).sort((a, b) => { const nameA: string = nonNullProp(a, 'name'); const nameB: string = nonNullProp(b, 'name'); if (nameA > nameB) { @@ -90,7 +90,7 @@ export class ResourceGroupListStep } }); - return picks.concat(resourceGroups.map((rg: ResourceManagementModels.ResourceGroup) => { + return picks.concat(resourceGroups.map((rg: ResourceGroup) => { return { id: rg.id, // eslint-disable-next-line @typescript-eslint/no-non-null-assertion diff --git a/ui/src/wizard/StorageAccountCreateStep.ts b/ui/src/wizard/StorageAccountCreateStep.ts index 0de1dfd3d0..36e8a272d3 100644 --- a/ui/src/wizard/StorageAccountCreateStep.ts +++ b/ui/src/wizard/StorageAccountCreateStep.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import type { StorageManagementClient, StorageManagementModels } from '@azure/arm-storage'; +import type { SkuName, StorageManagementClient } from '@azure/arm-storage'; import { Progress } from 'vscode'; import * as types from '../../index'; import { createStorageClient } from '../clients'; @@ -27,12 +27,12 @@ export class StorageAccountCreateStep`${this._defaults.performance}_${this._defaults.replication}`; + const newSkuName: SkuName = `${this._defaults.performance}_${this._defaults.replication}`; const creatingStorageAccount: string = localize('CreatingStorageAccount', 'Creating storage account "{0}" in location "{1}" with sku "{2}"...', newName, newLocation, newSkuName); ext.outputChannel.appendLog(creatingStorageAccount); progress.report({ message: creatingStorageAccount }); const storageClient: StorageManagementClient = await createStorageClient(wizardContext); - wizardContext.storageAccount = await storageClient.storageAccounts.create( + wizardContext.storageAccount = await storageClient.storageAccounts.beginCreateAndWait( // eslint-disable-next-line @typescript-eslint/no-non-null-assertion wizardContext.resourceGroup!.name!, newName, diff --git a/ui/src/wizard/StorageAccountListStep.ts b/ui/src/wizard/StorageAccountListStep.ts index 03015afbff..9ef579e815 100644 --- a/ui/src/wizard/StorageAccountListStep.ts +++ b/ui/src/wizard/StorageAccountListStep.ts @@ -3,13 +3,14 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import type { StorageManagementClient, StorageManagementModels } from '@azure/arm-storage'; +import type { StorageAccount, StorageManagementClient } from '@azure/arm-storage'; import * as types from '../../index'; import { createStorageClient } from '../clients'; -import { storageProvider } from '../constants'; +import { storageProvider, storageProviderType } from '../constants'; import { localize } from '../localize'; import { nonNullProp } from '../utils/nonNull'; import { openUrl } from '../utils/openUrl'; +import { uiUtils } from '../utils/uiUtils'; import { AzureWizardPromptStep } from './AzureWizardPromptStep'; import { LocationListStep } from './LocationListStep'; import { ResourceGroupListStep } from './ResourceGroupListStep'; @@ -69,16 +70,16 @@ export class StorageAccountListStep(wizardContext: T, name: string): Promise { const storageClient: StorageManagementClient = await createStorageClient(wizardContext); - return !!(await storageClient.storageAccounts.checkNameAvailability(name)).nameAvailable; + return !!(await storageClient.storageAccounts.checkNameAvailability({name, type: storageProviderType})).nameAvailable; } public async prompt(wizardContext: T): Promise { const client: StorageManagementClient = await createStorageClient(wizardContext); const quickPickOptions: types.IAzureQuickPickOptions = { placeHolder: 'Select a storage account.', id: `StorageAccountListStep/${wizardContext.subscriptionId}` }; - const picksTask: Promise[]> = this.getQuickPicks(wizardContext, client.storageAccounts.list()); + const picksTask: Promise[]> = this.getQuickPicks(wizardContext, uiUtils.listAllIterator(client.storageAccounts.list)); - const result: StorageManagementModels.StorageAccount | undefined = (await wizardContext.ui.showQuickPick(picksTask, quickPickOptions)).data; + const result: StorageAccount | undefined = (await wizardContext.ui.showQuickPick(picksTask, quickPickOptions)).data; wizardContext.storageAccount = result; if (wizardContext.storageAccount) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion @@ -104,8 +105,8 @@ export class StorageAccountListStep): Promise[]> { - const picks: types.IAzureQuickPickItem[] = [{ + private async getQuickPicks(wizardContext: T, storageAccountsTask: Promise): Promise[]> { + const picks: types.IAzureQuickPickItem[] = [{ label: localize('NewStorageAccount', '$(plus) Create new storage account'), description: '', data: undefined @@ -122,7 +123,7 @@ export class StorageAccountListStep { name = name.trim(); - if (!name || name.length < storageAccountNamingRules.minLength || name.length > storageAccountNamingRules.maxLength) { return localize('invalidLength', 'The name must be between {0} and {1} characters.', storageAccountNamingRules.minLength, storageAccountNamingRules.maxLength); } else if (name.match(storageAccountNamingRules.invalidCharsRegExp) !== null) { return localize('invalidChars', "The name can only contain lowercase letters and numbers."); } else { - const nameAvailabilityResult: StorageManagementModels.CheckNameAvailabilityResult = await client.storageAccounts.checkNameAvailability(name); + const nameAvailabilityResult: CheckNameAvailabilityResult = await client.storageAccounts.checkNameAvailability({name, type: storageProviderType}); if (!nameAvailabilityResult.nameAvailable) { return nameAvailabilityResult.message; } else { diff --git a/ui/src/wizard/VerifyProvidersStep.ts b/ui/src/wizard/VerifyProvidersStep.ts index 4ac754c098..14e7e0894f 100644 --- a/ui/src/wizard/VerifyProvidersStep.ts +++ b/ui/src/wizard/VerifyProvidersStep.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import type { ResourceManagementClient, ResourceManagementModels } from '@azure/arm-resources'; +import type { Provider, ResourceManagementClient } from '@azure/arm-resources'; import { Progress } from 'vscode'; import * as types from '../../index'; import { createResourcesClient } from '../clients'; @@ -27,7 +27,7 @@ export class VerifyProvidersStep ext const client: ResourceManagementClient = await createResourcesClient(context); await Promise.all(this._providers.map(async providerName => { try { - let provider: ResourceManagementModels.Provider = await client.providers.get(providerName); + let provider: Provider = await client.providers.get(providerName); if (provider.registrationState?.toLowerCase() !== 'registered') { await client.providers.register(providerName);