diff --git a/libraries/botbuilder-ai/etc/botbuilder-ai.api.md b/libraries/botbuilder-ai/etc/botbuilder-ai.api.md index 780e37e44e..9ef1042fcf 100644 --- a/libraries/botbuilder-ai/etc/botbuilder-ai.api.md +++ b/libraries/botbuilder-ai/etc/botbuilder-ai.api.md @@ -28,7 +28,7 @@ import { ObjectExpression } from 'adaptive-expressions'; import { Recognizer } from 'botbuilder-dialogs'; import { RecognizerConfiguration } from 'botbuilder-dialogs'; import { RecognizerResult } from 'botbuilder-core'; -import { RequestOptionsBase } from '@azure/core-http'; +import { RequestOptionsBase } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; import { ServiceCollection } from 'botbuilder-dialogs-adaptive-runtime-core'; import { StringExpression } from 'adaptive-expressions'; import { TemplateInterface } from 'botbuilder-dialogs'; diff --git a/libraries/botbuilder-ai/package.json b/libraries/botbuilder-ai/package.json index 01c382a39f..21f0c1d16c 100644 --- a/libraries/botbuilder-ai/package.json +++ b/libraries/botbuilder-ai/package.json @@ -27,12 +27,12 @@ } }, "dependencies": { - "@azure/core-http": "^3.0.4", "adaptive-expressions": "4.1.6", "botbuilder-core": "4.1.6", "botbuilder-dialogs": "4.1.6", "botbuilder-dialogs-adaptive-runtime-core": "4.1.6", "botbuilder-dialogs-declarative": "4.1.6", + "botbuilder-stdlib": "4.1.6", "botframework-connector": "4.1.6", "lodash": "^4.17.21", "node-fetch": "^2.7.0", diff --git a/libraries/botbuilder-ai/src/luisRecognizer.ts b/libraries/botbuilder-ai/src/luisRecognizer.ts index a40b8afb6e..310c240b9c 100644 --- a/libraries/botbuilder-ai/src/luisRecognizer.ts +++ b/libraries/botbuilder-ai/src/luisRecognizer.ts @@ -5,7 +5,7 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. */ -import { RequestOptionsBase } from '@azure/core-http'; +import { RequestOptionsBase } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; import Url from 'url-parse'; import { BotTelemetryClient, NullTelemetryClient, RecognizerResult, TurnContext } from 'botbuilder-core'; diff --git a/libraries/botbuilder-ai/src/luisRuntimeClientContext.ts b/libraries/botbuilder-ai/src/luisRuntimeClientContext.ts index c7df9e844c..dd6a5635df 100644 --- a/libraries/botbuilder-ai/src/luisRuntimeClientContext.ts +++ b/libraries/botbuilder-ai/src/luisRuntimeClientContext.ts @@ -4,14 +4,17 @@ * license information. */ -import { ServiceClient, ServiceClientCredentials, ServiceClientOptions } from '@azure/core-http'; +import { + ServiceClientContext, + ServiceClientCredentials, + ServiceClientOptions, +} from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; /** * Client for LUIS context */ -export class LUISRuntimeClientContext extends ServiceClient { +export class LUISRuntimeClientContext extends ServiceClientContext { endpoint: string; - credentials: ServiceClientCredentials; /** * Initializes a new instance of the LUISRuntimeClientContext class. @@ -33,11 +36,10 @@ export class LUISRuntimeClientContext extends ServiceClient { options = {}; } - super(credentials, options); + const baseUri = options?.baseUri || `${endpoint}/luis/v3.0-preview`; + + super(credentials, { ...options, baseUri }); - this.baseUri = '{Endpoint}/luis/v3.0-preview'; - this.requestContentType = 'application/json; charset=utf-8'; this.endpoint = endpoint; - this.credentials = credentials; } } diff --git a/libraries/botbuilder-ai/src/luisV2-models/luisMappers.ts b/libraries/botbuilder-ai/src/luisV2-models/luisMappers.ts index a33169405b..cd84bff8ad 100644 --- a/libraries/botbuilder-ai/src/luisV2-models/luisMappers.ts +++ b/libraries/botbuilder-ai/src/luisV2-models/luisMappers.ts @@ -6,7 +6,7 @@ * Licensed under the MIT License. */ -import { CompositeMapper } from '@azure/core-http'; +import { CompositeMapper } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; export const IntentModel: CompositeMapper = { serializedName: 'IntentModel', diff --git a/libraries/botbuilder-ai/src/luisV2-models/luisModels.ts b/libraries/botbuilder-ai/src/luisV2-models/luisModels.ts index 367bb25983..1c065ab869 100644 --- a/libraries/botbuilder-ai/src/luisV2-models/luisModels.ts +++ b/libraries/botbuilder-ai/src/luisV2-models/luisModels.ts @@ -4,7 +4,7 @@ * license information. */ -import { RequestOptionsBase, HttpResponse } from '@azure/core-http'; +import { RequestOptionsBase, HttpOperationResponse as HttpResponse } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; /** * Represents an intent prediction. diff --git a/libraries/botbuilder-ai/src/luisV2-models/luisParameters.ts b/libraries/botbuilder-ai/src/luisV2-models/luisParameters.ts index 8ff31939a0..2b8ce3a5e2 100644 --- a/libraries/botbuilder-ai/src/luisV2-models/luisParameters.ts +++ b/libraries/botbuilder-ai/src/luisV2-models/luisParameters.ts @@ -6,7 +6,7 @@ * Licensed under the MIT License. */ -import { OperationURLParameter, OperationQueryParameter } from '@azure/core-http'; +import { OperationURLParameter, OperationQueryParameter } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; export const appId: OperationURLParameter = { parameterPath: 'appId', diff --git a/libraries/botbuilder-ai/src/luisV2-models/luisPrediction.ts b/libraries/botbuilder-ai/src/luisV2-models/luisPrediction.ts index 54c1e950d8..9a4aeadaf9 100644 --- a/libraries/botbuilder-ai/src/luisV2-models/luisPrediction.ts +++ b/libraries/botbuilder-ai/src/luisV2-models/luisPrediction.ts @@ -6,7 +6,7 @@ * Licensed under the MIT License. */ -import { ServiceCallback, OperationSpec, Serializer } from '@azure/core-http'; +import { ServiceCallback, OperationSpec, createSerializer } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; import { LUISRuntimeClientContext } from '../luisRuntimeClientContext'; import { LuisResult, PredictionResolveOptionalParams, PredictionResolveResponse } from './luisResult'; import * as Parameters from './luisParameters'; @@ -83,7 +83,7 @@ export class LuisPrediction { } // Operation Specifications -const serializer = new Serializer(Mappers); +const serializer = createSerializer(Mappers); const resolveOperationSpec: OperationSpec = { httpMethod: 'POST', path: 'apps/{appId}', diff --git a/libraries/botbuilder-ai/src/luisV2-models/luisResult.ts b/libraries/botbuilder-ai/src/luisV2-models/luisResult.ts index 3c4feb8ffd..2094bf5c83 100644 --- a/libraries/botbuilder-ai/src/luisV2-models/luisResult.ts +++ b/libraries/botbuilder-ai/src/luisV2-models/luisResult.ts @@ -7,7 +7,7 @@ */ import { Sentiment } from './luisModels'; -import { HttpResponse, RequestOptionsBase } from '@azure/core-http'; +import { HttpOperationResponse as HttpResponse, RequestOptionsBase } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; /** * Prediction, based on the input query, containing intent(s) and entities. diff --git a/libraries/botbuilder-ai/src/luisV2-models/luisRuntimeClientV2.ts b/libraries/botbuilder-ai/src/luisV2-models/luisRuntimeClientV2.ts index 8e1ee25a77..d9a6df1413 100644 --- a/libraries/botbuilder-ai/src/luisV2-models/luisRuntimeClientV2.ts +++ b/libraries/botbuilder-ai/src/luisV2-models/luisRuntimeClientV2.ts @@ -6,7 +6,7 @@ * Licensed under the MIT License. */ -import { ServiceClientCredentials, ServiceClientOptions } from '@azure/core-http'; +import { ServiceClientCredentials, ServiceClientOptions } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; import * as Models from './luisResult'; import * as Mappers from './luisMappers'; import { LuisPrediction } from './luisPrediction'; @@ -30,9 +30,9 @@ class LUISRuntimeClientV2 extends LUISRuntimeClientContext { * @param [options] The parameter options */ constructor(credentials: ServiceClientCredentials, endpoint: string, options?: ServiceClientOptions) { - super(credentials, endpoint, options); + const baseUri = options?.baseUri || `${endpoint}/luis/v2.0`; + super(credentials, endpoint, { ...options, baseUri }); this.prediction = new LuisPrediction(this); - super.baseUri = '{Endpoint}/luis/v2.0'; } } diff --git a/libraries/botbuilder-azure-blobs/etc/botbuilder-azure-blobs.api.md b/libraries/botbuilder-azure-blobs/etc/botbuilder-azure-blobs.api.md index c3b31d86db..37e0e771b4 100644 --- a/libraries/botbuilder-azure-blobs/etc/botbuilder-azure-blobs.api.md +++ b/libraries/botbuilder-azure-blobs/etc/botbuilder-azure-blobs.api.md @@ -11,7 +11,7 @@ import { Storage as Storage_2 } from 'botbuilder-core'; import { StoragePipelineOptions } from '@azure/storage-blob'; import { StorageSharedKeyCredential } from '@azure/storage-blob'; import { StoreItems } from 'botbuilder-core'; -import { TokenCredential } from '@azure/core-http'; +import { TokenCredential } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; import { TranscriptInfo } from 'botbuilder-core'; import { TranscriptStore } from 'botbuilder-core'; diff --git a/libraries/botbuilder-azure-blobs/package.json b/libraries/botbuilder-azure-blobs/package.json index 0e34526d4b..a77aa97d0c 100644 --- a/libraries/botbuilder-azure-blobs/package.json +++ b/libraries/botbuilder-azure-blobs/package.json @@ -31,8 +31,7 @@ "botbuilder-core": "4.1.6", "botbuilder-stdlib": "4.1.6", "p-map": "^4.0.0", - "zod": "^3.23.8", - "@azure/core-http": "^3.0.4" + "zod": "^3.23.8" }, "scripts": { "build": "tsc -b", diff --git a/libraries/botbuilder-azure-blobs/src/blobsStorage.ts b/libraries/botbuilder-azure-blobs/src/blobsStorage.ts index 8b6825d89c..b98b79be37 100644 --- a/libraries/botbuilder-azure-blobs/src/blobsStorage.ts +++ b/libraries/botbuilder-azure-blobs/src/blobsStorage.ts @@ -13,7 +13,7 @@ import { import { Storage, StoreItems } from 'botbuilder-core'; import { ignoreError, isStatusCodeError } from './ignoreError'; import { sanitizeBlobKey } from './sanitizeBlobKey'; -import { TokenCredential, isTokenCredential } from '@azure/core-http'; +import { TokenCredential, isTokenCredential } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; /** * Optional settings for BlobsStorage diff --git a/libraries/botbuilder-azure-blobs/src/blobsTranscriptStore.ts b/libraries/botbuilder-azure-blobs/src/blobsTranscriptStore.ts index af31ec7e7c..4facdb85b9 100644 --- a/libraries/botbuilder-azure-blobs/src/blobsTranscriptStore.ts +++ b/libraries/botbuilder-azure-blobs/src/blobsTranscriptStore.ts @@ -15,7 +15,7 @@ import { StoragePipelineOptions, StorageSharedKeyCredential, } from '@azure/storage-blob'; -import { isTokenCredential, TokenCredential } from '@azure/core-http'; +import { isTokenCredential, TokenCredential } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; // Formats a timestamp in a way that is consistent with the C# SDK function formatTicks(timestamp: Date): string { diff --git a/libraries/botbuilder-stdlib/package.json b/libraries/botbuilder-stdlib/package.json index 0f9fe3500b..f4b59bf9f6 100644 --- a/libraries/botbuilder-stdlib/package.json +++ b/libraries/botbuilder-stdlib/package.json @@ -10,6 +10,12 @@ "url": "https://github.com/Microsoft/botbuilder-js/issues" }, "dependencies": { + "@azure/core-auth": "^1.9.0", + "@azure/core-http-compat": "^2.1.2", + "@azure/core-rest-pipeline": "^1.18.1", + "@azure/core-client": "^1.9.2", + "@azure/core-tracing": "^1.2.0", + "@azure/abort-controller": "^2.1.2", "eslint-plugin-only-warn": "^1.1.0" }, "repository": { diff --git a/libraries/botbuilder-stdlib/src/azureCoreHttpCompat.ts b/libraries/botbuilder-stdlib/src/azureCoreHttpCompat.ts new file mode 100644 index 0000000000..f0fe329486 --- /dev/null +++ b/libraries/botbuilder-stdlib/src/azureCoreHttpCompat.ts @@ -0,0 +1,5 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +export * from './azureCoreHttpCompat/compat'; +export * from './azureCoreHttpCompat/serviceClientContext'; diff --git a/libraries/botbuilder-stdlib/src/azureCoreHttpCompat/compat.ts b/libraries/botbuilder-stdlib/src/azureCoreHttpCompat/compat.ts new file mode 100644 index 0000000000..95393afd7e --- /dev/null +++ b/libraries/botbuilder-stdlib/src/azureCoreHttpCompat/compat.ts @@ -0,0 +1,58 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +export * from './interfaces'; + +// Re-export only ProxySettings as it is the same as the deprecated core-http library. +export { ProxySettings } from '@azure/core-rest-pipeline'; + +// Re-export only WebResourceLike, CompatResponse, RequestPolicy as they are the same as the deprecated core-http library. +export { + WebResourceLike, + CompatResponse as HttpOperationResponse, + RequestPolicy as HttpClient, +} from '@azure/core-http-compat'; + +// Re-export. Can't access the HttpHeaders directly from the @azure/core-http-compat package because it is not defined in the package.json 'exports' property. +export { HttpHeaders } from '../../node_modules/@azure/core-http-compat/dist/commonjs/util'; + +// Re-export only TokenCredential, isTokenCredential as they are the same as the deprecated core-http library. +export { TokenCredential, isTokenCredential } from '@azure/core-auth'; + +// Re-export these as they are the same as the deprecated core-http library. +export { + createSerializer, + OperationURLParameter, + OperationQueryParameter, + OperationSpec, + CompositeMapper, +} from '@azure/core-client'; + +import { WebResourceLike } from '@azure/core-http-compat'; +import { PipelineRequestOptions, createPipelineRequest } from '@azure/core-rest-pipeline'; +import { toWebResourceLike } from '../../node_modules/@azure/core-http-compat/dist/commonjs/util'; + +/** + * Creates a new WebResourceLike object from the provided resource. + * @param resource The resource to convert to a WebResourceLike object. + * @returns A new WebResourceLike object. + */ +export function createWebResource(resource?: PipelineRequestOptions): WebResourceLike { + return toWebResourceLike(createPipelineRequest(resource ?? { url: ''})); +} + +/** + * A set of constants used internally when processing requests. + */ +export const Constants = { + /** + * Defines constants for use with HTTP headers. + */ + HeaderConstants: { + /** + * The Authorization header. + */ + AUTHORIZATION: 'Authorization', + AUTHORIZATION_SCHEME: 'Bearer', + }, +}; diff --git a/libraries/botbuilder-stdlib/src/azureCoreHttpCompat/interfaces.ts b/libraries/botbuilder-stdlib/src/azureCoreHttpCompat/interfaces.ts new file mode 100644 index 0000000000..ee803aa894 --- /dev/null +++ b/libraries/botbuilder-stdlib/src/azureCoreHttpCompat/interfaces.ts @@ -0,0 +1,219 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { TracingContext } from '@azure/core-tracing'; +import { AbortSignalLike } from '@azure/abort-controller'; +import { ProxySettings, TransferProgressEvent } from '@azure/core-rest-pipeline'; +import { DeserializationContentTypes } from '@azure/core-client'; +import { + RequestPolicyFactory, + HttpPipelineLogLevel, + RequestPolicy as HttpClient, + WebResourceLike, + CompatResponse as HttpOperationResponse, +} from '@azure/core-http-compat'; + +/** + * Represents an object or class with a `signRequest` method which will sign outgoing requests (for example, by setting the `Authorization` header). + */ +export interface ServiceClientCredentials { + /** + * Signs a request with the Authentication header. + * + * @param webResource - The WebResourceLike/request to be signed. + * @returns The signed request object; + */ + signRequest(webResource: WebResourceLike): Promise; +} + +/** + * The flattened response to a REST call. + * Contains the underlying {@link HttpOperationResponse} as well as + * the merged properties of the `parsedBody`, `parsedHeaders`, etc. + */ +export interface RestResponse { + /** + * The underlying HTTP response containing both raw and deserialized response data. + */ + _response: HttpOperationResponse; + /** + * The flattened properties described by the `OperationSpec`, deserialized from headers and the HTTP body. + */ + [key: string]: any; +} + +/** + * Options to govern behavior of xml parser and builder. + */ +interface SerializerOptions { + /** + * indicates the name of the root element in the resulting XML when building XML. + */ + rootName?: string; + /** + * indicates whether the root element is to be included or not in the output when parsing XML. + */ + includeRoot?: boolean; + /** + * key used to access the XML value content when parsing XML. + */ + xmlCharKey?: string; +} + +/** + * Describes the base structure of the options object that will be used in every operation. + */ +export interface RequestOptionsBase { + /** + * will be applied before the request is sent. + */ + customHeaders?: { + [key: string]: string; + }; + /** + * Signal of an abort controller. Can be used to abort both sending a network request and waiting for a response. + */ + abortSignal?: AbortSignalLike; + /** + * The number of milliseconds a request can take before automatically being terminated. + * If the request is terminated, an `AbortError` is thrown. + */ + timeout?: number; + /** + * Callback which fires upon upload progress. + */ + onUploadProgress?: (progress: TransferProgressEvent) => void; + /** + * Callback which fires upon download progress. + */ + onDownloadProgress?: (progress: TransferProgressEvent) => void; + /** + * Whether or not the HttpOperationResponse should be deserialized. If this is undefined, then the + * HttpOperationResponse should be deserialized. + */ + shouldDeserialize?: boolean | ((response: HttpOperationResponse) => boolean); + /** + * Tracing: Context used when creating spans. + */ + tracingContext?: TracingContext; + /** + * May contain other properties. + */ + [key: string]: any; + /** + * Options to override XML parsing/building behavior. + */ + serializerOptions?: SerializerOptions; +} + +export interface ServiceClientOptions { + /** + * (Optional) baseUri will be set automatically within BotFrameworkAdapter, + * but is required if using the ConnectorClient outside of the adapter. + */ + baseUri?: string; + /** + * An array of factories which get called to create the RequestPolicy pipeline used to send a HTTP + * request on the wire, or a function that takes in the defaultRequestPolicyFactories and returns + * the requestPolicyFactories that will be used. + */ + requestPolicyFactories?: + | RequestPolicyFactory[] + | ((defaultRequestPolicyFactories: RequestPolicyFactory[]) => void | RequestPolicyFactory[]); + /** + * The HttpClient that will be used to send HTTP requests. + */ + httpClient?: HttpClient; + /** + * The HttpPipelineLogger that can be used to debug RequestPolicies within the HTTP pipeline. + */ + httpPipelineLogger?: HttpPipelineLogger; + /** + * If set to true, turn off the default retry policy. + */ + noRetryPolicy?: boolean; + /** + * Gets or sets the retry timeout in seconds for AutomaticRPRegistration. Default value is 30. + */ + rpRegistrationRetryTimeout?: number; + /** + * Whether or not to generate a client request ID header for each HTTP request. + */ + generateClientRequestIdHeader?: boolean; + /** + * Whether to include credentials in CORS requests in the browser. + * See https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials for more information. + */ + withCredentials?: boolean; + /** + * If specified, a GenerateRequestIdPolicy will be added to the HTTP pipeline that will add a + * header to all outgoing requests with this header name and a random UUID as the request ID. + */ + clientRequestIdHeaderName?: string; + /** + * The content-types that will be associated with JSON or XML serialization. + */ + deserializationContentTypes?: DeserializationContentTypes; + /** + * The header name to use for the telemetry header while sending the request. If this is not + * specified, then "User-Agent" will be used when running on Node.js and "x-ms-useragent" will + * be used when running in a browser. + */ + userAgentHeaderName?: string | ((defaultUserAgentHeaderName: string) => string); + /** + * The string to be set to the telemetry header while sending the request, or a function that + * takes in the default user-agent string and returns the user-agent string that will be used. + */ + userAgent?: string | ((defaultUserAgent: string) => string); + /** + * Proxy settings which will be used for every HTTP request (Node.js only). + */ + proxySettings?: ProxySettings; + /** + * If specified, will be used to build the BearerTokenAuthenticationPolicy. + */ + credentialScopes?: string | string[]; +} + +export interface ServiceCallback { + /** + * A method that will be invoked as a callback to a service function. + * @param err - The error occurred if any, while executing the request; otherwise null. + * @param result - The deserialized response body if an error did not occur. + * @param request - The raw/actual request sent to the server if an error did not occur. + * @param response - The raw/actual response from the server if an error did not occur. + */ + (err: Error | null, result?: TResult, request?: WebResourceLike, response?: HttpOperationResponse): void; +} + +/** + * A Logger that can be added to a HttpPipeline. This enables each RequestPolicy to log messages + * that can be used for debugging purposes. + */ +export interface HttpPipelineLogger { + /** + * The log level threshold for what logs will be logged. + */ + minimumLogLevel: HttpPipelineLogLevel; + + /** + * Log the provided message. + * @param logLevel - The HttpLogDetailLevel associated with this message. + * @param message - The message to log. + */ + log(logLevel: HttpPipelineLogLevel, message: string): void; +} + +/** + * A collection of properties that apply to a single invocation of an operation. + */ +export interface OperationArguments { + /** + * The parameters that were passed to the operation method. + */ + [parameterName: string]: any; + /** + * The optional arugments that are provided to an operation. + */ + options?: RequestOptionsBase; +} diff --git a/libraries/botbuilder-stdlib/src/azureCoreHttpCompat/serviceClientContext.ts b/libraries/botbuilder-stdlib/src/azureCoreHttpCompat/serviceClientContext.ts new file mode 100644 index 0000000000..4897b7fc77 --- /dev/null +++ b/libraries/botbuilder-stdlib/src/azureCoreHttpCompat/serviceClientContext.ts @@ -0,0 +1,233 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + */ + +import { + ServiceClient, + OperationSpec, + OperationArguments as OperationArgumentsPipeline, + OperationRequestOptions, +} from '@azure/core-client'; +import { convertHttpClient, createRequestPolicyFactoryPolicy } from '@azure/core-http-compat'; +import { toCompatResponse } from '../../node_modules/@azure/core-http-compat/dist/commonjs/response'; +import { PipelineRequest, PipelinePolicy, createHttpHeaders } from '@azure/core-rest-pipeline'; +import { + ServiceCallback, + ServiceClientCredentials, + ServiceClientOptions, + OperationArguments, + HttpOperationResponse, + createWebResource, + RestResponse, +} from './compat'; + +export class ServiceClientContext { + /** + * If specified, this is the base URI that requests will be made against for this ServiceClient. + * If it is not specified, then all OperationSpecs must contain a baseUrl property. + */ + protected baseUri?: string; + /** + * The default request content type for the service. + * Used if no requestContentType is present on an OperationSpec. + */ + protected requestContentType?: string; + + private options: ServiceClientOptions; + private client: ServiceClient; + private readonly _requestPolicyFactories: PipelinePolicy[] = []; + + credentials: ServiceClientCredentials; + + // Protects against JSON.stringify leaking secrets + protected toJSON(): unknown { + return { name: this.constructor.name }; + } + + /** + * Initializes a new instance of the ConnectorClientContext class. + * @param credentials Subscription credentials which uniquely identify client subscription. + * @param [options] The parameter options + */ + constructor(credentials: ServiceClientCredentials, options: ServiceClientOptions = {}) { + if (credentials === null || credentials === undefined) { + throw new Error("'credentials' cannot be null."); + } + + if (!options) { + options = {}; + } + + const requestContentType = + options.deserializationContentTypes?.json?.join(' ') || + options.deserializationContentTypes?.xml?.join(' ') || + 'application/json; charset=utf-8'; + + const userAgentPrefix = + (typeof options.userAgent === 'function' ? options.userAgent('') : options.userAgent) || ''; + + const { + baseUri: endpoint, + proxySettings: proxyOptions, + httpClient, + credentialScopes, + requestPolicyFactories, + } = options; + + // do something with noPolicy option. + this.client = new ServiceClient({ + endpoint, + requestContentType, + userAgentOptions: { userAgentPrefix }, + allowInsecureConnection: endpoint?.toLowerCase().startsWith('http:'), + proxyOptions, + httpClient: httpClient ? convertHttpClient(httpClient) : undefined, + credentialScopes, + }); + + this.baseUri = endpoint; + this.requestContentType = requestContentType; + this.credentials = credentials; + this.options = options; + this._requestPolicyFactories = this.addPolicies(this.client, requestPolicyFactories); + } + + /** + * Send the provided httpRequest. + * @param request The HTTP request to send. + */ + async sendRequest(request: PipelineRequest): Promise { + if (!request) { + throw new Error('request cannot be null'); + } + + const newRequest = await this.addRequestSettings(request); + const response = await this.client.sendRequest(newRequest); + return toCompatResponse(response); + } + + /** + * Send an HTTP request that is populated using the provided OperationSpec. + * @param operationArguments - The arguments that the HTTP request's templated values will be populated from. + * @param operationSpec - The OperationSpec to use to populate the httpRequest. + * @param callback - The callback to call when the response is received. + */ + async sendOperationRequest( + operationArguments: OperationArguments, + operationSpec: OperationSpec, + callback?: ServiceCallback, + ): Promise { + if (!operationArguments) { + throw new Error('operationArguments cannot be null'); + } + + const { + customHeaders, + timeout, + onDownloadProgress, + onUploadProgress, + shouldDeserialize, + serializerOptions, + tracingContext, + ...restOptions + } = operationArguments.options || {}; + + let _response; + const requestOptions: OperationRequestOptions = {}; + const operationArgumentPipeline: OperationArgumentsPipeline = { + ...operationArguments, + options: { + ...restOptions, + requestOptions, + onResponse(rawResponse, flatResponse, error) { + _response = rawResponse; + const response = toCompatResponse(rawResponse); + callback?.(error as Error, flatResponse, response.request, response); + }, + }, + }; + + if (customHeaders) { + requestOptions.customHeaders = customHeaders; + } + + if (timeout) { + requestOptions.timeout = timeout; + } + + if (onDownloadProgress) { + requestOptions.onDownloadProgress = onDownloadProgress; + } + + if (onUploadProgress) { + requestOptions.onUploadProgress = onUploadProgress; + } + + if (shouldDeserialize) { + requestOptions.shouldDeserialize = (response) => { + if (typeof shouldDeserialize === 'function') { + return shouldDeserialize(toCompatResponse(response)); + } else if (typeof shouldDeserialize === 'boolean') { + return shouldDeserialize; + } + return true; + }; + } + + if (serializerOptions) { + operationArgumentPipeline.options!.serializerOptions = { + xml: serializerOptions, + }; + } + + if (tracingContext) { + operationArgumentPipeline.options!.tracingOptions = { + tracingContext, + }; + } + + const result = await this.client.sendOperationRequest(operationArgumentPipeline, operationSpec); + + Object.defineProperty(result, '_response', { + value: _response, + }); + + return result; + } + + private async addRequestSettings(request: PipelineRequest) { + const webResource = createWebResource(request); + await this.credentials.signRequest(webResource); + const headers = createHttpHeaders({ + ...request.headers.toJSON({ preserveCase: true }), + ...webResource.headers.toJson({ preserveCase: true }), + }); + request.withCredentials = this.options?.withCredentials === true; + request.headers = headers; + return request; + } + + private addPolicies( + client: ServiceClient, + policies: ServiceClientOptions['requestPolicyFactories'], + ): PipelinePolicy[] { + if (Array.isArray(policies)) { + const policy = createRequestPolicyFactoryPolicy(policies); + client.pipeline.removePolicy(policy); + client.pipeline.addPolicy(policy); + } else if (typeof policies === 'function') { + this.addPolicies(client, policies([]) || []); + } + + this.client.pipeline.addPolicy({ + name: 'ServiceClientContext_Credentials_SignRequest', + sendRequest: async (request, next) => { + const newRequest = await this.addRequestSettings(request); + return next(newRequest); + }, + }); + + return client.pipeline.getOrderedPolicies(); + } +} diff --git a/libraries/botbuilder-stdlib/src/index.ts b/libraries/botbuilder-stdlib/src/index.ts index f31f5d62f7..4c7f34f21c 100644 --- a/libraries/botbuilder-stdlib/src/index.ts +++ b/libraries/botbuilder-stdlib/src/index.ts @@ -3,6 +3,7 @@ export * from './types'; export * as stringExt from './stringExt'; +export * as AzureCoreHttpCompat from './azureCoreHttpCompat'; export { delay } from './delay'; export { maybeCast } from './maybeCast'; diff --git a/libraries/botbuilder/etc/botbuilder.api.md b/libraries/botbuilder/etc/botbuilder.api.md index b2c5138a13..f82abdc301 100644 --- a/libraries/botbuilder/etc/botbuilder.api.md +++ b/libraries/botbuilder/etc/botbuilder.api.md @@ -41,8 +41,8 @@ import { ExtendedUserTokenProvider } from 'botbuilder-core'; import { FileConsentCardResponse } from 'botbuilder-core'; import { GetPropertyPaneConfigurationResponse } from 'botbuilder-core'; import { HandleActionResponse } from 'botbuilder-core'; -import { HttpClient } from '@azure/core-http'; -import { HttpOperationResponse } from '@azure/core-http'; +import { HttpClient } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; +import { HttpOperationResponse } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; import { ICredentialProvider } from 'botframework-connector'; import { INodeBuffer } from 'botframework-streaming'; import { INodeDuplex } from 'botframework-streaming'; @@ -101,7 +101,7 @@ import { TranscriptInfo } from 'botbuilder-core'; import { TranscriptStore } from 'botbuilder-core'; import { TurnContext } from 'botbuilder-core'; import { UserState } from 'botbuilder-core'; -import { WebResource } from '@azure/core-http'; +import { WebResourceLike } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; // Warning: (ae-forgotten-export) The symbol "ConnectorClientBuilder" needs to be exported by the entry point index.d.ts // @@ -382,7 +382,7 @@ export class StatusCodeError extends Error { // @public export class StreamingHttpClient implements HttpClient { constructor(server: IStreamingTransportServer); - sendRequest(httpRequest: WebResource): Promise; + sendRequest(httpRequest: WebResourceLike): Promise; } // @public diff --git a/libraries/botbuilder/package.json b/libraries/botbuilder/package.json index 7d3bf49cfa..a15d4c3930 100644 --- a/libraries/botbuilder/package.json +++ b/libraries/botbuilder/package.json @@ -27,7 +27,7 @@ } }, "dependencies": { - "@azure/core-http": "^3.0.4", + "@azure/core-rest-pipeline": "^1.18.1", "@azure/msal-node": "^2.13.1", "axios": "^1.7.7", "botbuilder-core": "4.1.6", diff --git a/libraries/botbuilder/src/botFrameworkAdapter.ts b/libraries/botbuilder/src/botFrameworkAdapter.ts index 7df7cc2599..883cf22bee 100644 --- a/libraries/botbuilder/src/botFrameworkAdapter.ts +++ b/libraries/botbuilder/src/botFrameworkAdapter.ts @@ -9,7 +9,6 @@ import * as z from 'zod'; import { BotFrameworkHttpAdapter } from './botFrameworkHttpAdapter'; import { ConnectorClientBuilder, Request, Response, ResponseT, WebRequest, WebResponse } from './interfaces'; -import { HttpClient, RequestPolicyFactory, userAgentPolicy } from '@azure/core-http'; import { INodeBufferT, INodeSocketT, LogicT } from './zod'; import { arch, release, type } from 'os'; import { delay, retry } from 'botbuilder-stdlib'; @@ -1501,75 +1500,37 @@ export class BotFrameworkAdapter } private createConnectorClientInternal(serviceUrl: string, credentials: AppCredentials): ConnectorClient { + const options: ConnectorClientOptions = { ...this.settings.clientOptions }; if (BotFrameworkAdapter.isStreamingServiceUrl(serviceUrl)) { // Check if we have a streaming server. Otherwise, requesting a connector client // for a non-existent streaming connection results in an error if (!this.streamingServer) { throw new Error( - `Cannot create streaming connector client for serviceUrl ${serviceUrl} without a streaming connection. Call 'useWebSocket' or 'useNamedPipe' to start a streaming connection.` + `Cannot create streaming connector client for serviceUrl ${serviceUrl} without a streaming connection. Call 'useWebSocket' or 'useNamedPipe' to start a streaming connection.`, ); } - const clientOptions = this.getClientOptions(serviceUrl, new StreamingHttpClient(this.streamingServer)); - return new ConnectorClient(credentials, clientOptions); - } - - const clientOptions = this.getClientOptions(serviceUrl); - return new ConnectorClient(credentials, clientOptions); - } - - private getClientOptions(serviceUrl: string, httpClient?: HttpClient): ConnectorClientOptions { - const { requestPolicyFactories, ...clientOptions } = this.settings.clientOptions ?? {}; - - const options: ConnectorClientOptions = Object.assign({}, { baseUri: serviceUrl }, clientOptions); - - if (httpClient) { - options.httpClient = httpClient; + options.httpClient = new StreamingHttpClient(this.streamingServer); } + options.baseUri = serviceUrl; const userAgent = typeof options.userAgent === 'function' ? options.userAgent(USER_AGENT) : options.userAgent; - const setUserAgent = userAgentPolicy({ - value: `${USER_AGENT}${userAgent ?? ''}`, - }); - - const acceptHeader: RequestPolicyFactory = { - create: (nextPolicy) => ({ - sendRequest: (httpRequest) => { - if (!httpRequest.headers.contains('accept')) { - httpRequest.headers.set('accept', '*/*'); - } - return nextPolicy.sendRequest(httpRequest); - }, - }), - }; - - // Resolve any user request policy factories, then include our user agent via a factory policy - options.requestPolicyFactories = (defaultRequestPolicyFactories) => { - let defaultFactories = []; + options.userAgent = `${USER_AGENT} ${userAgent ?? ''}`; - if (requestPolicyFactories) { - if (typeof requestPolicyFactories === 'function') { - const newDefaultFactories = requestPolicyFactories(defaultRequestPolicyFactories); - if (newDefaultFactories) { - defaultFactories = newDefaultFactories; - } - } else if (requestPolicyFactories) { - defaultFactories = [...requestPolicyFactories]; - } - - // If the user has supplied custom factories, allow them to optionally set user agent - // before we do. - defaultFactories = [...defaultFactories, acceptHeader, setUserAgent]; - } else { - // In the case that there are no user supplied factories, inject our user agent as - // the first policy to ensure none of the default policies override it. - defaultFactories = [acceptHeader, setUserAgent, ...defaultRequestPolicyFactories]; - } - - return defaultFactories; - }; + options.requestPolicyFactories = [ + { + create: (nextPolicy) => ({ + sendRequest: (httpRequest) => { + if (!httpRequest.headers.contains('accept')) { + httpRequest.headers.set('accept', '*/*'); + } + return nextPolicy.sendRequest(httpRequest); + }, + }), + }, + ]; - return options; + return new ConnectorClient(credentials, options); } // Retrieves the ConnectorClient from the TurnContext or creates a new ConnectorClient with the provided serviceUrl and credentials. @@ -1770,10 +1731,10 @@ export class BotFrameworkAdapter ? contextOrServiceUrl.activity.serviceUrl : contextOrServiceUrl : this.settings.oAuthEndpoint - ? this.settings.oAuthEndpoint - : JwtTokenValidation.isGovernment(this.settings.channelService) - ? US_GOV_OAUTH_ENDPOINT - : OAUTH_ENDPOINT; + ? this.settings.oAuthEndpoint + : JwtTokenValidation.isGovernment(this.settings.channelService) + ? US_GOV_OAUTH_ENDPOINT + : OAUTH_ENDPOINT; } /** @@ -2172,7 +2133,7 @@ function abortWebSocketUpgrade(socket: INodeSocket, err: any): void { AuthenticationError.isStatusCodeError(err) ? (message = `HTTP/1.1 ${err.statusCode} ${StatusCodes[err.statusCode]}\r\n${ err.message - }\r\n${connectionHeader}\r\n`) + }\r\n${connectionHeader}\r\n`) : (message = AuthenticationError.determineStatusCodeAndBuildMessage(err)); socket.write(message); diff --git a/libraries/botbuilder/src/cloudAdapter.ts b/libraries/botbuilder/src/cloudAdapter.ts index c914aa8f93..9356958f79 100644 --- a/libraries/botbuilder/src/cloudAdapter.ts +++ b/libraries/botbuilder/src/cloudAdapter.ts @@ -5,7 +5,12 @@ import * as z from 'zod'; import type { BotFrameworkHttpAdapter } from './botFrameworkHttpAdapter'; import { Activity, CloudAdapterBase, InvokeResponse, StatusCodes, TurnContext } from 'botbuilder-core'; import { GET, POST, VERSION_PATH } from './streaming'; -import { HttpClient, HttpHeaders, HttpOperationResponse, WebResource } from '@azure/core-http'; +import { + HttpClient, + HttpHeaders, + HttpOperationResponse, + WebResourceLike as WebResource, +} from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; import { INodeBufferT, INodeSocketT, LogicT } from './zod'; import { Request, Response, ResponseT } from './interfaces'; import { USER_AGENT } from './botFrameworkAdapter'; diff --git a/libraries/botbuilder/src/streaming/streamingHttpClient.ts b/libraries/botbuilder/src/streaming/streamingHttpClient.ts index 0d631ba2bb..7a803d0cc0 100644 --- a/libraries/botbuilder/src/streaming/streamingHttpClient.ts +++ b/libraries/botbuilder/src/streaming/streamingHttpClient.ts @@ -6,7 +6,11 @@ * Licensed under the MIT License. */ -import { WebResource, HttpOperationResponse, HttpClient } from '@azure/core-http'; +import { + WebResourceLike as WebResource, + HttpOperationResponse, + HttpClient, +} from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; import { IStreamingTransportServer, StreamingRequest } from 'botframework-streaming'; /** diff --git a/libraries/botbuilder/tests/botFrameworkAdapter.test.js b/libraries/botbuilder/tests/botFrameworkAdapter.test.js index ca5d995d69..d22001654a 100644 --- a/libraries/botbuilder/tests/botFrameworkAdapter.test.js +++ b/libraries/botbuilder/tests/botFrameworkAdapter.test.js @@ -6,7 +6,8 @@ const sinon = require('sinon'); const { BotFrameworkAdapter } = require('../'); const { Conversations } = require('botframework-connector/lib/connectorApi/operations'); const { UserToken, BotSignIn } = require('botframework-connector/lib/tokenApi/operations'); -const { userAgentPolicy, HttpHeaders } = require('@azure/core-http'); +const { HttpHeaders } = require('botbuilder-stdlib/lib/azureCoreHttpCompat'); +const { createPipelineRequest, createHttpHeaders } = require('@azure/core-rest-pipeline'); const { ActivityTypes, @@ -461,7 +462,7 @@ describe('BotFrameworkAdapter', function () { const userAgent = 'test user agent'; nock(reference.serviceUrl) - .matchHeader('user-agent', ([val]) => val.endsWith(userAgent)) + .matchHeader('user-agent', (val) => val.includes(userAgent)) .post('/v3/conversations/convo1/activities/1234') .reply(200, { id: 'abc123id' }); @@ -509,39 +510,37 @@ describe('BotFrameworkAdapter', function () { }); it('ConnectorClient should use requestPolicyFactories from clientOptions', async function () { - const setUserAgent = userAgentPolicy({ value: 'test' }); - const factories = [setUserAgent]; - - const adapter = new BotFrameworkAdapter({ clientOptions: { requestPolicyFactories: factories } }); + const policy = { + create(){ + return { + sendRequest(){} + } + } + }; + const adapter = new BotFrameworkAdapter({ clientOptions: { requestPolicyFactories: [policy] } }); await adapter.continueConversation(reference, async (turnContext) => { const connectorClient = turnContext.turnState.get(turnContext.adapter.ConnectorClientKey); assert( - connectorClient._requestPolicyFactories.find((policy) => policy === setUserAgent), - 'requestPolicyFactories from clientOptions parameter is not used.' + connectorClient._requestPolicyFactories.find((policy) => policy === policy), + 'requestPolicyFactories from clientOptions parameter is not used.', ); }); }); it('ConnectorClient should add requestPolicyFactory for accept header', async function () { let hasAcceptHeader = false; - const mockNextPolicy = { - create: () => ({}), - sendRequest: () => { - return {}; - }, - }; const client = new BotFrameworkAdapter().createConnectorClient('https://localhost'); const length = client._requestPolicyFactories.length; for (let i = 0; i < length; i++) { - const mockHttp = { - headers: new HttpHeaders(), - }; + const mockHttp = createPipelineRequest({ + headers: createHttpHeaders(), + }); - const result = client._requestPolicyFactories[i].create(mockNextPolicy); + const result = client._requestPolicyFactories[i]; - result.sendRequest(mockHttp); + await result.sendRequest(mockHttp, (request) => ({ request, headers: mockHttp.headers })); if (mockHttp.headers.get('accept') == '*/*') { hasAcceptHeader = true; break; @@ -1363,7 +1362,7 @@ describe('BotFrameworkAdapter', function () { it('should create a User-Agent header with the same info as the host machine.', async function () { nock(reference.serviceUrl) - .matchHeader('user-agent', ([val]) => val.endsWith(userAgent)) + .matchHeader('user-agent', (val) => val.includes(userAgent)) .post('/v3/conversations/convo1/activities/1234') .reply(200, { id: 'abc123id' }); @@ -1376,7 +1375,7 @@ describe('BotFrameworkAdapter', function () { it('should still add Botbuilder User-Agent header when custom requestPolicyFactories are provided.', async function () { nock(reference.serviceUrl) - .matchHeader('user-agent', ([val]) => val.endsWith(userAgent)) + .matchHeader('user-agent', (val) => val.includes(userAgent)) .post('/v3/conversations/convo1/activities/1234') .reply(200, { id: 'abc123id' }); diff --git a/libraries/botframework-connector/package.json b/libraries/botframework-connector/package.json index 6181d9a7c9..fdcd09a8e2 100644 --- a/libraries/botframework-connector/package.json +++ b/libraries/botframework-connector/package.json @@ -27,7 +27,7 @@ } }, "dependencies": { - "@azure/core-http": "^3.0.4", + "@azure/core-rest-pipeline": "^1.18.1", "@azure/identity": "^4.4.1", "@azure/msal-node": "^2.13.1", "@types/jsonwebtoken": "9.0.6", diff --git a/libraries/botframework-connector/src/auth/appCredentials.ts b/libraries/botframework-connector/src/auth/appCredentials.ts index c02b78f940..0b9af81e08 100644 --- a/libraries/botframework-connector/src/auth/appCredentials.ts +++ b/libraries/botframework-connector/src/auth/appCredentials.ts @@ -7,7 +7,7 @@ */ import { ConfidentialClientApplication } from '@azure/msal-node'; -import { ServiceClientCredentials, WebResource } from '@azure/core-http'; +import { ServiceClientCredentials, WebResourceLike as WebResource } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; import { TokenCredentials } from './tokenCredentials'; import { AuthenticationConstants } from './authenticationConstants'; import { AuthenticatorResult } from './authenticatorResult'; diff --git a/libraries/botframework-connector/src/auth/botFrameworkClientImpl.ts b/libraries/botframework-connector/src/auth/botFrameworkClientImpl.ts index 4a78f324a5..a4e17a7ddf 100644 --- a/libraries/botframework-connector/src/auth/botFrameworkClientImpl.ts +++ b/libraries/botframework-connector/src/auth/botFrameworkClientImpl.ts @@ -8,7 +8,8 @@ import type { ConnectorClientOptions } from '../connectorApi/models'; import { ConversationIdHttpHeaderName } from '../conversationConstants'; import { ServiceClientCredentialsFactory } from './serviceClientCredentialsFactory'; import { USER_AGENT } from './connectorFactoryImpl'; -import { WebResource } from '@azure/core-http'; +import { createWebResource } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; +import { createHttpHeaders } from '@azure/core-rest-pipeline'; import { ok } from 'assert'; import axios from 'axios'; @@ -140,11 +141,16 @@ export class BotFrameworkClientImpl implements BotFrameworkClient { } activity.recipient.role = RoleTypes.Skill; - const webRequest = new WebResource(toUrl, 'POST', JSON.stringify(activity), undefined, { - Accept: 'application/json', - [ConversationIdHttpHeaderName]: conversationId, - 'Content-Type': 'application/json', - 'User-Agent': USER_AGENT, + const webRequest = createWebResource({ + url: toUrl, + method: 'POST', + body: JSON.stringify(activity), + headers: createHttpHeaders({ + Accept: 'application/json', + [ConversationIdHttpHeaderName]: conversationId, + 'Content-Type': 'application/json', + 'User-Agent': USER_AGENT, + }), }); const request = await credentials.signRequest(webRequest); diff --git a/libraries/botframework-connector/src/auth/certificateServiceClientCredentialsFactory.ts b/libraries/botframework-connector/src/auth/certificateServiceClientCredentialsFactory.ts index ff2e607caa..93158daf34 100644 --- a/libraries/botframework-connector/src/auth/certificateServiceClientCredentialsFactory.ts +++ b/libraries/botframework-connector/src/auth/certificateServiceClientCredentialsFactory.ts @@ -6,7 +6,7 @@ * Licensed under the MIT License. */ -import type { ServiceClientCredentials } from '@azure/core-http'; +import type { ServiceClientCredentials } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; import { ServiceClientCredentialsFactory } from './serviceClientCredentialsFactory'; import { ok } from 'assert'; import { CertificateAppCredentials } from './certificateAppCredentials'; diff --git a/libraries/botframework-connector/src/auth/connectorFactoryImpl.ts b/libraries/botframework-connector/src/auth/connectorFactoryImpl.ts index ea6d77a6a6..a53ecccd8f 100644 --- a/libraries/botframework-connector/src/auth/connectorFactoryImpl.ts +++ b/libraries/botframework-connector/src/auth/connectorFactoryImpl.ts @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import { getDefaultUserAgentValue, RequestPolicyFactory, userAgentPolicy } from '@azure/core-http'; import { ConnectorClient } from '../connectorApi/connectorClient'; import { ConnectorClientOptions } from '../connectorApi/models'; import { ConnectorFactory } from './connectorFactory'; @@ -9,9 +8,7 @@ import type { ServiceClientCredentialsFactory } from './serviceClientCredentials // eslint-disable-next-line @typescript-eslint/no-var-requires const packageInfo: Record<'name' | 'version', string> = require('../../package.json'); -export const USER_AGENT = `Microsoft-BotFramework/3.1 ${packageInfo.name}/${ - packageInfo.version -} ${getDefaultUserAgentValue()} `; +export const USER_AGENT = `Microsoft-BotFramework/3.1 ${packageInfo.name}/${packageInfo.version} `; /** * @internal @@ -32,7 +29,7 @@ export class ConnectorFactoryImpl extends ConnectorFactory { private readonly loginEndpoint: string, private readonly validateAuthority: boolean, private readonly credentialFactory: ServiceClientCredentialsFactory, - private readonly connectorClientOptions: ConnectorClientOptions = {} + private readonly connectorClientOptions: ConnectorClientOptions = {}, ) { super(); } @@ -48,61 +45,32 @@ export class ConnectorFactoryImpl extends ConnectorFactory { this.appId, audience ?? this.toChannelFromBotOAuthScope, this.loginEndpoint, - this.validateAuthority + this.validateAuthority, ); - // A new connector client for making calls against this serviceUrl using credentials derived from the current appId and the specified audience. - const options = this.getClientOptions(serviceUrl); - return new ConnectorClient(credentials, options); - } - - private getClientOptions(serviceUrl: string): ConnectorClientOptions { - const { requestPolicyFactories, ...clientOptions } = this.connectorClientOptions; - - const options: ConnectorClientOptions = Object.assign({}, { baseUri: serviceUrl }, clientOptions); - - const userAgent = typeof options.userAgent === 'function' ? options.userAgent(USER_AGENT) : options.userAgent; - const setUserAgent = userAgentPolicy({ - value: `${USER_AGENT}${userAgent ?? ''}`, - }); - - const acceptHeader: RequestPolicyFactory = { - create: (nextPolicy) => ({ - sendRequest: (httpRequest) => { - if (!httpRequest.headers.contains('accept')) { - httpRequest.headers.set('accept', '*/*'); - } - return nextPolicy.sendRequest(httpRequest); - }, - }), + const userAgent = + typeof this.connectorClientOptions?.userAgent === 'function' + ? this.connectorClientOptions?.userAgent(USER_AGENT) + : this.connectorClientOptions?.userAgent; + const options: ConnectorClientOptions = { + ...this.connectorClientOptions, + baseUri: serviceUrl, + userAgent: `${USER_AGENT} ${userAgent ?? ''}`, }; - // Resolve any user request policy factories, then include our user agent via a factory policy - options.requestPolicyFactories = (defaultRequestPolicyFactories) => { - let defaultFactories = []; - - if (requestPolicyFactories) { - if (typeof requestPolicyFactories === 'function') { - const newDefaultFactories = requestPolicyFactories(defaultRequestPolicyFactories); - if (newDefaultFactories) { - defaultFactories = newDefaultFactories; - } - } else if (requestPolicyFactories) { - defaultFactories = [...requestPolicyFactories]; - } - - // If the user has supplied custom factories, allow them to optionally set user agent - // before we do. - defaultFactories = [...defaultFactories, setUserAgent, acceptHeader]; - } else { - // In the case that there are no user supplied factories, inject our user agent as - // the first policy to ensure none of the default policies override it. - defaultFactories = [acceptHeader, setUserAgent, ...defaultRequestPolicyFactories]; + options.requestPolicyFactories = [ + { + create: (nextPolicy) => ({ + sendRequest: (httpRequest) => { + if (!httpRequest.headers.contains('accept')) { + httpRequest.headers.set('accept', '*/*'); + } + return nextPolicy.sendRequest(httpRequest); + }, + }), } + ] - return defaultFactories; - }; - - return options; + return new ConnectorClient(credentials, options); } } diff --git a/libraries/botframework-connector/src/auth/federatedServiceClientCredentialsFactory.ts b/libraries/botframework-connector/src/auth/federatedServiceClientCredentialsFactory.ts index 6f0df67a81..77316af6af 100644 --- a/libraries/botframework-connector/src/auth/federatedServiceClientCredentialsFactory.ts +++ b/libraries/botframework-connector/src/auth/federatedServiceClientCredentialsFactory.ts @@ -5,7 +5,7 @@ // Licensed under the MIT License. import { ok } from 'assert'; -import type { ServiceClientCredentials } from '@azure/core-http'; +import type { ServiceClientCredentials } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; import { ServiceClientCredentialsFactory } from './serviceClientCredentialsFactory'; import { FederatedAppCredentials } from './federatedAppCredentials'; diff --git a/libraries/botframework-connector/src/auth/jwtTokenExtractor.ts b/libraries/botframework-connector/src/auth/jwtTokenExtractor.ts index 36a0d6f496..a08284ff91 100644 --- a/libraries/botframework-connector/src/auth/jwtTokenExtractor.ts +++ b/libraries/botframework-connector/src/auth/jwtTokenExtractor.ts @@ -12,7 +12,7 @@ import { EndorsementsValidator } from './endorsementsValidator'; import { OpenIdMetadata } from './openIdMetadata'; import { AuthenticationError } from './authenticationError'; import { StatusCodes } from 'botframework-schema'; -import { ProxySettings } from '@azure/core-http'; +import { ProxySettings } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; /** * A JWT token processing class that gets identity information and performs security token validation. diff --git a/libraries/botframework-connector/src/auth/managedIdentityServiceClientCredentialsFactory.ts b/libraries/botframework-connector/src/auth/managedIdentityServiceClientCredentialsFactory.ts index 127b54b29e..9e4d201cfb 100644 --- a/libraries/botframework-connector/src/auth/managedIdentityServiceClientCredentialsFactory.ts +++ b/libraries/botframework-connector/src/auth/managedIdentityServiceClientCredentialsFactory.ts @@ -7,7 +7,7 @@ */ import type { IJwtTokenProviderFactory } from './jwtTokenProviderFactory'; -import type { ServiceClientCredentials } from '@azure/core-http'; +import type { ServiceClientCredentials } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; import { ManagedIdentityAppCredentials } from './managedIdentityAppCredentials'; import { ServiceClientCredentialsFactory } from './serviceClientCredentialsFactory'; import { ok } from 'assert'; diff --git a/libraries/botframework-connector/src/auth/msalServiceClientCredentialsFactory.ts b/libraries/botframework-connector/src/auth/msalServiceClientCredentialsFactory.ts index 997915d4c7..db9cffffa2 100644 --- a/libraries/botframework-connector/src/auth/msalServiceClientCredentialsFactory.ts +++ b/libraries/botframework-connector/src/auth/msalServiceClientCredentialsFactory.ts @@ -6,7 +6,7 @@ import { ConfidentialClientApplication } from '@azure/msal-node'; import { MsalAppCredentials } from './msalAppCredentials'; -import { ServiceClientCredentials } from '@azure/core-http'; +import { ServiceClientCredentials } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; import { ServiceClientCredentialsFactory } from './serviceClientCredentialsFactory'; import { AuthenticationConstants } from './authenticationConstants'; import { GovernmentConstants } from './governmentConstants'; diff --git a/libraries/botframework-connector/src/auth/openIdMetadata.ts b/libraries/botframework-connector/src/auth/openIdMetadata.ts index e926dd9e4a..8520f3253c 100644 --- a/libraries/botframework-connector/src/auth/openIdMetadata.ts +++ b/libraries/botframework-connector/src/auth/openIdMetadata.ts @@ -12,7 +12,7 @@ import fetch from 'node-fetch'; import { HttpsProxyAgent } from 'https-proxy-agent'; import { AuthenticationError } from './authenticationError'; import { StatusCodes } from 'botframework-schema'; -import { ProxySettings } from '@azure/core-http'; +import { ProxySettings } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; /** * Class in charge of manage OpenId metadata. diff --git a/libraries/botframework-connector/src/auth/passwordServiceClientCredentialFactory.ts b/libraries/botframework-connector/src/auth/passwordServiceClientCredentialFactory.ts index 2584bbcbd6..4a9ada7bb6 100644 --- a/libraries/botframework-connector/src/auth/passwordServiceClientCredentialFactory.ts +++ b/libraries/botframework-connector/src/auth/passwordServiceClientCredentialFactory.ts @@ -4,7 +4,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import type { ServiceClientCredentials } from '@azure/core-http'; +import type { ServiceClientCredentials } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; import { AuthenticationConstants } from './authenticationConstants'; import { GovernmentConstants } from './governmentConstants'; import { MicrosoftAppCredentials } from './microsoftAppCredentials'; diff --git a/libraries/botframework-connector/src/auth/serviceClientCredentialsFactory.ts b/libraries/botframework-connector/src/auth/serviceClientCredentialsFactory.ts index f790d97a21..fc3626db56 100644 --- a/libraries/botframework-connector/src/auth/serviceClientCredentialsFactory.ts +++ b/libraries/botframework-connector/src/auth/serviceClientCredentialsFactory.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import { ServiceClientCredentials } from '@azure/core-http'; +import { ServiceClientCredentials } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; // Export underlying type for convenience export { ServiceClientCredentials }; diff --git a/libraries/botframework-connector/src/auth/tokenCredentials.ts b/libraries/botframework-connector/src/auth/tokenCredentials.ts index 9614344345..e639797990 100644 --- a/libraries/botframework-connector/src/auth/tokenCredentials.ts +++ b/libraries/botframework-connector/src/auth/tokenCredentials.ts @@ -1,17 +1,14 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. -import { HttpHeaders, Constants, WebResourceLike, ServiceClientCredentials } from '@azure/core-http'; - -const HeaderConstants = Constants.HeaderConstants; -const DEFAULT_AUTHORIZATION_SCHEME = 'Bearer'; +import { HttpHeaders, Constants, WebResourceLike, ServiceClientCredentials } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; /** * A credentials object that uses a token string and a authorzation scheme to authenticate. */ export class TokenCredentials implements ServiceClientCredentials { token: string; - authorizationScheme: string = DEFAULT_AUTHORIZATION_SCHEME; + authorizationScheme: string = Constants.HeaderConstants.AUTHORIZATION_SCHEME; /** * Creates a new TokenCredentials object. @@ -20,7 +17,7 @@ export class TokenCredentials implements ServiceClientCredentials { * @param {string} token The token. * @param {string} [authorizationScheme] The authorization scheme. */ - constructor(token: string, authorizationScheme: string = DEFAULT_AUTHORIZATION_SCHEME) { + constructor(token: string, authorizationScheme: string = Constants.HeaderConstants.AUTHORIZATION_SCHEME) { if (!token) { throw new Error('token cannot be null or undefined.'); } @@ -34,9 +31,9 @@ export class TokenCredentials implements ServiceClientCredentials { * @param {WebResourceLike} webResource The WebResourceLike to be signed. * @returns {Promise} The signed request object. */ - signRequest(webResource: WebResourceLike) { + signRequest(webResource: WebResourceLike): Promise { if (!webResource.headers) webResource.headers = new HttpHeaders(); - webResource.headers.set(HeaderConstants.AUTHORIZATION, `${this.authorizationScheme} ${this.token}`); + webResource.headers.set(Constants.HeaderConstants.AUTHORIZATION, `${this.authorizationScheme} ${this.token}`); return Promise.resolve(webResource); } } diff --git a/libraries/botframework-connector/src/auth/userTokenClientImpl.ts b/libraries/botframework-connector/src/auth/userTokenClientImpl.ts index 7946648ee1..d198dd148d 100644 --- a/libraries/botframework-connector/src/auth/userTokenClientImpl.ts +++ b/libraries/botframework-connector/src/auth/userTokenClientImpl.ts @@ -2,7 +2,7 @@ // Licensed under the MIT License. import * as z from 'zod'; -import type { ServiceClientCredentials } from '@azure/core-http'; +import type { ServiceClientCredentials } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; import { Activity, SignInUrlResponse, TokenExchangeRequest, TokenResponse, TokenStatus } from 'botframework-schema'; import { ConnectorClientOptions } from '../connectorApi/models'; import { TokenApiClient } from '../tokenApi/tokenApiClient'; diff --git a/libraries/botframework-connector/src/connectorApi/connectorClient.ts b/libraries/botframework-connector/src/connectorApi/connectorClient.ts index f5f320d3f8..250f25e714 100644 --- a/libraries/botframework-connector/src/connectorApi/connectorClient.ts +++ b/libraries/botframework-connector/src/connectorApi/connectorClient.ts @@ -5,12 +5,11 @@ import * as Mappers from './models/mappers'; import * as Models from './models'; -import { ServiceClientCredentials } from '@azure/core-http'; +import { ServiceClientCredentials } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; import * as operations from './operations'; import { ConnectorClientContext } from './connectorClientContext'; class ConnectorClient extends ConnectorClientContext { - // Operation groups attachments: operations.Attachments; conversations: operations.Conversations; diff --git a/libraries/botframework-connector/src/connectorApi/connectorClientContext.ts b/libraries/botframework-connector/src/connectorApi/connectorClientContext.ts index 02b0abede9..e927f66ec5 100644 --- a/libraries/botframework-connector/src/connectorApi/connectorClientContext.ts +++ b/libraries/botframework-connector/src/connectorApi/connectorClientContext.ts @@ -2,39 +2,23 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. */ - -import { ServiceClient, ServiceClientCredentials, getDefaultUserAgentValue } from "@azure/core-http"; +import { ServiceClientContext, ServiceClientCredentials } from "botbuilder-stdlib/lib/azureCoreHttpCompat"; import * as Models from "./models"; -const packageName = "botframework-connector"; -const packageVersion = "4.0.0"; - -export class ConnectorClientContext extends ServiceClient { - credentials: ServiceClientCredentials; - - /** - * Initializes a new instance of the ConnectorClientContext class. - * @param credentials Subscription credentials which uniquely identify client subscription. - * @param [options] The parameter options - */ - constructor(credentials: ServiceClientCredentials, options?: Models.ConnectorClientOptions) { - if (credentials === null || credentials === undefined) { - throw new Error('\'credentials\' cannot be null.'); - } - - if (!options) { - // NOTE: autogen creates a {} which is invalid, it needs to be cast - options = {} as Models.ConnectorClientOptions; +const packageName = 'botframework-connector'; +const packageVersion = '4.0.0'; + +export class ConnectorClientContext extends ServiceClientContext { + /** + * Initializes a new instance of the ConnectorClientContext class. + * @param credentials Subscription credentials which uniquely identify client subscription. + * @param [options] The parameter options + */ + constructor(credentials: ServiceClientCredentials, options?: Models.ConnectorClientOptions) { + super(credentials, { + ...options, + baseUri: options?.baseUri || 'https://api.botframework.com', + userAgent: `${packageName}/${packageVersion} ${options?.userAgent || ''}`, + }); } - // TODO This is to workaround fact that AddUserAgent() was removed. - const defaultUserAgent = getDefaultUserAgentValue(); - options.userAgent = `${packageName}/${packageVersion} ${defaultUserAgent} ${options.userAgent || ''}`; - - super(credentials, options); - - this.baseUri = options.baseUri || this.baseUri || "https://api.botframework.com"; - this.requestContentType = "application/json; charset=utf-8"; - this.credentials = credentials; - - } } diff --git a/libraries/botframework-connector/src/connectorApi/models/index.ts b/libraries/botframework-connector/src/connectorApi/models/index.ts index cb441f1a8d..649e6ab3fe 100644 --- a/libraries/botframework-connector/src/connectorApi/models/index.ts +++ b/libraries/botframework-connector/src/connectorApi/models/index.ts @@ -3,8 +3,7 @@ * Licensed under the MIT License. */ - -import { ServiceClientOptions, RequestOptionsBase, HttpResponse } from "@azure/core-http"; +import { ServiceClientOptions, RequestOptionsBase, HttpOperationResponse as HttpResponse } from "botbuilder-stdlib/lib/azureCoreHttpCompat"; import { AttachmentInfo, ChannelAccount, ConversationResourceResponse, ConversationsResult, PagedMembersResult, ResourceResponse } from "botframework-schema"; import type { Agent as HttpAgent } from "http"; import type { Agent as HttpsAgent } from "https"; @@ -14,12 +13,6 @@ export * from "botframework-schema"; * An interface representing ConnectorClientOptions. */ export interface ConnectorClientOptions extends ServiceClientOptions { - /** - * (Optional) baseUri will be set automatically within BotFrameworkAdapter, - * but is required if using the ConnectorClient outside of the adapter. - */ - baseUri?: string; - /** * HTTP and HTTPS agents which will be used for every HTTP request (Node.js only). */ diff --git a/libraries/botframework-connector/src/connectorApi/models/mappers.ts b/libraries/botframework-connector/src/connectorApi/models/mappers.ts index b6b104410b..146eef1521 100644 --- a/libraries/botframework-connector/src/connectorApi/models/mappers.ts +++ b/libraries/botframework-connector/src/connectorApi/models/mappers.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. */ -import { CompositeMapper } from "@azure/core-http" +import { CompositeMapper } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; export const AttachmentView: CompositeMapper = { serializedName: "AttachmentView", diff --git a/libraries/botframework-connector/src/connectorApi/models/parameters.ts b/libraries/botframework-connector/src/connectorApi/models/parameters.ts index 6b0f81797c..da296daa70 100644 --- a/libraries/botframework-connector/src/connectorApi/models/parameters.ts +++ b/libraries/botframework-connector/src/connectorApi/models/parameters.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. */ -import { OperationURLParameter, OperationQueryParameter } from "@azure/core-http" +import { OperationURLParameter, OperationQueryParameter } from "botbuilder-stdlib/lib/azureCoreHttpCompat" export const activityId: OperationURLParameter = { parameterPath: "activityId", diff --git a/libraries/botframework-connector/src/connectorApi/operations/attachments.ts b/libraries/botframework-connector/src/connectorApi/operations/attachments.ts index c28e2f0b98..3841cd6511 100644 --- a/libraries/botframework-connector/src/connectorApi/operations/attachments.ts +++ b/libraries/botframework-connector/src/connectorApi/operations/attachments.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. */ -import { RequestOptionsBase, ServiceCallback, OperationSpec, Serializer } from "@azure/core-http"; +import { RequestOptionsBase, ServiceCallback, OperationSpec, createSerializer } from "botbuilder-stdlib/lib/azureCoreHttpCompat"; import { ConnectorClientContext } from "../connectorClientContext"; import * as Models from "../models"; import * as Mappers from "../models/attachmentsMappers"; @@ -85,7 +85,7 @@ export class Attachments { } // Operation Specifications -const serializer = new Serializer(Mappers); +const serializer = createSerializer(Mappers); const getAttachmentInfoOperationSpec: OperationSpec = { httpMethod: "GET", path: "v3/attachments/{attachmentId}", diff --git a/libraries/botframework-connector/src/connectorApi/operations/conversations.ts b/libraries/botframework-connector/src/connectorApi/operations/conversations.ts index c38c3c14e1..8ac49a589e 100644 --- a/libraries/botframework-connector/src/connectorApi/operations/conversations.ts +++ b/libraries/botframework-connector/src/connectorApi/operations/conversations.ts @@ -6,7 +6,7 @@ import * as Mappers from "../models/conversationsMappers"; import * as Models from "../models"; import * as Parameters from "../models/parameters"; -import { ServiceCallback, RequestOptionsBase, RestResponse, Serializer, OperationSpec } from "@azure/core-http" +import { ServiceCallback, RequestOptionsBase, RestResponse, createSerializer, OperationSpec } from "botbuilder-stdlib/lib/azureCoreHttpCompat" import { ConnectorClientContext } from "../connectorClientContext"; import { ConversationIdHttpHeaderName } from "../../conversationConstants"; @@ -519,7 +519,7 @@ export class Conversations { } // Operation Specifications -const serializer = new Serializer(Mappers); +const serializer = createSerializer(Mappers); const getConversationsOperationSpec: OperationSpec = { httpMethod: "GET", path: "v3/conversations", diff --git a/libraries/botframework-connector/src/teams/models/index.ts b/libraries/botframework-connector/src/teams/models/index.ts index 5981690659..4e8407e7a3 100644 --- a/libraries/botframework-connector/src/teams/models/index.ts +++ b/libraries/botframework-connector/src/teams/models/index.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. */ -import { HttpResponse, ServiceClientOptions, RequestOptionsBase } from '@azure/core-http'; +import { HttpOperationResponse as HttpResponse, ServiceClientOptions, RequestOptionsBase } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; import { ConversationList, TeamDetails, diff --git a/libraries/botframework-connector/src/teams/models/mappers.ts b/libraries/botframework-connector/src/teams/models/mappers.ts index 86124cf8f2..4d52de7bf4 100644 --- a/libraries/botframework-connector/src/teams/models/mappers.ts +++ b/libraries/botframework-connector/src/teams/models/mappers.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. */ -import { CompositeMapper } from '@azure/core-http'; +import { CompositeMapper } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; export const ChannelInfo: CompositeMapper = { serializedName: 'ChannelInfo', diff --git a/libraries/botframework-connector/src/teams/models/parameters.ts b/libraries/botframework-connector/src/teams/models/parameters.ts index 4f3e13d646..bc75068b94 100644 --- a/libraries/botframework-connector/src/teams/models/parameters.ts +++ b/libraries/botframework-connector/src/teams/models/parameters.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. */ -import { OperationURLParameter, OperationQueryParameter } from '@azure/core-http'; +import { OperationURLParameter, OperationQueryParameter } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; export const teamId: OperationURLParameter = { parameterPath: 'teamId', diff --git a/libraries/botframework-connector/src/teams/operations/teams.ts b/libraries/botframework-connector/src/teams/operations/teams.ts index b3942c889b..3a8c5ec1ae 100644 --- a/libraries/botframework-connector/src/teams/operations/teams.ts +++ b/libraries/botframework-connector/src/teams/operations/teams.ts @@ -4,7 +4,7 @@ * Licensed under the MIT License. */ -import { ServiceCallback, RequestOptionsBase, Serializer, OperationSpec } from '@azure/core-http' +import { ServiceCallback, RequestOptionsBase, createSerializer, OperationSpec } from 'botbuilder-stdlib/lib/azureCoreHttpCompat' import * as Models from '../models'; import * as Mappers from '../models/teamsMappers'; import * as Parameters from '../models/parameters'; @@ -507,7 +507,7 @@ export class Teams { } // Operation Specifications -const serializer = new Serializer(Mappers); +const serializer = createSerializer(Mappers); const fetchChannelListOperationSpec: OperationSpec = { httpMethod: 'GET', path: 'v3/teams/{teamId}/conversations', diff --git a/libraries/botframework-connector/src/teams/teamsConnectorClient.ts b/libraries/botframework-connector/src/teams/teamsConnectorClient.ts index dcfff5a484..33d8e10ef2 100644 --- a/libraries/botframework-connector/src/teams/teamsConnectorClient.ts +++ b/libraries/botframework-connector/src/teams/teamsConnectorClient.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. */ -import { ServiceClientCredentials } from '@azure/core-http'; +import { ServiceClientCredentials } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; import * as Models from './models'; import * as Mappers from './models/mappers'; import * as operations from './operations'; diff --git a/libraries/botframework-connector/src/teams/teamsConnectorClientContext.ts b/libraries/botframework-connector/src/teams/teamsConnectorClientContext.ts index d1ea5a6d3e..c5e538d0d9 100644 --- a/libraries/botframework-connector/src/teams/teamsConnectorClientContext.ts +++ b/libraries/botframework-connector/src/teams/teamsConnectorClientContext.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. */ -import { ServiceClientCredentials, ServiceClient } from '@azure/core-http'; +import { ServiceClientCredentials, ServiceClientContext } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; import { TeamsConnectorClientOptions } from './models'; /** @@ -12,24 +12,16 @@ import { TeamsConnectorClientOptions } from './models'; * configured in the [Bot Framework Developer Portal](https://dev.botframework.com). * The Connector service uses industry-standard REST and JSON over HTTPS. */ -export class TeamsConnectorClientContext extends ServiceClient { - credentials: ServiceClientCredentials; - +export class TeamsConnectorClientContext extends ServiceClientContext { /** * Initializes a new instance of the TeamsConnectorClientContext class. - * * @param credentials Subscription credentials which uniquely identify client subscription. * @param [options] The parameter options */ constructor(credentials: ServiceClientCredentials, options?: TeamsConnectorClientOptions) { - if (!options) { - options = {}; - } - - super(credentials, options); - - this.baseUri = options.baseUri || this.baseUri || 'https://api.botframework.com'; - this.requestContentType = 'application/json; charset=utf-8'; - this.credentials = credentials; + super(credentials, { + ...options, + baseUri: options?.baseUri || 'https://api.botframework.com' + }); } } diff --git a/libraries/botframework-connector/src/tokenApi/models/index.ts b/libraries/botframework-connector/src/tokenApi/models/index.ts index 687310d099..5e7397fa90 100644 --- a/libraries/botframework-connector/src/tokenApi/models/index.ts +++ b/libraries/botframework-connector/src/tokenApi/models/index.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. */ -import { ServiceClientOptions, RequestOptionsBase, HttpResponse } from "@azure/core-http"; +import { ServiceClientOptions, RequestOptionsBase, HttpOperationResponse as HttpResponse } from "botbuilder-stdlib/lib/azureCoreHttpCompat"; import { SignInUrlResponse, TokenResponse, TokenStatus } from "botframework-schema"; /** diff --git a/libraries/botframework-connector/src/tokenApi/models/mappers.ts b/libraries/botframework-connector/src/tokenApi/models/mappers.ts index a92d719ecf..bd4f42cec2 100644 --- a/libraries/botframework-connector/src/tokenApi/models/mappers.ts +++ b/libraries/botframework-connector/src/tokenApi/models/mappers.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. */ -import { CompositeMapper } from "@azure/core-http"; +import { CompositeMapper } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; export const TokenExchangeResource: CompositeMapper = { serializedName: "TokenExchangeResource", diff --git a/libraries/botframework-connector/src/tokenApi/models/parameters.ts b/libraries/botframework-connector/src/tokenApi/models/parameters.ts index f6c3a94800..354bbbfe56 100644 --- a/libraries/botframework-connector/src/tokenApi/models/parameters.ts +++ b/libraries/botframework-connector/src/tokenApi/models/parameters.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. */ -import { OperationQueryParameter } from "@azure/core-http" +import { OperationQueryParameter } from "botbuilder-stdlib/lib/azureCoreHttpCompat" export const channelId0: OperationQueryParameter = { parameterPath: [ diff --git a/libraries/botframework-connector/src/tokenApi/operations/botSignIn.ts b/libraries/botframework-connector/src/tokenApi/operations/botSignIn.ts index f35b18984e..fb558a1321 100644 --- a/libraries/botframework-connector/src/tokenApi/operations/botSignIn.ts +++ b/libraries/botframework-connector/src/tokenApi/operations/botSignIn.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. */ -import { ServiceCallback, Serializer, OperationSpec } from "@azure/core-http"; +import { ServiceCallback, createSerializer, OperationSpec } from "botbuilder-stdlib/lib/azureCoreHttpCompat"; import * as Models from "../models"; import * as Mappers from "../models/botSignInMappers"; import * as Parameters from "../models/parameters"; @@ -78,7 +78,7 @@ export class BotSignIn { } // Operation Specifications -const serializer = new Serializer(Mappers); +const serializer = createSerializer(Mappers); const getSignInUrlOperationSpec: OperationSpec = { httpMethod: "GET", path: "api/botsignin/GetSignInUrl", diff --git a/libraries/botframework-connector/src/tokenApi/operations/userToken.ts b/libraries/botframework-connector/src/tokenApi/operations/userToken.ts index 4eba5a3b39..4196dbf9b1 100644 --- a/libraries/botframework-connector/src/tokenApi/operations/userToken.ts +++ b/libraries/botframework-connector/src/tokenApi/operations/userToken.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. */ -import { ServiceCallback, RequestOptionsBase, Serializer, OperationSpec } from '@azure/core-http'; +import { ServiceCallback, RequestOptionsBase, createSerializer, OperationSpec } from 'botbuilder-stdlib/lib/azureCoreHttpCompat'; import * as Models from '../models'; import * as Mappers from '../models/userTokenMappers'; import * as Parameters from '../models/parameters'; @@ -272,7 +272,7 @@ export class UserToken { } // Operation Specifications -const serializer = new Serializer(Mappers); +const serializer = createSerializer(Mappers); const getTokenOperationSpec: OperationSpec = { httpMethod: 'GET', path: 'api/usertoken/GetToken', diff --git a/libraries/botframework-connector/src/tokenApi/tokenApiClient.ts b/libraries/botframework-connector/src/tokenApi/tokenApiClient.ts index 4c432d20e4..8679c4a182 100644 --- a/libraries/botframework-connector/src/tokenApi/tokenApiClient.ts +++ b/libraries/botframework-connector/src/tokenApi/tokenApiClient.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. */ -import { ServiceClientCredentials } from "@azure/core-http"; +import { ServiceClientCredentials } from "botbuilder-stdlib/lib/azureCoreHttpCompat"; import * as Models from "./models"; import * as Mappers from "./models/mappers"; import * as operations from "./operations"; diff --git a/libraries/botframework-connector/src/tokenApi/tokenApiClientContext.ts b/libraries/botframework-connector/src/tokenApi/tokenApiClientContext.ts index 664008e07f..755261a12e 100644 --- a/libraries/botframework-connector/src/tokenApi/tokenApiClientContext.ts +++ b/libraries/botframework-connector/src/tokenApi/tokenApiClientContext.ts @@ -3,41 +3,23 @@ * Licensed under the MIT License. */ -import { ServiceClient, ServiceClientCredentials, getDefaultUserAgentValue } from "@azure/core-http"; +import { ServiceClientContext, ServiceClientCredentials } from "botbuilder-stdlib/lib/azureCoreHttpCompat"; import * as Models from "./models"; -const packageName = "botframework-Token"; -const packageVersion = "4.0.0"; - -export class TokenApiClientContext extends ServiceClient { - credentials: ServiceClientCredentials; - - // Protects against JSON.stringify leaking secrets - private toJSON(): unknown { - return { name: this.constructor.name }; - } - - /** - * Initializes a new instance of the TokenApiClientContext class. - * @param credentials Subscription credentials which uniquely identify client subscription. - * @param [options] The parameter options - */ - constructor(credentials: ServiceClientCredentials, options?: Models.TokenApiClientOptions) { - if (credentials === null || credentials === undefined) { - throw new Error('\'credentials\' cannot be null.'); - } - - if (!options) { - options = {}; +const packageName = 'botframework-token'; +const packageVersion = '4.0.0'; + +export class TokenApiClientContext extends ServiceClientContext { + /** + * Initializes a new instance of the TokenApiClientContext class. + * @param credentials Subscription credentials which uniquely identify client subscription. + * @param [options] The parameter options + */ + constructor(credentials: ServiceClientCredentials, options?: Models.TokenApiClientOptions) { + super(credentials, { + ...options, + baseUri: options?.baseUri || 'https://token.botframework.com', + userAgent: `${packageName}/${packageVersion} ${options?.userAgent || ''}`, + }); } - const defaultUserAgent = getDefaultUserAgentValue(); - options.userAgent = `${packageName}/${packageVersion} ${defaultUserAgent} ${options.userAgent || ''}`; - - super(credentials, options); - - this.baseUri = options.baseUri || this.baseUri || "https://token.botframework.com"; - this.requestContentType = "application/json; charset=utf-8"; - this.credentials = credentials; - - } } diff --git a/libraries/botframework-connector/tests/appCredentials.test.js b/libraries/botframework-connector/tests/appCredentials.test.js index d8104402d9..356012dcb1 100644 --- a/libraries/botframework-connector/tests/appCredentials.test.js +++ b/libraries/botframework-connector/tests/appCredentials.test.js @@ -5,7 +5,7 @@ const { AuthenticationConstants, CertificateAppCredentials, MicrosoftAppCredentials } = require('../'); const { ok: assert, strictEqual } = require('assert'); -const { WebResource } = require('@azure/core-http'); +const { createWebResource } = require('botbuilder-stdlib/lib/azureCoreHttpCompat'); const APP_ID = '2cd87869-38a0-4182-9251-d056e8f0ac24'; const APP_PASSWORD = 'password'; @@ -43,13 +43,13 @@ describe('AppCredentials', function () { describe('signRequest', function () { it('should not sign request when appId is falsy', async function () { const creds = new MicrosoftAppCredentials(''); - const webRequest = await creds.signRequest(new WebResource()); + const webRequest = await creds.signRequest(createWebResource()); assert(!webRequest.headers.Authorization); }); it('should not sign request when appId is anonymous skill appId', async function () { const creds = new MicrosoftAppCredentials(AuthenticationConstants.AnonymousSkillAppId); - const webRequest = await creds.signRequest(new WebResource()); + const webRequest = await creds.signRequest(createWebResource()); assert(!webRequest.headers.Authorization); }); }); diff --git a/libraries/botframework-connector/tests/botFrameworkAuthenticationFactory.test.js b/libraries/botframework-connector/tests/botFrameworkAuthenticationFactory.test.js index 44090d10ee..dfe9cd7050 100644 --- a/libraries/botframework-connector/tests/botFrameworkAuthenticationFactory.test.js +++ b/libraries/botframework-connector/tests/botFrameworkAuthenticationFactory.test.js @@ -11,7 +11,7 @@ const { PasswordServiceClientCredentialFactory, SkillValidation, } = require('..'); -const { HttpHeaders } = require('@azure/core-http'); +const { createPipelineRequest, createHttpHeaders } = require('@azure/core-rest-pipeline'); describe('BotFrameworkAuthenticationFactory', function () { it('should create anonymous BotFrameworkAuthentication', function () { @@ -123,7 +123,7 @@ describe('BotFrameworkAuthenticationFactory', function () { assert.strictEqual(connectorFactory.credentialFactory, credsFactory); const connectorClient = await connectorFactory.create(HOST_SERVICE_URL, HOST_AUDIENCE); - assertHasAcceptHeader(connectorClient); + await assertHasAcceptHeader(connectorClient); assert.strictEqual(connectorClient.credentials.appId, APP_ID); assert.strictEqual(connectorClient.credentials.appPassword, APP_PASSWORD); assert.strictEqual(connectorClient.credentials.oAuthScope, HOST_AUDIENCE); @@ -135,24 +135,18 @@ describe('BotFrameworkAuthenticationFactory', function () { }); }); - function assertHasAcceptHeader(client) { + async function assertHasAcceptHeader(client) { let hasAcceptHeader = false; - const mockNextPolicy = { - create: (_) => ({}), - sendRequest: (_) => { - return {}; - }, - }; const length = client._requestPolicyFactories.length; for (let i = 0; i < length; i++) { - const mockHttp = { - headers: new HttpHeaders(), - }; + const mockHttp = createPipelineRequest({ + headers: createHttpHeaders(), + }); - const result = client._requestPolicyFactories[i].create(mockNextPolicy); + const result = client._requestPolicyFactories[i]; - result.sendRequest(mockHttp); + await result.sendRequest(mockHttp, (request) => ({ request, headers: mockHttp.headers })); if (mockHttp.headers.get('accept') == '*/*') { hasAcceptHeader = true; break; diff --git a/libraries/botframework-connector/tests/ms-rest-mappers-test.js b/libraries/botframework-connector/tests/ms-rest-mappers-test.js index 75261898b3..e95420a646 100644 --- a/libraries/botframework-connector/tests/ms-rest-mappers-test.js +++ b/libraries/botframework-connector/tests/ms-rest-mappers-test.js @@ -1,6 +1,6 @@ -const { Serializer } = require('@azure/core-http'); +const { createSerializer } = require('botbuilder-stdlib/lib/azureCoreHttpCompat'); const Mappers = require('../lib/connectorApi/models/mappers'); -const serializer = new Serializer({ Activity: Mappers.Activity, Entity: Mappers.Entity }); +const serializer = createSerializer({ Activity: Mappers.Activity, Entity: Mappers.Entity }); const assert = require('assert'); describe('serialize', function () { diff --git a/package.json b/package.json index 2352fddc46..c084240c1b 100644 --- a/package.json +++ b/package.json @@ -15,11 +15,13 @@ ], "nohoist": [ "**/@types/selenium-webdriver", - "botbuilder/filenamify" + "botbuilder/filenamify", + "botbuilder-stdlib/@azure/core-http-compat" ], "nohoistComments": { "**/@types/selenium-webdriver": "This package is excluded from the root @types folder as it requires ES2015+, whereas some BotBuilder libraries support ES5+.", - "botbuilder/filenamify": "This package is excluded because it's compiled as CJS by tsup as it's ESM-only." + "botbuilder/filenamify": "This package is excluded because it's compiled as CJS by tsup as it's ESM-only.", + "botbuilder-stdlib/@azure/core-http-compat": "This package is excluded to access the utils functions from botbuilder-stdlib/node_modules folder." } }, "scripts": { diff --git a/tools/resourceManagement/lib/resource/operations/deploymentOperations.js b/tools/resourceManagement/lib/resource/operations/deploymentOperations.js index e4e6a0d86b..13b093fcf0 100644 --- a/tools/resourceManagement/lib/resource/operations/deploymentOperations.js +++ b/tools/resourceManagement/lib/resource/operations/deploymentOperations.js @@ -10,7 +10,8 @@ 'use strict'; -const { stripRequest, stripResponse, WebResource } = require("@azure/core-http"); +const { stripRequest, stripResponse } = require("../utils"); +const { createWebResource } = require("botbuilder-stdlib/lib/azureCoreHttpCompat"); const uuid = require('uuid'); /** @@ -111,7 +112,7 @@ function _get(resourceGroupName, deploymentName, operationId, options, callback) } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'GET'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -290,7 +291,7 @@ function _list(resourceGroupName, deploymentName, options, callback) { } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'GET'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -418,7 +419,7 @@ function _listNext(nextPageLink, options, callback) { requestUrl = requestUrl.replace('{nextLink}', nextPageLink); // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'GET'; httpRequest.url = requestUrl; httpRequest.headers = {}; diff --git a/tools/resourceManagement/lib/resource/operations/deployments.js b/tools/resourceManagement/lib/resource/operations/deployments.js index 01bb1ccdd9..77de815595 100644 --- a/tools/resourceManagement/lib/resource/operations/deployments.js +++ b/tools/resourceManagement/lib/resource/operations/deployments.js @@ -10,7 +10,8 @@ 'use strict'; -const { stripRequest, stripResponse, WebResource } = require("@azure/core-http"); +const { stripRequest, stripResponse } = require("../utils"); +const { createWebResource } = require("botbuilder-stdlib/lib/azureCoreHttpCompat"); const uuid = require('uuid'); /** @@ -178,7 +179,7 @@ function _checkExistence(resourceGroupName, deploymentName, options, callback) { } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'HEAD'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -471,7 +472,7 @@ function _get(resourceGroupName, deploymentName, options, callback) { } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'GET'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -643,7 +644,7 @@ function _cancel(resourceGroupName, deploymentName, options, callback) { } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'POST'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -857,7 +858,7 @@ function _validate(resourceGroupName, deploymentName, parameters, options, callb } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'POST'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -1058,7 +1059,7 @@ function _exportTemplate(resourceGroupName, deploymentName, options, callback) { } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'POST'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -1229,7 +1230,7 @@ function _listByResourceGroup(resourceGroupName, options, callback) { } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'GET'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -1407,7 +1408,7 @@ function _beginDeleteMethod(resourceGroupName, deploymentName, options, callback } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'DELETE'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -1623,7 +1624,7 @@ function _beginCreateOrUpdate(resourceGroupName, deploymentName, parameters, opt } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'PUT'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -1781,7 +1782,7 @@ function _listByResourceGroupNext(nextPageLink, options, callback) { requestUrl = requestUrl.replace('{nextLink}', nextPageLink); // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'GET'; httpRequest.url = requestUrl; httpRequest.headers = {}; diff --git a/tools/resourceManagement/lib/resource/operations/providers.js b/tools/resourceManagement/lib/resource/operations/providers.js index 0876c3944c..36d483039c 100644 --- a/tools/resourceManagement/lib/resource/operations/providers.js +++ b/tools/resourceManagement/lib/resource/operations/providers.js @@ -10,7 +10,8 @@ 'use strict'; -const { stripRequest, stripResponse, WebResource } = require("@azure/core-http"); +const { stripRequest, stripResponse } = require("../utils"); +const { createWebResource } = require("botbuilder-stdlib/lib/azureCoreHttpCompat"); const uuid = require('uuid'); /** @@ -77,7 +78,7 @@ function _unregister(resourceProviderNamespace, options, callback) { } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'POST'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -217,7 +218,7 @@ function _register(resourceProviderNamespace, options, callback) { } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'POST'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -372,7 +373,7 @@ function _list(options, callback) { } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'GET'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -522,7 +523,7 @@ function _get(resourceProviderNamespace, options, callback) { } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'GET'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -649,7 +650,7 @@ function _listNext(nextPageLink, options, callback) { requestUrl = requestUrl.replace('{nextLink}', nextPageLink); // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'GET'; httpRequest.url = requestUrl; httpRequest.headers = {}; diff --git a/tools/resourceManagement/lib/resource/operations/resourceGroups.js b/tools/resourceManagement/lib/resource/operations/resourceGroups.js index 49b6629c5b..c175b56a35 100644 --- a/tools/resourceManagement/lib/resource/operations/resourceGroups.js +++ b/tools/resourceManagement/lib/resource/operations/resourceGroups.js @@ -10,7 +10,8 @@ 'use strict'; -const { stripRequest, stripResponse, WebResource } = require("@azure/core-http"); +const { stripRequest, stripResponse } = require("../utils"); +const { createWebResource } = require("botbuilder-stdlib/lib/azureCoreHttpCompat"); const uuid = require('uuid'); /** @@ -87,7 +88,7 @@ function _checkExistence(resourceGroupName, options, callback) { } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'HEAD'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -241,7 +242,7 @@ function _createOrUpdate(resourceGroupName, parameters, options, callback) { } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'PUT'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -489,7 +490,7 @@ function _get(resourceGroupName, options, callback) { } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'GET'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -658,7 +659,7 @@ function _update(resourceGroupName, parameters, options, callback) { } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'PATCH'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -837,7 +838,7 @@ function _exportTemplate(resourceGroupName, parameters, options, callback) { } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'POST'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -1004,7 +1005,7 @@ function _list(options, callback) { } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'GET'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -1158,7 +1159,7 @@ function _beginDeleteMethod(resourceGroupName, options, callback) { } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'DELETE'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -1269,7 +1270,7 @@ function _listNext(nextPageLink, options, callback) { requestUrl = requestUrl.replace('{nextLink}', nextPageLink); // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'GET'; httpRequest.url = requestUrl; httpRequest.headers = {}; diff --git a/tools/resourceManagement/lib/resource/operations/resources.js b/tools/resourceManagement/lib/resource/operations/resources.js index 3efa42587d..29ab990751 100644 --- a/tools/resourceManagement/lib/resource/operations/resources.js +++ b/tools/resourceManagement/lib/resource/operations/resources.js @@ -11,7 +11,8 @@ 'use strict'; const uuid = require('uuid'); -const { stripRequest, stripResponse, WebResource } = require("@azure/core-http"); +const { stripRequest, stripResponse } = require("../utils"); +const { createWebResource } = require("botbuilder-stdlib/lib/azureCoreHttpCompat"); /** * Get all the resources for a resource group. @@ -116,7 +117,7 @@ function _listByResourceGroup(resourceGroupName, options, callback) { } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'GET'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -428,7 +429,7 @@ function _list(options, callback) { } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'GET'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -606,7 +607,7 @@ function _checkExistence(resourceGroupName, resourceProviderNamespace, parentRes } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'HEAD'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -971,7 +972,7 @@ function _get(resourceGroupName, resourceProviderNamespace, parentResourcePath, } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'GET'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -1109,7 +1110,7 @@ function _checkExistenceById(resourceId, apiVersion, options, callback) { } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'HEAD'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -1419,7 +1420,7 @@ function _getById(resourceId, apiVersion, options, callback) { } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'GET'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -1584,7 +1585,7 @@ function _beginMoveResources(sourceResourceGroupName, parameters, options, callb } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'POST'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -1749,7 +1750,7 @@ function _beginValidateMoveResources(sourceResourceGroupName, parameters, option } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'POST'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -1923,7 +1924,7 @@ function _beginDeleteMethod(resourceGroupName, resourceProviderNamespace, parent } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'DELETE'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -2129,7 +2130,7 @@ function _beginCreateOrUpdate(resourceGroupName, resourceProviderNamespace, pare } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'PUT'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -2298,7 +2299,7 @@ function _beginDeleteById(resourceId, apiVersion, options, callback) { } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'DELETE'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -2465,7 +2466,7 @@ function _beginCreateOrUpdateById(resourceId, apiVersion, parameters, options, c } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'PUT'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -2623,7 +2624,7 @@ function _listByResourceGroupNext(nextPageLink, options, callback) { requestUrl = requestUrl.replace('{nextLink}', nextPageLink); // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'GET'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -2750,7 +2751,7 @@ function _listNext(nextPageLink, options, callback) { requestUrl = requestUrl.replace('{nextLink}', nextPageLink); // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'GET'; httpRequest.url = requestUrl; httpRequest.headers = {}; diff --git a/tools/resourceManagement/lib/resource/operations/tags.js b/tools/resourceManagement/lib/resource/operations/tags.js index bbd72bade2..36875e4260 100644 --- a/tools/resourceManagement/lib/resource/operations/tags.js +++ b/tools/resourceManagement/lib/resource/operations/tags.js @@ -10,7 +10,8 @@ 'use strict'; -const { stripRequest, stripResponse, WebResource } = require("@azure/core-http"); +const { stripRequest, stripResponse } = require("../utils"); +const { createWebResource } = require("botbuilder-stdlib/lib/azureCoreHttpCompat"); const uuid = require('uuid'); /** @@ -81,7 +82,7 @@ function _deleteValue(tagName, tagValue, options, callback) { } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'DELETE'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -209,7 +210,7 @@ function _createOrUpdateValue(tagName, tagValue, options, callback) { } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'PUT'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -369,7 +370,7 @@ function _createOrUpdate(tagName, options, callback) { } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'PUT'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -526,7 +527,7 @@ function _deleteMethod(tagName, options, callback) { } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'DELETE'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -643,7 +644,7 @@ function _list(options, callback) { } // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'GET'; httpRequest.url = requestUrl; httpRequest.headers = {}; @@ -771,7 +772,7 @@ function _listNext(nextPageLink, options, callback) { requestUrl = requestUrl.replace('{nextLink}', nextPageLink); // Create HTTP transport objects - let httpRequest = new WebResource(); + let httpRequest = createWebResource(); httpRequest.method = 'GET'; httpRequest.url = requestUrl; httpRequest.headers = {}; diff --git a/tools/resourceManagement/lib/resource/resourceManagementClient.js b/tools/resourceManagement/lib/resource/resourceManagementClient.js index 187e4427ed..9b1ceb9e58 100644 --- a/tools/resourceManagement/lib/resource/resourceManagementClient.js +++ b/tools/resourceManagement/lib/resource/resourceManagementClient.js @@ -14,7 +14,7 @@ 'use strict'; -const { ServiceClient, Serializer } = require("@azure/core-http"); +const { ServiceClientContext, createSerializer } = require("botbuilder-stdlib/lib/azureCoreHttpCompat"); const fs = require('fs'); const path = require('path'); @@ -23,7 +23,7 @@ const operations = require('./operations'); /** Class representing a ResourceManagementClient. */ -class ResourceManagementClient extends ServiceClient { +class ResourceManagementClient extends ServiceClientContext { /** * Create a ResourceManagementClient. * @param {credentials} credentials - Credentials needed for the client to connect to Azure. @@ -87,7 +87,7 @@ class ResourceManagementClient extends ServiceClient { addSerializationMixin(destObject) { ['serialize', 'serializeObject', 'deserialize'].forEach((property) => { - destObject[property] = Serializer[property]; + destObject[property] = createSerializer()[property]; }); }; diff --git a/tools/resourceManagement/lib/resource/utils.js b/tools/resourceManagement/lib/resource/utils.js new file mode 100644 index 0000000000..975b969ee2 --- /dev/null +++ b/tools/resourceManagement/lib/resource/utils.js @@ -0,0 +1,31 @@ +/** + * Returns a stripped version of the Http Response which only contains body, + * headers and the status. + * + * @param response - The Http Response + * @returns The stripped version of Http Response. + */ +function stripResponse(response) { + const strippedResponse = {}; + strippedResponse.body = response.bodyAsText; + strippedResponse.headers = response.headers; + strippedResponse.status = response.status; + return strippedResponse; + } + + /** + * Returns a stripped version of the Http Request that does not contain the + * Authorization header. + * + * @param request - The Http Request object + * @returns The stripped version of Http Request. + */ + function stripRequest(request) { + const strippedRequest = request.clone(); + if (strippedRequest.headers) { + strippedRequest.headers.remove("authorization"); + } + return strippedRequest; + } + + module.exports = { stripResponse, stripRequest }; \ No newline at end of file diff --git a/tools/resourceManagement/package.json b/tools/resourceManagement/package.json index e7e3744279..aebdeebed9 100644 --- a/tools/resourceManagement/package.json +++ b/tools/resourceManagement/package.json @@ -29,5 +29,8 @@ }, "scripts": { "test": "npm -s run-script jshint" + }, + "dependencies": { + "botbuilder-stdlib": "4.1.6" } } diff --git a/yarn.lock b/yarn.lock index 1cf28bf893..4cbd53845e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17,7 +17,7 @@ dependencies: tslib "^1.9.3" -"@azure/abort-controller@^2.0.0": +"@azure/abort-controller@^2.0.0", "@azure/abort-controller@^2.1.2": version "2.1.2" resolved "https://registry.yarnpkg.com/@azure/abort-controller/-/abort-controller-2.1.2.tgz#42fe0ccab23841d9905812c58f1082d27784566d" integrity sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA== @@ -38,14 +38,6 @@ "@azure/core-util" "^1.1.0" tslib "^2.6.2" -"@azure/core-auth@^1.3.0": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.3.2.tgz#6a2c248576c26df365f6c7881ca04b7f6d08e3d0" - integrity sha512-7CU6DmCHIZp5ZPiZ9r3J17lTKMmYsm/zGvNkjArQwPkrLlZ1TZ+EUYfGgh2X31OLMVAQCTJZW4cXHJi02EbJnA== - dependencies: - "@azure/abort-controller" "^1.0.0" - tslib "^2.2.0" - "@azure/core-auth@^1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.4.0.tgz#6fa9661c1705857820dbc216df5ba5665ac36a9e" @@ -54,6 +46,15 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" +"@azure/core-auth@^1.8.0", "@azure/core-auth@^1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.9.0.tgz#ac725b03fabe3c892371065ee9e2041bee0fd1ac" + integrity sha512-FPwHpZywuyasDSLMqJ6fhbOK3TqUdviZNF8OqRGA4W5Ewib2lEEZ+pBsYcBa88B2NGO/SEnYPGhyBqNlE8ilSw== + dependencies: + "@azure/abort-controller" "^2.0.0" + "@azure/core-util" "^1.11.0" + tslib "^2.6.2" + "@azure/core-client@^1.3.0", "@azure/core-client@^1.6.2", "@azure/core-client@^1.9.2": version "1.9.2" resolved "https://registry.yarnpkg.com/@azure/core-client/-/core-client-1.9.2.tgz#6fc69cee2816883ab6c5cdd653ee4f2ff9774f74" @@ -67,7 +68,7 @@ "@azure/logger" "^1.0.0" tslib "^2.6.2" -"@azure/core-http-compat@^2.0.0": +"@azure/core-http-compat@^2.0.0", "@azure/core-http-compat@^2.1.2": version "2.1.2" resolved "https://registry.yarnpkg.com/@azure/core-http-compat/-/core-http-compat-2.1.2.tgz#d1585ada24ba750dc161d816169b33b35f762f0d" integrity sha512-5MnV1yqzZwgNLLjlizsU3QqOeQChkIXw781Fwh1xdAqJR5AA32IUaq6xv1BICJvfbHoa+JYcaij2HFkhLbNTJQ== @@ -76,26 +77,6 @@ "@azure/core-client" "^1.3.0" "@azure/core-rest-pipeline" "^1.3.0" -"@azure/core-http@^3.0.4": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@azure/core-http/-/core-http-3.0.4.tgz#024b2909bbc0f2fce08c74f97a21312c4f42e922" - integrity sha512-Fok9VVhMdxAFOtqiiAtg74fL0UJkt0z3D+ouUUxcRLzZNBioPRAMJFVxiWoJljYpXsRi4GDQHzQHDc9AiYaIUQ== - dependencies: - "@azure/abort-controller" "^1.0.0" - "@azure/core-auth" "^1.3.0" - "@azure/core-tracing" "1.0.0-preview.13" - "@azure/core-util" "^1.1.1" - "@azure/logger" "^1.0.0" - "@types/node-fetch" "^2.5.0" - "@types/tunnel" "^0.0.3" - form-data "^4.0.0" - node-fetch "^2.6.7" - process "^0.11.10" - tslib "^2.2.0" - tunnel "^0.0.6" - uuid "^8.3.0" - xml2js "^0.5.0" - "@azure/core-lro@^2.2.0": version "2.5.4" resolved "https://registry.yarnpkg.com/@azure/core-lro/-/core-lro-2.5.4.tgz#b21e2bcb8bd9a8a652ff85b61adeea51a8055f90" @@ -127,13 +108,19 @@ https-proxy-agent "^7.0.0" tslib "^2.6.2" -"@azure/core-tracing@1.0.0-preview.13": - version "1.0.0-preview.13" - resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz#55883d40ae2042f6f1e12b17dd0c0d34c536d644" - integrity sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ== +"@azure/core-rest-pipeline@^1.18.1": + version "1.18.1" + resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.18.1.tgz#380e7d3f15be80de83ee414176adb32824402f38" + integrity sha512-/wS73UEDrxroUEVywEm7J0p2c+IIiVxyfigCGfsKvCxxCET4V/Hef2aURqltrXMRjNmdmt5IuOgIpl8f6xdO5A== dependencies: - "@opentelemetry/api" "^1.0.1" - tslib "^2.2.0" + "@azure/abort-controller" "^2.0.0" + "@azure/core-auth" "^1.8.0" + "@azure/core-tracing" "^1.0.1" + "@azure/core-util" "^1.11.0" + "@azure/logger" "^1.0.0" + http-proxy-agent "^7.0.0" + https-proxy-agent "^7.0.0" + tslib "^2.6.2" "@azure/core-tracing@^1.0.0", "@azure/core-tracing@^1.0.1", "@azure/core-tracing@^1.1.1", "@azure/core-tracing@^1.1.2": version "1.1.2" @@ -142,6 +129,13 @@ dependencies: tslib "^2.6.2" +"@azure/core-tracing@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.2.0.tgz#7be5d53c3522d639cf19042cbcdb19f71bc35ab2" + integrity sha512-UKTiEJPkWcESPYJz3X5uKRYyOcJD+4nYph+KpfdPRnQJVrZfk0KJgdnaAWKfhsBBtAf/D58Az4AvCJEmWgIBAg== + dependencies: + tslib "^2.6.2" + "@azure/core-util@^1.1.0", "@azure/core-util@^1.3.0", "@azure/core-util@^1.6.1", "@azure/core-util@^1.8.1", "@azure/core-util@^1.9.0": version "1.9.2" resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.9.2.tgz#1dc37dc5b0dae34c578be62cf98905ba7c0cafe7" @@ -150,7 +144,15 @@ "@azure/abort-controller" "^2.0.0" tslib "^2.6.2" -"@azure/core-util@^1.1.1", "@azure/core-util@^1.2.0": +"@azure/core-util@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.11.0.tgz#f530fc67e738aea872fbdd1cc8416e70219fada7" + integrity sha512-DxOSLua+NdpWoSqULhjDyAZTXFdP/LKkqtYuxxz1SCN289zk3OG8UOpnCQAz/tygyACBtWp/BoO72ptK7msY8g== + dependencies: + "@azure/abort-controller" "^2.0.0" + tslib "^2.6.2" + +"@azure/core-util@^1.2.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.5.0.tgz#ffe49c3e867044da67daeb8122143fa065e1eb0e" integrity sha512-GZBpVFDtQ/15hW1OgBcRdT4Bl7AEpcEZqLfbAvOtm1CQUncKWiYapFHVD588hmlV27NbOOtSm3cnLF3lvoHi4g== @@ -3311,11 +3313,6 @@ resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.9.0.tgz#d03eba68273dc0f7509e2a3d5cba21eae10379fe" integrity sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg== -"@opentelemetry/api@^1.0.1": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.0.3.tgz#13a12ae9e05c2a782f7b5e84c3cbfda4225eaf80" - integrity sha512-puWxACExDe9nxbBB3lOymQFrLYml2dVOrd7USiVRnSbgXE+KwBu+HxFvxrzfqsiSda9IWsXJG1ef7C1O2/GmKQ== - "@opentelemetry/core@1.26.0", "@opentelemetry/core@^1.19.0", "@opentelemetry/core@^1.25.1": version "1.26.0" resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.26.0.tgz#7d84265aaa850ed0ca5813f97d831155be42b328" @@ -4310,14 +4307,6 @@ resolved "https://registry.yarnpkg.com/@types/nconf/-/nconf-0.10.7.tgz#921830f3180700bef1aed07c36d27efd451d5bc0" integrity sha512-ltJgbQX0XgjkeDrz0anTCXLBLatppWYFCxp88ILEwybfAuyNWr0Qb+ceFFqZ0VDR8fguEjr0hH37ZF+AF4gsxw== -"@types/node-fetch@^2.5.0": - version "2.5.7" - resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.7.tgz#20a2afffa882ab04d44ca786449a276f9f6bbf3c" - integrity sha512-o2WVNf5UhWRkxlf6eq+jMZDu7kjgpgJfl4xVNlvryc95O/6F2ld8ztKX+qu+Rjyet93WAWm5LjeX9H5FGkODvw== - dependencies: - "@types/node" "*" - form-data "^3.0.0" - "@types/node-fetch@^2.6.11": version "2.6.11" resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.11.tgz#9b39b78665dae0e82a08f02f4967d62c66f95d24" @@ -4496,13 +4485,6 @@ resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.0.tgz#fef1904e4668b6e5ecee60c52cc6a078ffa6697d" integrity sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A== -"@types/tunnel@^0.0.3": - version "0.0.3" - resolved "https://registry.yarnpkg.com/@types/tunnel/-/tunnel-0.0.3.tgz#f109e730b072b3136347561fc558c9358bb8c6e9" - integrity sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA== - dependencies: - "@types/node" "*" - "@types/unist@*", "@types/unist@^3.0.0": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/unist/-/unist-3.0.3.tgz#acaab0f919ce69cce629c2d4ed2eb4adc1b6c20c" @@ -8700,15 +8682,6 @@ form-data@^2.5.0: combined-stream "^1.0.6" mime-types "^2.1.12" -form-data@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682" - integrity sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - form-data@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" @@ -13676,11 +13649,6 @@ sanitize-html@2.13.0: parse-srcset "^1.0.2" postcss "^8.3.11" -sax@>=0.6.0: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== - saxes@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/saxes/-/saxes-6.0.0.tgz#fe5b4a4768df4f14a201b1ba6a65c1f3d9988cc5" @@ -14397,8 +14365,16 @@ string-argv@~0.3.1: resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== -"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.2.2, string-width@^4.2.3: - name string-width-cjs +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.2.2, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -14513,7 +14489,14 @@ stringify-entities@^4.0.0: character-entities-html4 "^2.0.0" character-entities-legacy "^3.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@6.0.1, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@6.0.1, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -15020,11 +15003,6 @@ tunnel-agent@^0.6.0: dependencies: safe-buffer "^5.0.1" -tunnel@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" - integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg== - tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" @@ -15942,7 +15920,7 @@ workerpool@^6.5.1: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.5.1.tgz#060f73b39d0caf97c6db64da004cd01b4c099544" integrity sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -15969,6 +15947,15 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" @@ -16023,14 +16010,6 @@ xml-name-validator@^5.0.0: resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-5.0.0.tgz#82be9b957f7afdacf961e5980f1bf227c0bf7673" integrity sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg== -xml2js@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.5.0.tgz#d9440631fbb2ed800203fad106f2724f62c493b7" - integrity sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA== - dependencies: - sax ">=0.6.0" - xmlbuilder "~11.0.0" - xml@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" @@ -16041,11 +16020,6 @@ xmlbuilder@15.1.1: resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-15.1.1.tgz#9dcdce49eea66d8d10b42cae94a79c3c8d0c2ec5" integrity sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg== -xmlbuilder@~11.0.0: - version "11.0.1" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" - integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== - xmlchars@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"