diff --git a/package.json b/package.json index 23599ffe6..55bdb401e 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "private": true, "main": "build/main.js", "dependencies": { - "@azure/storage-blob": "10.3.0", + "@azure/storage-blob": "12.1.2", "@fluentui/react": "^7.117.2", "@microsoft/applicationinsights-react-js": "^3.0.1", "@microsoft/applicationinsights-web": "^2.5.6", diff --git a/src/providers/storage/azureBlobStorage.test.ts b/src/providers/storage/azureBlobStorage.test.ts deleted file mode 100644 index c50a860d4..000000000 --- a/src/providers/storage/azureBlobStorage.test.ts +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. - -import MockFactory from "../../common/mockFactory"; -import registerProviders from "../../registerProviders"; -import { AzureBlobStorage } from "./azureBlobStorage"; -jest.mock("@azure/storage-blob"); -import { BlockBlobURL, ContainerURL, ServiceURL, Aborter } from "@azure/storage-blob"; -jest.mock("../../services/assetService"); -import { AssetService } from "../../services/assetService"; -import { AssetType } from "../../models/applicationState"; - -describe("Azure blob functions", () => { - - const ad = MockFactory.createAzureData(); - const options = ad.options; - - const serviceURL = ServiceURL as jest.Mocked; - serviceURL.prototype.listContainersSegment = jest.fn(() => Promise.resolve(ad.containers)); - - ContainerURL.fromServiceURL = jest.fn(() => new ContainerURL(null, null)); - const containerURL = ContainerURL as jest.Mocked; - containerURL.prototype.create = jest.fn(() => Promise.resolve({ statusCode: 201 })); - containerURL.prototype.delete = jest.fn(() => Promise.resolve({ statusCode: 204 })); - containerURL.prototype.listBlobFlatSegment = jest.fn(() => Promise.resolve(ad.blobs)); - - BlockBlobURL.fromContainerURL = jest.fn(() => new BlockBlobURL(null, null)); - - registerProviders(); - - it("Reads text from a blob", async () => { - const blockBlobURL = BlockBlobURL as jest.Mocked; - - const blob = MockFactory.blob(ad.blobName, ad.blobText, ad.fileType); - blockBlobURL.prototype.download = jest.fn(() => Promise.resolve({ - blobBody: Promise.resolve(blob), - })); - - const provider: AzureBlobStorage = new AzureBlobStorage(options); - - const content = await provider.readText(ad.blobName); - expect(BlockBlobURL.fromContainerURL).toBeCalledWith( - expect.any(ContainerURL), - ad.blobName, - ); - expect(content).toEqual(ad.blobText); - }); - - it("Reads buffer from a blob", async () => { - const blockBlobURL = BlockBlobURL as jest.Mocked; - - const blob = MockFactory.blob( - ad.blobName, Buffer.from(ad.blobText), ad.fileType, - ); - blockBlobURL.prototype.download = jest.fn(() => Promise.resolve({ - blobBody: Promise.resolve(blob), - })); - - const provider: AzureBlobStorage = new AzureBlobStorage(options); - - const content = await provider.readBinary(ad.blobName); - expect(BlockBlobURL.fromContainerURL).toBeCalledWith( - expect.any(ContainerURL), - ad.blobName, - ); - expect(content).toEqual(Buffer.from(ad.blobText)); - }); - - it("Writes text to a blob", () => { - const blockBlobURL = BlockBlobURL as jest.Mocked; - const blob = MockFactory.blob(ad.blobName, ad.blobText, ad.fileType); - blockBlobURL.prototype.download = jest.fn(() => Promise.resolve({ - blobBody: Promise.resolve(blob), - })); - - const provider: AzureBlobStorage = new AzureBlobStorage(options); - - provider.writeText(ad.blobName, ad.blobText); - expect(BlockBlobURL.fromContainerURL).toBeCalledWith( - expect.any(ContainerURL), - ad.blobName, - ); - expect(blockBlobURL.prototype.upload).toBeCalledWith( - Aborter.none, - ad.blobText, - ad.blobText.length, - ); - }); - - it("Writes a buffer to a blob", () => { - const blockBlobURL = BlockBlobURL as jest.Mocked; - - const provider: AzureBlobStorage = new AzureBlobStorage(options); - - provider.writeText(ad.blobName, Buffer.from(ad.blobText)); - expect(BlockBlobURL.fromContainerURL).toBeCalledWith( - expect.any(ContainerURL), - ad.blobName, - ); - expect(blockBlobURL.prototype.upload).toBeCalledWith( - Aborter.none, - Buffer.from(ad.blobText), - ad.blobText.length, - ); - }); - - it("Lists the blobs within a container", async () => { - const provider: AzureBlobStorage = new AzureBlobStorage(options); - const blobs = await provider.listFiles(null); - expect(containerURL.prototype.listBlobFlatSegment).toBeCalled(); - expect(blobs).toEqual(ad.blobs.segment.blobItems.map((element) => element.name)); - }); - - it("Deletes a blob within a container", async () => { - const blockBlobURL = BlockBlobURL as jest.Mocked; - - const provider: AzureBlobStorage = new AzureBlobStorage(options); - - provider.deleteFile(ad.blobName); - expect(BlockBlobURL.fromContainerURL).toBeCalledWith( - expect.any(ContainerURL), - ad.blobName, - ); - expect(blockBlobURL.prototype.delete).toBeCalledWith(Aborter.none); - }); - - it("Lists the containers within an account", async () => { - const provider: AzureBlobStorage = new AzureBlobStorage(options); - const containers = await provider.listContainers(null); - expect(serviceURL.prototype.listContainersSegment).toBeCalled(); - expect(containers).toEqual(ad.containers.containerItems.map((element) => element.name)); - }); - - it("Creates a container in the account", async () => { - const provider: AzureBlobStorage = new AzureBlobStorage(options); - await expect(provider.createContainer(null)).resolves.not.toBeNull(); - expect(containerURL.prototype.create).toBeCalled(); - }); - - it("Creates a container that already exists", async () => { - containerURL.prototype.create = jest.fn(() => { - return Promise.reject({ statusCode: 409 }); - }); - - const provider: AzureBlobStorage = new AzureBlobStorage(options); - await expect(provider.createContainer(null)).resolves.not.toBeNull(); - expect(containerURL.prototype.create).toBeCalled(); - }); - - it("Deletes a container in the account", () => { - const provider: AzureBlobStorage = new AzureBlobStorage(options); - provider.deleteContainer(null); - expect(containerURL.prototype.delete).toBeCalled(); - }); - - it("getAssets", async () => { - const provider: AzureBlobStorage = new AzureBlobStorage(options); - AssetService.createAssetFromFilePath = jest.fn(() => { - return { - type: AssetType.Image, - }; - }); - provider.getFileName = jest.fn(); - const assets = await provider.getAssets(); - expect(provider.getFileName).toBeCalled(); - expect(assets).toHaveLength(ad.blobs.segment.blobItems.length); - }); - - it("get file name from url", async () => { - const provider: AzureBlobStorage = new AzureBlobStorage(options); - const url = "https://account.blob.core.windows.net/container/filename.jpg?aBcDeFGHiJkLMnoP"; - const fileName = provider.getFileName(url); - expect(fileName).toEqual("filename.jpg"); - }); - - it("creates a container when specified in options", () => { - const newOptions = { - ...options, - containerName: "newContainer", - createContainer: true, - }; - const provider: AzureBlobStorage = new AzureBlobStorage(newOptions); - - provider.initialize(); - expect(ContainerURL.fromServiceURL).toBeCalledWith( - expect.any(ServiceURL), - newOptions.containerName, - ); - }); - - it("does not create a container when not specified", async () => { - const provider: AzureBlobStorage = new AzureBlobStorage(options); - await provider.initialize(); - expect(serviceURL.prototype.listContainersSegment).toBeCalled(); - }); -}); diff --git a/src/providers/storage/azureBlobStorage.ts b/src/providers/storage/azureBlobStorage.ts index 46e6bbe9a..42c4d8f94 100644 --- a/src/providers/storage/azureBlobStorage.ts +++ b/src/providers/storage/azureBlobStorage.ts @@ -1,18 +1,12 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. - -import { AzureBlobStorageError } from "./azureBlobStorageError"; -import { IStorageProvider } from "./storageProviderFactory"; -import { IAsset, AssetType, StorageType, AssetState, AppError } from "../../models/applicationState"; -import { AssetService } from "../../services/assetService"; -import { - TokenCredential, AnonymousCredential, ContainerURL, - StorageURL, Credential, Aborter, BlockBlobURL, ServiceURL -} from "@azure/storage-blob"; +import { BlobServiceClient, ContainerClient } from "@azure/storage-blob"; import { constants } from "../../common/constants"; -import { ErrorCode } from "../../models/applicationState"; import { strings } from "../../common/strings"; +import { AppError, AssetState, AssetType, ErrorCode, IAsset, StorageType } from "../../models/applicationState"; import { throwUnhandledRejectionForEdge } from "../../react/components/common/errorHandler/errorHandler"; +import { AssetService } from "../../services/assetService"; +import { IStorageProvider } from "./storageProviderFactory"; /** * Options for Azure Cloud Storage @@ -34,7 +28,10 @@ export class AzureBlobStorage implements IStorageProvider { */ public storageType: StorageType = StorageType.Cloud; - constructor(private options?: IAzureCloudStorageOptions) { } + private containerClient: ContainerClient; + constructor(private options?: IAzureCloudStorageOptions) { + this.containerClient = new ContainerClient(options!.sas!); + } /** * Initialize connection to Blob Storage account & container @@ -45,33 +42,35 @@ export class AzureBlobStorage implements IStorageProvider { * connect to Azure Blob Storage */ // tslint:disable-next-line:no-empty - public async initialize(): Promise {} + public async initialize(): Promise { } /** * Reads text from specified blob * @param blobName - Name of blob in container */ - public async readText(blobName: string, ignoreNotFound?: boolean): Promise { + public async readText(blobName: string, ignoreNotFound?: boolean | undefined): Promise { try { - const blockBlobURL = this.getBlockBlobURL(blobName); - const downloadResponse = await blockBlobURL.download(Aborter.none, 0); - return await this.bodyToString(downloadResponse); + const client = this.containerClient.getBlockBlobClient(blobName); + const result = await client.download(); + + return await this.blobToString(await result.blobBody!); } catch (exception) { this.azureBlobStorageErrorHandler(exception, ignoreNotFound); } } - public async isValidProjectConnection() { + public async isValidProjectConnection(filepath?: string | undefined): Promise { try { - return await new ServiceURL(this.options.sas, StorageURL.newPipeline(this.getCredential())).getAccountInfo(Aborter.timeout(5000)) - .then(() => { - return true; - }) - .catch(() => { - return false; - }) + const client = new BlobServiceClient(this.options!.sas!); + return await client.getAccountInfo() + .then(() => { + return true; + }) + .catch(() => { + return false; + }); } catch { - return (false); + return false; } } @@ -79,10 +78,13 @@ export class AzureBlobStorage implements IStorageProvider { * Reads Buffer from specified blob * @param blobName - Name of blob in container */ - public async readBinary(blobName: string) { + public async readBinary(blobName: string): Promise { try { - const text = await this.readText(blobName); - return Buffer.from(text); + const client = this.containerClient.getBlockBlobClient(blobName); + const result = await client.download(); + + const arrayBuffer = await this.blobToArrayBuffer(await result.blobBody!); + return Buffer.from(arrayBuffer); } catch (exception) { this.azureBlobStorageErrorHandler(exception); } @@ -95,13 +97,7 @@ export class AzureBlobStorage implements IStorageProvider { */ public async writeText(blobName: string, content: string | Buffer) { try { - const containerURL = new ContainerURL(this.options.sas, StorageURL.newPipeline(this.getCredential())); - const blockBlobURL = BlockBlobURL.fromContainerURL(containerURL, blobName); - await blockBlobURL.upload( - Aborter.none, - content, - content.length, - ); + await this.containerClient.uploadBlockBlob(blobName, content, content.length); } catch (exception) { this.azureBlobStorageErrorHandler(exception); } @@ -112,9 +108,9 @@ export class AzureBlobStorage implements IStorageProvider { * @param blobName - Name of blob in container * @param content - Buffer to write to blob */ - public writeBinary(blobName: string, content: Buffer) { + public async writeBinary(blobName: string, content: Buffer) { try { - return this.writeText(blobName, content); + await this.containerClient.uploadBlockBlob(blobName, content, content.length); } catch (exception) { this.azureBlobStorageErrorHandler(exception); } @@ -126,7 +122,7 @@ export class AzureBlobStorage implements IStorageProvider { */ public async deleteFile(blobName: string, ignoreNotFound?: boolean, ignoreForbidden?: boolean): Promise { try { - await this.getBlockBlobURL(blobName).delete(Aborter.none); + await this.containerClient.deleteBlob(blobName); } catch (exception) { this.azureBlobStorageErrorHandler(exception, ignoreNotFound, ignoreForbidden); } @@ -143,33 +139,11 @@ export class AzureBlobStorage implements IStorageProvider { public async listFiles(path?: string, ext?: string): Promise { try { const result: string[] = []; - let marker; - const containerURL = new ContainerURL(this.options.sas, StorageURL.newPipeline(this.getCredential())); - do { - const pathIsString = typeof path === "string"; - if (pathIsString && path.length > 0 && path[path.length - 1] !== "/") { - path += "/"; - } - const listBlobsResponse = pathIsString - ? await containerURL.listBlobHierarchySegment( - Aborter.none, - "/", - marker, - { prefix: path }) - : await containerURL.listBlobFlatSegment( - Aborter.none, - marker); - if (!listBlobsResponse.segment || !listBlobsResponse.containerName) { - throw new AzureBlobStorageError(404); + for await (const blob of this.containerClient.listBlobsFlat({ prefix: path, includeDeleted: false })) { + if ((ext && blob.name.endsWith(ext)) || !ext) { + result.push(blob.name); } - marker = listBlobsResponse.nextMarker; - for (const blob of listBlobsResponse.segment.blobItems) { - if ((ext && blob.name.endsWith(ext)) || !ext) { - result.push(blob.name); - } - } - } while (marker); - + } return result; } catch (exception) { this.azureBlobStorageErrorHandler(exception); @@ -192,9 +166,8 @@ export class AzureBlobStorage implements IStorageProvider { * provider, this function creates that container. Included to satisfy interface */ public async createContainer(containerName: string): Promise { - const containerURL = new ContainerURL(this.options.sas, StorageURL.newPipeline(this.getCredential())); try { - await containerURL.create(Aborter.none); + await this.containerClient.create(); } catch (e) { if (e.statusCode === 409) { return; @@ -212,8 +185,7 @@ export class AzureBlobStorage implements IStorageProvider { */ public async deleteContainer(containerName: string): Promise { try { - const containerURL = new ContainerURL(this.options.sas, StorageURL.newPipeline(this.getCredential())); - await containerURL.delete(Aborter.none); + await this.containerClient.delete(); } catch (exception) { this.azureBlobStorageErrorHandler(exception); } @@ -259,38 +231,8 @@ export class AzureBlobStorage implements IStorageProvider { return assetType === AssetType.Image || assetType === AssetType.TIFF || assetType === AssetType.PDF; } - /** - * Gets a Credential object. OAuthToken if specified in options, anonymous - * credential otherwise (uses the SAS token) - * @returns - Credential object from Azure Storage SDK - */ - private getCredential(): Credential { - if (this.options.oauthToken) { - return new TokenCredential(this.options.oauthToken); - } else { - return new AnonymousCredential(); - } - } - - private getBlockBlobURL(blobName: string): BlockBlobURL { - const containerURL = new ContainerURL(this.options.sas, StorageURL.newPipeline(this.getCredential())); - return BlockBlobURL.fromContainerURL(containerURL, blobName); - } - private getUrl(blobName: string): string { - return this.getBlockBlobURL(blobName).url; - } - - private async bodyToString( - response: { - readableStreamBody?: NodeJS.ReadableStream; - blobBody?: Promise; - }, - // tslint:disable-next-line:variable-name - _length?: number, - ): Promise { - const blob = await response.blobBody!; - return this.blobToString(blob); + return this.containerClient.getBlobClient(blobName).url; } private async blobToString(blob: Blob): Promise { @@ -304,6 +246,16 @@ export class AzureBlobStorage implements IStorageProvider { fileReader.readAsText(blob); }); } + private async blobToArrayBuffer(blob: Blob): Promise { + const fileReader = new FileReader(); + return new Promise((resolve, reject) => { + fileReader.onloadend = (ev: any) => { + resolve(ev.target!.result); + }; + fileReader.onerror = reject; + fileReader.readAsArrayBuffer(blob); + }); + } private azureBlobStorageErrorHandler = (exception, ignoreNotFound?: boolean, ignoreForbidden?: boolean) => { const appError = this.toAppError(exception); diff --git a/yarn.lock b/yarn.lock index 7f50266b1..27e0cb3a0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7,27 +7,106 @@ resolved "https://registry.yarnpkg.com/7zip-bin/-/7zip-bin-5.0.3.tgz#bc5b5532ecafd923a61f2fb097e3b108c0106a3f" integrity sha512-GLyWIFBbGvpKPGo55JyRZAo4lVbnBiD52cKlw/0Vt+wnmKvWJkpZvsjVoaIolyBXDeAQKSicRtqFNPem9w0WYA== -"@azure/ms-rest-js@1.2.3": - version "1.2.3" - resolved "https://registry.yarnpkg.com/@azure/ms-rest-js/-/ms-rest-js-1.2.3.tgz#0f08d9ce2e4b681b0348cfd774ae5f37371f1ce7" - integrity sha512-eROQ034b+9v0Hd3wETKi/EwF5pqS3VRAk1Lm8iKVPOP8v30f6Zfzsi420MRfBMsbNCx/mE2N0L65Px7tvcGfVg== - dependencies: - axios "^0.18.0" - form-data "^2.3.2" - tough-cookie "^2.4.3" - tslib "^1.9.2" - uuid "^3.2.1" +"@azure/abort-controller@^1.0.0": + version "1.0.1" + resolved "https://registry.npm.taobao.org/@azure/abort-controller/download/@azure/abort-controller-1.0.1.tgz#8510935b25ac051e58920300e9d7b511ca6e656a" + integrity sha1-hRCTWyWsBR5YkgMA6de1EcpuZWo= + dependencies: + tslib "^1.9.3" + +"@azure/core-asynciterator-polyfill@^1.0.0": + version "1.0.0" + resolved "https://registry.npm.taobao.org/@azure/core-asynciterator-polyfill/download/@azure/core-asynciterator-polyfill-1.0.0.tgz#dcccebb88406e5c76e0e1d52e8cc4c43a68b3ee7" + integrity sha1-3MzruIQG5cduDh1S6MxMQ6aLPuc= + +"@azure/core-auth@^1.1.3": + version "1.1.3" + resolved "https://registry.npm.taobao.org/@azure/core-auth/download/@azure/core-auth-1.1.3.tgz#94e7bbc207010e7a2fdba61565443e4e1cf1e131" + integrity sha1-lOe7wgcBDnov26YVZUQ+Thzx4TE= + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-tracing" "1.0.0-preview.8" + "@opentelemetry/api" "^0.6.1" + tslib "^2.0.0" + +"@azure/core-http@^1.1.1": + version "1.1.6" + resolved "https://registry.npm.taobao.org/@azure/core-http/download/@azure/core-http-1.1.6.tgz#9d76bc569c9907e3224bd09c09b4ac08bde9faf8" + integrity sha1-nXa8VpyZB+MiS9CcCbSsCL3p+vg= + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-auth" "^1.1.3" + "@azure/core-tracing" "1.0.0-preview.9" + "@azure/logger" "^1.0.0" + "@opentelemetry/api" "^0.10.2" + "@types/node-fetch" "^2.5.0" + "@types/tunnel" "^0.0.1" + form-data "^3.0.0" + node-fetch "^2.6.0" + process "^0.11.10" + tough-cookie "^4.0.0" + tslib "^2.0.0" + tunnel "^0.0.6" + uuid "^8.1.0" xml2js "^0.4.19" -"@azure/storage-blob@10.3.0": - version "10.3.0" - resolved "https://registry.yarnpkg.com/@azure/storage-blob/-/storage-blob-10.3.0.tgz#a93043dce9a2b136b306ef00d1ef14bea49dde73" - integrity sha512-KZbJ3q8RpAdeIB5Em1lgXkiq7Mll9bSHHbHavOFMepkkF7HQa3Sez9FdkAVIkVVWK5YoBlshBGZ+mtiSQiS9Fw== +"@azure/core-lro@^1.0.2": + version "1.0.2" + resolved "https://registry.npm.taobao.org/@azure/core-lro/download/@azure/core-lro-1.0.2.tgz#b7b51ff7b84910b7eb152a706b0531d020864f31" + integrity sha1-t7Uf97hJELfrFSpwawUx0CCGTzE= + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-http" "^1.1.1" + events "^3.0.0" + tslib "^1.10.0" + +"@azure/core-paging@^1.1.1": + version "1.1.1" + resolved "https://registry.npm.taobao.org/@azure/core-paging/download/@azure/core-paging-1.1.1.tgz#9639d2d5b6631d481d81040504e0e26c003f47b1" + integrity sha1-ljnS1bZjHUgdgQQFBODibAA/R7E= + dependencies: + "@azure/core-asynciterator-polyfill" "^1.0.0" + +"@azure/core-tracing@1.0.0-preview.8": + version "1.0.0-preview.8" + resolved "https://registry.npm.taobao.org/@azure/core-tracing/download/@azure/core-tracing-1.0.0-preview.8.tgz#1e0ff857e855edb774ffd33476003c27b5bb2705" + integrity sha1-Hg/4V+hV7bd0/9M0dgA8J7W7JwU= + dependencies: + "@opencensus/web-types" "0.0.7" + "@opentelemetry/api" "^0.6.1" + tslib "^1.10.0" + +"@azure/core-tracing@1.0.0-preview.9": + version "1.0.0-preview.9" + resolved "https://registry.npm.taobao.org/@azure/core-tracing/download/@azure/core-tracing-1.0.0-preview.9.tgz#84f3b85572013f9d9b85e1e5d89787aa180787eb" + integrity sha1-hPO4VXIBP52bheHl2JeHqhgHh+s= + dependencies: + "@opencensus/web-types" "0.0.7" + "@opentelemetry/api" "^0.10.2" + tslib "^2.0.0" + +"@azure/logger@^1.0.0": + version "1.0.0" + resolved "https://registry.npm.taobao.org/@azure/logger/download/@azure/logger-1.0.0.tgz#48b371dfb34288c8797e5c104f6c4fb45bf1772c" + integrity sha1-SLNx37NCiMh5flwQT2xPtFvxdyw= dependencies: - "@azure/ms-rest-js" "1.2.3" - events "3.0.0" tslib "^1.9.3" +"@azure/storage-blob@12.1.2": + version "12.1.2" + resolved "https://registry.npm.taobao.org/@azure/storage-blob/download/@azure/storage-blob-12.1.2.tgz#046d146a3bd2622b61d6bdc5708955893a5b4f04" + integrity sha1-BG0UajvSYith1r3FcIlViTpbTwQ= + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-http" "^1.1.1" + "@azure/core-lro" "^1.0.2" + "@azure/core-paging" "^1.1.1" + "@azure/core-tracing" "1.0.0-preview.8" + "@azure/logger" "^1.0.0" + "@opentelemetry/api" "^0.6.1" + events "^3.0.0" + tslib "^1.10.0" + "@babel/code-frame@7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" @@ -1527,6 +1606,35 @@ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== +"@opencensus/web-types@0.0.7": + version "0.0.7" + resolved "https://registry.npm.taobao.org/@opencensus/web-types/download/@opencensus/web-types-0.0.7.tgz#4426de1fe5aa8f624db395d2152b902874f0570a" + integrity sha1-RCbeH+Wqj2JNs5XSFSuQKHTwVwo= + +"@opentelemetry/api@^0.10.2": + version "0.10.2" + resolved "https://registry.npm.taobao.org/@opentelemetry/api/download/@opentelemetry/api-0.10.2.tgz#9647b881f3e1654089ff7ea59d587b2d35060654" + integrity sha1-lke4gfPhZUCJ/36lnVh7LTUGBlQ= + dependencies: + "@opentelemetry/context-base" "^0.10.2" + +"@opentelemetry/api@^0.6.1": + version "0.6.1" + resolved "https://registry.npm.taobao.org/@opentelemetry/api/download/@opentelemetry/api-0.6.1.tgz#a00b504801f408230b9ad719716fe91ad888c642" + integrity sha1-oAtQSAH0CCMLmtcZcW/pGtiIxkI= + dependencies: + "@opentelemetry/context-base" "^0.6.1" + +"@opentelemetry/context-base@^0.10.2": + version "0.10.2" + resolved "https://registry.npm.taobao.org/@opentelemetry/context-base/download/@opentelemetry/context-base-0.10.2.tgz#55bea904b2b91aa8a8675df9eaba5961bddb1def" + integrity sha1-Vb6pBLK5GqioZ1356rpZYb3bHe8= + +"@opentelemetry/context-base@^0.6.1": + version "0.6.1" + resolved "https://registry.npm.taobao.org/@opentelemetry/context-base/download/@opentelemetry/context-base-0.6.1.tgz#b260e454ee4f9635ea024fc83be225e397f15363" + integrity sha1-smDkVO5PljXqAk/IO+Il45fxU2M= + "@sindresorhus/is@^0.14.0": version "0.14.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" @@ -1778,6 +1886,14 @@ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== +"@types/node-fetch@^2.5.0": + version "2.5.7" + resolved "https://registry.npm.taobao.org/@types/node-fetch/download/@types/node-fetch-2.5.7.tgz?cache=0&sync_timestamp=1596840698879&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnode-fetch%2Fdownload%2F%40types%2Fnode-fetch-2.5.7.tgz#20a2afffa882ab04d44ca786449a276f9f6bbf3c" + integrity sha1-IKKv/6iCqwTUTKeGRJonb59rvzw= + dependencies: + "@types/node" "*" + form-data "^3.0.0" + "@types/node@*": version "14.0.10" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.10.tgz#dbfaa170bd9eafccccb6d7060743a761b0844afd" @@ -1877,6 +1993,13 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== +"@types/tunnel@^0.0.1": + version "0.0.1" + resolved "https://registry.npm.taobao.org/@types/tunnel/download/@types/tunnel-0.0.1.tgz#0d72774768b73df26f25df9184273a42da72b19c" + integrity sha1-DXJ3R2i3PfJvJd+RhCc6QtpysZw= + dependencies: + "@types/node" "*" + "@types/yargs-parser@*": version "15.0.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d" @@ -2679,14 +2802,6 @@ axios@*, axios@^0.19.0: dependencies: follow-redirects "1.5.10" -axios@^0.18.0: - version "0.18.1" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.18.1.tgz#ff3f0de2e7b5d180e757ad98000f1081b87bcea3" - integrity sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g== - dependencies: - follow-redirects "1.5.10" - is-buffer "^2.0.2" - axobject-query@^2.0.2: version "2.1.2" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.1.2.tgz#2bdffc0371e643e5f03ba99065d5179b9ca79799" @@ -3682,10 +3797,10 @@ color@^3.0.0: color-convert "^1.9.1" color-string "^1.5.2" -combined-stream@^1.0.6, combined-stream@~1.0.6: +combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + resolved "https://registry.npm.taobao.org/combined-stream/download/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha1-w9RaizT9cwYxoRCoolIGgrMdWn8= dependencies: delayed-stream "~1.0.0" @@ -5224,11 +5339,6 @@ eventemitter3@^4.0.0: resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384" integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ== -events@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88" - integrity sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA== - events@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/events/-/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59" @@ -5708,13 +5818,13 @@ fork-ts-checker-webpack-plugin@3.1.1: tapable "^1.0.0" worker-rpc "^0.1.0" -form-data@^2.3.2: - version "2.5.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" - integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== +form-data@^3.0.0: + version "3.0.0" + resolved "https://registry.npm.taobao.org/form-data/download/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682" + integrity sha1-MbfjnIXxNVtxOe4MZHzw3n+DxoI= dependencies: asynckit "^0.4.0" - combined-stream "^1.0.6" + combined-stream "^1.0.8" mime-types "^2.1.12" form-data@~2.3.2: @@ -6763,11 +6873,6 @@ is-buffer@^1.0.2, is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-buffer@^2.0.2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" - integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== - is-callable@^1.1.4, is-callable@^1.1.5: version "1.2.0" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb" @@ -8576,6 +8681,11 @@ node-dir@^0.1.10: dependencies: minimatch "^3.0.2" +node-fetch@^2.6.0: + version "2.6.0" + resolved "https://registry.npm.taobao.org/node-fetch/download/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" + integrity sha1-5jNFY4bUqlWGP2dqerDaqP3ssP0= + node-forge@0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579" @@ -10275,10 +10385,10 @@ pseudomap@^1.0.2: resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= -psl@^1.1.28: +psl@^1.1.28, psl@^1.1.33: version "1.8.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" - integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + resolved "https://registry.npm.taobao.org/psl/download/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha1-kyb4vPsBOtzABf3/BWrM4CDlHCQ= public-encrypt@^4.0.0: version "4.0.3" @@ -12583,7 +12693,7 @@ token-types@^2.0.0: "@tokenizer/token" "^0.1.0" ieee754 "^1.1.13" -tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@^2.4.3, tough-cookie@^2.5.0, tough-cookie@~2.5.0: +tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@^2.5.0, tough-cookie@~2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== @@ -12591,6 +12701,15 @@ tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@^2.4.3, tough-cookie@^2.5 psl "^1.1.28" punycode "^2.1.1" +tough-cookie@^4.0.0: + version "4.0.0" + resolved "https://registry.npm.taobao.org/tough-cookie/download/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" + integrity sha1-2CIjTuyogvmR8PkIgkrSYi3b7OQ= + dependencies: + psl "^1.1.33" + punycode "^2.1.1" + universalify "^0.1.2" + tr46@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" @@ -12638,11 +12757,16 @@ ts-pnp@^1.1.6: resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== -tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.2, tslib@^1.9.3: +tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: version "1.13.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== +tslib@^2.0.0: + version "2.0.1" + resolved "https://registry.npm.taobao.org/tslib/download/tslib-2.0.1.tgz?cache=0&sync_timestamp=1596752024863&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftslib%2Fdownload%2Ftslib-2.0.1.tgz#410eb0d113e5b6356490eec749603725b021b43e" + integrity sha1-QQ6w0RPltjVkkO7HSWA3JbAhtD4= + tslint@^6.1.1: version "6.1.2" resolved "https://registry.yarnpkg.com/tslint/-/tslint-6.1.2.tgz#2433c248512cc5a7b2ab88ad44a6b1b34c6911cf" @@ -12824,10 +12948,10 @@ unique-string@^2.0.0: dependencies: crypto-random-string "^2.0.0" -universalify@^0.1.0: +universalify@^0.1.0, universalify@^0.1.2: version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + resolved "https://registry.npm.taobao.org/universalify/download/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha1-tkb2m+OULavOzJ1mOcgNwQXvqmY= universalify@^1.0.0: version "1.0.0" @@ -12984,11 +13108,16 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= -uuid@^3.0.1, uuid@^3.2.1, uuid@^3.3.2: +uuid@^3.0.1, uuid@^3.3.2: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== +uuid@^8.1.0: + version "8.3.0" + resolved "https://registry.npm.taobao.org/uuid/download/uuid-8.3.0.tgz?cache=0&sync_timestamp=1595886825323&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fuuid%2Fdownload%2Fuuid-8.3.0.tgz#ab738085ca22dc9a8c92725e459b1d507df5d6ea" + integrity sha1-q3OAhcoi3JqMknJeRZsdUH311uo= + v8-compile-cache@2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe"