• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

microsoft / botbuilder-js / 14082188906

26 Mar 2025 11:29AM UTC coverage: 84.47% (-0.05%) from 84.524%
14082188906

push

github

web-flow
refactor: [#4759] Migrate off @azure/core-http (#4834)

* Migrate deprecated core-http to new libraries

* Fix ESLint

* Remove unused dependency

* Fix node_modules pathing

* Remove unused folder declaration

* Fix TypeScript modifying .js and .d.ts files

* Fix eslint

8260 of 10940 branches covered (75.5%)

Branch coverage included in aggregate %.

129 of 148 new or added lines in 22 files covered. (87.16%)

6 existing lines in 3 files now uncovered.

20572 of 23193 relevant lines covered (88.7%)

3968.38 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

69.34
/libraries/botbuilder-stdlib/src/azureCoreHttpCompat/serviceClientContext.ts
1
/**
2
 * Copyright (c) Microsoft Corporation. All rights reserved.
3
 * Licensed under the MIT License.
4
 */
5

6
import {
1✔
7
    ServiceClient,
8
    OperationSpec,
9
    OperationArguments as OperationArgumentsPipeline,
10
    OperationRequestOptions,
11
} from '@azure/core-client';
12
import { convertHttpClient, createRequestPolicyFactoryPolicy } from '@azure/core-http-compat';
1✔
13
import { toCompatResponse } from './response';
1✔
14
import { PipelineRequest, PipelinePolicy, createHttpHeaders } from '@azure/core-rest-pipeline';
1✔
15
import {
1✔
16
    ServiceCallback,
17
    ServiceClientCredentials,
18
    ServiceClientOptions,
19
    OperationArguments,
20
    HttpOperationResponse,
21
    createWebResource,
22
    RestResponse,
23
} from './compat';
24

25
/**
26
 * Compat implementation between @azure/core-http and @azure/core-client.
27
 */
28
export class ServiceClientContext {
1✔
29
    /**
30
     * If specified, this is the base URI that requests will be made against for this ServiceClient.
31
     * If it is not specified, then all OperationSpecs must contain a baseUrl property.
32
     */
33
    protected baseUri?: string;
34
    /**
35
     * The default request content type for the service.
36
     * Used if no requestContentType is present on an OperationSpec.
37
     */
38
    protected requestContentType?: string;
39

40
    private options: ServiceClientOptions;
41
    private client: ServiceClient;
42
    private readonly _requestPolicyFactories: PipelinePolicy[] = [];
170✔
43

44
    credentials: ServiceClientCredentials;
45

46
    // Protects against JSON.stringify leaking secrets
47
    protected toJSON(): unknown {
NEW
48
        return { name: this.constructor.name };
×
49
    }
50

51
    /**
52
     * Initializes a new instance of the ConnectorClientContext class.
53
     *
54
     * @param credentials Subscription credentials which uniquely identify client subscription.
55
     * @param [options] The parameter options
56
     */
57
    constructor(credentials: ServiceClientCredentials, options: ServiceClientOptions = {}) {
×
58
        if (credentials === null || credentials === undefined) {
170✔
59
            throw new Error("'credentials' cannot be null.");
1✔
60
        }
61

62
        if (!options) {
169!
NEW
63
            options = {};
×
64
        }
65

66
        const requestContentType =
67
            options.deserializationContentTypes?.json?.join(' ') ||
169!
68
            options.deserializationContentTypes?.xml?.join(' ') ||
1,014!
69
            'application/json; charset=utf-8';
70

71
        const userAgentPrefix =
72
            (typeof options.userAgent === 'function' ? options.userAgent('') : options.userAgent) || '';
169!
73

74
        const {
75
            baseUri: endpoint,
76
            proxySettings: proxyOptions,
77
            httpClient,
78
            credentialScopes,
79
            requestPolicyFactories,
80
        } = options;
169✔
81

82
        // do something with noPolicy option.
83
        this.client = new ServiceClient({
169✔
84
            endpoint,
85
            requestContentType,
86
            userAgentOptions: { userAgentPrefix },
87
            allowInsecureConnection: endpoint?.toLowerCase().startsWith('http:'),
507!
88
            proxyOptions,
89
            httpClient: httpClient ? convertHttpClient(httpClient) : undefined,
169✔
90
            credentialScopes,
91
        });
92

93
        this.baseUri = endpoint;
169✔
94
        this.requestContentType = requestContentType;
169✔
95
        this.credentials = credentials;
169✔
96
        this.options = options;
169✔
97
        this._requestPolicyFactories = this.addPolicies(this.client, requestPolicyFactories);
169✔
98
    }
99

100
    /**
101
     * Send the provided httpRequest.
102
     *
103
     * @param request The HTTP request to send.
104
     * @returns The HTTP response.
105
     */
106
    async sendRequest(request: PipelineRequest): Promise<HttpOperationResponse> {
107
        if (!request) {
1!
NEW
108
            throw new Error('request cannot be null');
×
109
        }
110

111
        const newRequest = await this.addRequestSettings(request);
1✔
NEW
112
        const response = await this.client.sendRequest(newRequest);
×
NEW
113
        return toCompatResponse(response);
×
114
    }
115

116
    /**
117
     * Send an HTTP request that is populated using the provided OperationSpec.
118
     *
119
     * @param operationArguments - The arguments that the HTTP request's templated values will be populated from.
120
     * @param operationSpec - The OperationSpec to use to populate the httpRequest.
121
     * @param callback - The callback to call when the response is received.
122
     * @returns The response object.
123
     */
124
    async sendOperationRequest(
125
        operationArguments: OperationArguments,
126
        operationSpec: OperationSpec,
127
        callback?: ServiceCallback<any>,
128
    ): Promise<RestResponse> {
129
        if (!operationArguments) {
145!
NEW
130
            throw new Error('operationArguments cannot be null');
×
131
        }
132

133
        const {
134
            customHeaders,
135
            timeout,
136
            onDownloadProgress,
137
            onUploadProgress,
138
            shouldDeserialize,
139
            serializerOptions,
140
            tracingContext,
145✔
141
            ...restOptions
145✔
142
        } = operationArguments.options || {};
145✔
143

144
        let _response;
145
        const requestOptions: OperationRequestOptions = {};
145✔
146
        const operationArgumentPipeline: OperationArgumentsPipeline = {
145✔
147
            ...operationArguments,
148
            options: {
149
                ...restOptions,
150
                requestOptions,
151
                onResponse(rawResponse, flatResponse, error) {
152
                    _response = rawResponse;
142✔
153
                    const response = toCompatResponse(rawResponse);
142✔
154
                    callback?.(error as Error, flatResponse, response.request, response);
142!
155
                },
156
            },
157
        };
158

159
        if (customHeaders) {
145✔
160
            requestOptions.customHeaders = customHeaders;
43✔
161
        }
162

163
        if (timeout) {
145!
NEW
164
            requestOptions.timeout = timeout;
×
165
        }
166

167
        if (onDownloadProgress) {
145!
NEW
168
            requestOptions.onDownloadProgress = onDownloadProgress;
×
169
        }
170

171
        if (onUploadProgress) {
145!
NEW
172
            requestOptions.onUploadProgress = onUploadProgress;
×
173
        }
174

175
        if (shouldDeserialize) {
145!
NEW
176
            requestOptions.shouldDeserialize = (response) => {
×
NEW
177
                if (typeof shouldDeserialize === 'function') {
×
NEW
178
                    return shouldDeserialize(toCompatResponse(response));
×
NEW
179
                } else if (typeof shouldDeserialize === 'boolean') {
×
NEW
180
                    return shouldDeserialize;
×
181
                }
NEW
182
                return true;
×
183
            };
184
        }
185

186
        if (serializerOptions) {
145!
NEW
187
            operationArgumentPipeline.options!.serializerOptions = {
×
188
                xml: serializerOptions,
189
            };
190
        }
191

192
        if (tracingContext) {
145!
NEW
193
            operationArgumentPipeline.options!.tracingOptions = {
×
194
                tracingContext,
195
            };
196
        }
197

198
        const result = await this.client.sendOperationRequest<RestResponse>(operationArgumentPipeline, operationSpec);
145✔
199

200
        Object.defineProperty(result, '_response', {
117✔
201
            value: _response,
202
        });
203

204
        return result;
117✔
205
    }
206

207
    private async addRequestSettings(request: PipelineRequest) {
208
        const webResource = createWebResource(request);
146✔
209
        await this.credentials.signRequest(webResource);
146✔
210
        const headers = createHttpHeaders({
146✔
211
            ...request.headers.toJSON({ preserveCase: true }),
212
            ...webResource.headers.toJson({ preserveCase: true }),
213
        });
214
        request.withCredentials = this.options?.withCredentials === true;
145!
215
        request.headers = headers;
145✔
216
        return request;
145✔
217
    }
218

219
    private addPolicies(
220
        client: ServiceClient,
221
        policies: ServiceClientOptions['requestPolicyFactories'],
222
    ): PipelinePolicy[] {
223
        if (Array.isArray(policies)) {
169✔
224
            const policy = createRequestPolicyFactoryPolicy(policies);
68✔
225
            policy.name = 'ServiceClientContext_RequestPolicyFactories';
68✔
226
            client.pipeline.removePolicy(policy);
68✔
227
            client.pipeline.addPolicy(policy);
68✔
228
        } else if (typeof policies === 'function') {
101!
NEW
229
            this.addPolicies(client, policies([]) || []);
×
230
        }
231

232
        this.client.pipeline.addPolicy({
169✔
233
            name: 'ServiceClientContext_Credentials_SignRequest',
234
            sendRequest: async (request, next) => {
145✔
235
                const newRequest = await this.addRequestSettings(request);
145✔
236
                return next(newRequest);
145✔
237
            },
238
        });
239

240
        return client.pipeline.getOrderedPolicies();
169✔
241
    }
242
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc