UNPKG

24.8 kBJavaScriptView Raw
1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT License. See License.txt in the project root for license information.
3import { __assign, __spreadArrays } from "tslib";
4import { isTokenCredential } from "@azure/core-auth";
5import { DefaultHttpClient } from "./defaultHttpClient";
6import { getPathStringFromParameter, getPathStringFromParameterPath, } from "./operationParameter";
7import { isStreamOperation } from "./operationSpec";
8import { deserializationPolicy, } from "./policies/deserializationPolicy";
9import { exponentialRetryPolicy } from "./policies/exponentialRetryPolicy";
10import { generateClientRequestIdPolicy } from "./policies/generateClientRequestIdPolicy";
11import { userAgentPolicy, getDefaultUserAgentHeaderName, getDefaultUserAgentValue, } from "./policies/userAgentPolicy";
12import { DefaultRedirectOptions, redirectPolicy } from "./policies/redirectPolicy";
13import { RequestPolicyOptions, } from "./policies/requestPolicy";
14import { rpRegistrationPolicy } from "./policies/rpRegistrationPolicy";
15import { signingPolicy } from "./policies/signingPolicy";
16import { systemErrorRetryPolicy } from "./policies/systemErrorRetryPolicy";
17import { QueryCollectionFormat } from "./queryCollectionFormat";
18import { MapperType } from "./serializer";
19import { URLBuilder } from "./url";
20import * as utils from "./util/utils";
21import { stringifyXML } from "./util/xml";
22import { isWebResourceLike, WebResource, } from "./webResource";
23import { agentPolicy } from "./policies/agentPolicy";
24import { proxyPolicy, getDefaultProxySettings } from "./policies/proxyPolicy";
25import { throttlingRetryPolicy } from "./policies/throttlingRetryPolicy";
26import { AzureIdentityCredentialAdapter } from "./credentials/azureIdentityTokenCredentialAdapter";
27/**
28 * @class
29 * Initializes a new instance of the ServiceClient.
30 */
31var ServiceClient = /** @class */ (function () {
32 /**
33 * The ServiceClient constructor
34 * @constructor
35 * @param {ServiceClientCredentials} [credentials] The credentials object used for authentication.
36 * @param {ServiceClientOptions} [options] The service client options that govern the behavior of the client.
37 */
38 function ServiceClient(credentials, options) {
39 if (!options) {
40 options = {};
41 }
42 var serviceClientCredentials;
43 if (isTokenCredential(credentials)) {
44 serviceClientCredentials = new AzureIdentityCredentialAdapter(credentials);
45 }
46 else {
47 serviceClientCredentials = credentials;
48 }
49 if (serviceClientCredentials && !serviceClientCredentials.signRequest) {
50 throw new Error("credentials argument needs to implement signRequest method");
51 }
52 this._withCredentials = options.withCredentials || false;
53 this._httpClient = options.httpClient || new DefaultHttpClient();
54 this._requestPolicyOptions = new RequestPolicyOptions(options.httpPipelineLogger);
55 var requestPolicyFactories;
56 if (Array.isArray(options.requestPolicyFactories)) {
57 requestPolicyFactories = options.requestPolicyFactories;
58 }
59 else {
60 requestPolicyFactories = createDefaultRequestPolicyFactories(serviceClientCredentials, options);
61 if (options.requestPolicyFactories) {
62 var newRequestPolicyFactories = options.requestPolicyFactories(requestPolicyFactories);
63 if (newRequestPolicyFactories) {
64 requestPolicyFactories = newRequestPolicyFactories;
65 }
66 }
67 }
68 this._requestPolicyFactories = requestPolicyFactories;
69 }
70 /**
71 * Send the provided httpRequest.
72 */
73 ServiceClient.prototype.sendRequest = function (options) {
74 if (options === null || options === undefined || typeof options !== "object") {
75 throw new Error("options cannot be null or undefined and it must be of type object.");
76 }
77 var httpRequest;
78 try {
79 if (isWebResourceLike(options)) {
80 options.validateRequestProperties();
81 httpRequest = options;
82 }
83 else {
84 httpRequest = new WebResource();
85 httpRequest = httpRequest.prepare(options);
86 }
87 }
88 catch (error) {
89 return Promise.reject(error);
90 }
91 var httpPipeline = this._httpClient;
92 if (this._requestPolicyFactories && this._requestPolicyFactories.length > 0) {
93 for (var i = this._requestPolicyFactories.length - 1; i >= 0; --i) {
94 httpPipeline = this._requestPolicyFactories[i].create(httpPipeline, this._requestPolicyOptions);
95 }
96 }
97 return httpPipeline.sendRequest(httpRequest);
98 };
99 /**
100 * Send an HTTP request that is populated using the provided OperationSpec.
101 * @param {OperationArguments} operationArguments The arguments that the HTTP request's templated values will be populated from.
102 * @param {OperationSpec} operationSpec The OperationSpec to use to populate the httpRequest.
103 * @param {ServiceCallback} callback The callback to call when the response is received.
104 */
105 ServiceClient.prototype.sendOperationRequest = function (operationArguments, operationSpec, callback) {
106 if (typeof operationArguments.options === "function") {
107 callback = operationArguments.options;
108 operationArguments.options = undefined;
109 }
110 var httpRequest = new WebResource();
111 var result;
112 try {
113 var baseUri = operationSpec.baseUrl || this.baseUri;
114 if (!baseUri) {
115 throw new Error("If operationSpec.baseUrl is not specified, then the ServiceClient must have a baseUri string property that contains the base URL to use.");
116 }
117 httpRequest.method = operationSpec.httpMethod;
118 httpRequest.operationSpec = operationSpec;
119 var requestUrl = URLBuilder.parse(baseUri);
120 if (operationSpec.path) {
121 requestUrl.appendPath(operationSpec.path);
122 }
123 if (operationSpec.urlParameters && operationSpec.urlParameters.length > 0) {
124 for (var _i = 0, _a = operationSpec.urlParameters; _i < _a.length; _i++) {
125 var urlParameter = _a[_i];
126 var urlParameterValue = getOperationArgumentValueFromParameter(this, operationArguments, urlParameter, operationSpec.serializer);
127 urlParameterValue = operationSpec.serializer.serialize(urlParameter.mapper, urlParameterValue, getPathStringFromParameter(urlParameter));
128 if (!urlParameter.skipEncoding) {
129 urlParameterValue = encodeURIComponent(urlParameterValue);
130 }
131 requestUrl.replaceAll("{" + (urlParameter.mapper.serializedName || getPathStringFromParameter(urlParameter)) + "}", urlParameterValue);
132 }
133 }
134 if (operationSpec.queryParameters && operationSpec.queryParameters.length > 0) {
135 for (var _b = 0, _c = operationSpec.queryParameters; _b < _c.length; _b++) {
136 var queryParameter = _c[_b];
137 var queryParameterValue = getOperationArgumentValueFromParameter(this, operationArguments, queryParameter, operationSpec.serializer);
138 if (queryParameterValue != undefined) {
139 queryParameterValue = operationSpec.serializer.serialize(queryParameter.mapper, queryParameterValue, getPathStringFromParameter(queryParameter));
140 if (queryParameter.collectionFormat != undefined) {
141 if (queryParameter.collectionFormat === QueryCollectionFormat.Multi) {
142 if (queryParameterValue.length === 0) {
143 queryParameterValue = "";
144 }
145 else {
146 for (var index in queryParameterValue) {
147 var item = queryParameterValue[index];
148 queryParameterValue[index] = item == undefined ? "" : item.toString();
149 }
150 }
151 }
152 else if (queryParameter.collectionFormat === QueryCollectionFormat.Ssv ||
153 queryParameter.collectionFormat === QueryCollectionFormat.Tsv) {
154 queryParameterValue = queryParameterValue.join(queryParameter.collectionFormat);
155 }
156 }
157 if (!queryParameter.skipEncoding) {
158 if (Array.isArray(queryParameterValue)) {
159 for (var index in queryParameterValue) {
160 if (queryParameterValue[index] !== undefined &&
161 queryParameterValue[index] !== null) {
162 queryParameterValue[index] = encodeURIComponent(queryParameterValue[index]);
163 }
164 }
165 }
166 else {
167 queryParameterValue = encodeURIComponent(queryParameterValue);
168 }
169 }
170 if (queryParameter.collectionFormat != undefined &&
171 queryParameter.collectionFormat !== QueryCollectionFormat.Multi &&
172 queryParameter.collectionFormat !== QueryCollectionFormat.Ssv &&
173 queryParameter.collectionFormat !== QueryCollectionFormat.Tsv) {
174 queryParameterValue = queryParameterValue.join(queryParameter.collectionFormat);
175 }
176 requestUrl.setQueryParameter(queryParameter.mapper.serializedName || getPathStringFromParameter(queryParameter), queryParameterValue);
177 }
178 }
179 }
180 httpRequest.url = requestUrl.toString();
181 var contentType = operationSpec.contentType || this.requestContentType;
182 if (contentType) {
183 httpRequest.headers.set("Content-Type", contentType);
184 }
185 if (operationSpec.headerParameters) {
186 for (var _d = 0, _e = operationSpec.headerParameters; _d < _e.length; _d++) {
187 var headerParameter = _e[_d];
188 var headerValue = getOperationArgumentValueFromParameter(this, operationArguments, headerParameter, operationSpec.serializer);
189 if (headerValue != undefined) {
190 headerValue = operationSpec.serializer.serialize(headerParameter.mapper, headerValue, getPathStringFromParameter(headerParameter));
191 var headerCollectionPrefix = headerParameter.mapper
192 .headerCollectionPrefix;
193 if (headerCollectionPrefix) {
194 for (var _f = 0, _g = Object.keys(headerValue); _f < _g.length; _f++) {
195 var key = _g[_f];
196 httpRequest.headers.set(headerCollectionPrefix + key, headerValue[key]);
197 }
198 }
199 else {
200 httpRequest.headers.set(headerParameter.mapper.serializedName ||
201 getPathStringFromParameter(headerParameter), headerValue);
202 }
203 }
204 }
205 }
206 var options = operationArguments.options;
207 if (options) {
208 if (options.customHeaders) {
209 for (var customHeaderName in options.customHeaders) {
210 httpRequest.headers.set(customHeaderName, options.customHeaders[customHeaderName]);
211 }
212 }
213 if (options.abortSignal) {
214 httpRequest.abortSignal = options.abortSignal;
215 }
216 if (options.timeout) {
217 httpRequest.timeout = options.timeout;
218 }
219 if (options.onUploadProgress) {
220 httpRequest.onUploadProgress = options.onUploadProgress;
221 }
222 if (options.onDownloadProgress) {
223 httpRequest.onDownloadProgress = options.onDownloadProgress;
224 }
225 }
226 httpRequest.withCredentials = this._withCredentials;
227 serializeRequestBody(this, httpRequest, operationArguments, operationSpec);
228 if (httpRequest.streamResponseBody == undefined) {
229 httpRequest.streamResponseBody = isStreamOperation(operationSpec);
230 }
231 result = this.sendRequest(httpRequest).then(function (res) {
232 return flattenResponse(res, operationSpec.responses[res.status]);
233 });
234 }
235 catch (error) {
236 result = Promise.reject(error);
237 }
238 var cb = callback;
239 if (cb) {
240 result
241 // tslint:disable-next-line:no-null-keyword
242 .then(function (res) { return cb(null, res._response.parsedBody, res._response.request, res._response); })
243 .catch(function (err) { return cb(err); });
244 }
245 return result;
246 };
247 return ServiceClient;
248}());
249export { ServiceClient };
250export function serializeRequestBody(serviceClient, httpRequest, operationArguments, operationSpec) {
251 if (operationSpec.requestBody && operationSpec.requestBody.mapper) {
252 httpRequest.body = getOperationArgumentValueFromParameter(serviceClient, operationArguments, operationSpec.requestBody, operationSpec.serializer);
253 var bodyMapper = operationSpec.requestBody.mapper;
254 var required = bodyMapper.required, xmlName = bodyMapper.xmlName, xmlElementName = bodyMapper.xmlElementName, serializedName = bodyMapper.serializedName;
255 var typeName = bodyMapper.type.name;
256 try {
257 if (httpRequest.body != undefined || required) {
258 var requestBodyParameterPathString = getPathStringFromParameter(operationSpec.requestBody);
259 httpRequest.body = operationSpec.serializer.serialize(bodyMapper, httpRequest.body, requestBodyParameterPathString);
260 var isStream = typeName === MapperType.Stream;
261 if (operationSpec.isXML) {
262 if (typeName === MapperType.Sequence) {
263 httpRequest.body = stringifyXML(utils.prepareXMLRootList(httpRequest.body, xmlElementName || xmlName || serializedName), { rootName: xmlName || serializedName });
264 }
265 else if (!isStream) {
266 httpRequest.body = stringifyXML(httpRequest.body, {
267 rootName: xmlName || serializedName,
268 });
269 }
270 }
271 else if (!isStream) {
272 httpRequest.body = JSON.stringify(httpRequest.body);
273 }
274 }
275 }
276 catch (error) {
277 throw new Error("Error \"" + error.message + "\" occurred in serializing the payload - " + JSON.stringify(serializedName, undefined, " ") + ".");
278 }
279 }
280 else if (operationSpec.formDataParameters && operationSpec.formDataParameters.length > 0) {
281 httpRequest.formData = {};
282 for (var _i = 0, _a = operationSpec.formDataParameters; _i < _a.length; _i++) {
283 var formDataParameter = _a[_i];
284 var formDataParameterValue = getOperationArgumentValueFromParameter(serviceClient, operationArguments, formDataParameter, operationSpec.serializer);
285 if (formDataParameterValue != undefined) {
286 var formDataParameterPropertyName = formDataParameter.mapper.serializedName || getPathStringFromParameter(formDataParameter);
287 httpRequest.formData[formDataParameterPropertyName] = operationSpec.serializer.serialize(formDataParameter.mapper, formDataParameterValue, getPathStringFromParameter(formDataParameter));
288 }
289 }
290 }
291}
292function isRequestPolicyFactory(instance) {
293 return typeof instance.create === "function";
294}
295function getValueOrFunctionResult(value, defaultValueCreator) {
296 var result;
297 if (typeof value === "string") {
298 result = value;
299 }
300 else {
301 result = defaultValueCreator();
302 if (typeof value === "function") {
303 result = value(result);
304 }
305 }
306 return result;
307}
308function createDefaultRequestPolicyFactories(credentials, options) {
309 var factories = [];
310 if (options.generateClientRequestIdHeader) {
311 factories.push(generateClientRequestIdPolicy(options.clientRequestIdHeaderName));
312 }
313 if (credentials) {
314 if (isRequestPolicyFactory(credentials)) {
315 factories.push(credentials);
316 }
317 else {
318 factories.push(signingPolicy(credentials));
319 }
320 }
321 var userAgentHeaderName = getValueOrFunctionResult(options.userAgentHeaderName, getDefaultUserAgentHeaderName);
322 var userAgentHeaderValue = getValueOrFunctionResult(options.userAgent, getDefaultUserAgentValue);
323 if (userAgentHeaderName && userAgentHeaderValue) {
324 factories.push(userAgentPolicy({ key: userAgentHeaderName, value: userAgentHeaderValue }));
325 }
326 var redirectOptions = __assign(__assign({}, DefaultRedirectOptions), options.redirectOptions);
327 if (redirectOptions.handleRedirects) {
328 factories.push(redirectPolicy(redirectOptions.maxRetries));
329 }
330 factories.push(rpRegistrationPolicy(options.rpRegistrationRetryTimeout));
331 if (!options.noRetryPolicy) {
332 factories.push(exponentialRetryPolicy());
333 factories.push(systemErrorRetryPolicy());
334 factories.push(throttlingRetryPolicy());
335 }
336 factories.push(deserializationPolicy(options.deserializationContentTypes));
337 var proxySettings = options.proxySettings || getDefaultProxySettings();
338 if (proxySettings) {
339 factories.push(proxyPolicy(proxySettings));
340 }
341 if (options.agentSettings) {
342 factories.push(agentPolicy(options.agentSettings));
343 }
344 return factories;
345}
346/**
347 * Get the property parent for the property at the provided path when starting with the provided
348 * parent object.
349 */
350export function getPropertyParent(parent, propertyPath) {
351 if (parent && propertyPath) {
352 var propertyPathLength = propertyPath.length;
353 for (var i = 0; i < propertyPathLength - 1; ++i) {
354 var propertyName = propertyPath[i];
355 if (!parent[propertyName]) {
356 parent[propertyName] = {};
357 }
358 parent = parent[propertyName];
359 }
360 }
361 return parent;
362}
363function getOperationArgumentValueFromParameter(serviceClient, operationArguments, parameter, serializer) {
364 return getOperationArgumentValueFromParameterPath(serviceClient, operationArguments, parameter.parameterPath, parameter.mapper, serializer);
365}
366export function getOperationArgumentValueFromParameterPath(serviceClient, operationArguments, parameterPath, parameterMapper, serializer) {
367 var value;
368 if (typeof parameterPath === "string") {
369 parameterPath = [parameterPath];
370 }
371 if (Array.isArray(parameterPath)) {
372 if (parameterPath.length > 0) {
373 if (parameterMapper.isConstant) {
374 value = parameterMapper.defaultValue;
375 }
376 else {
377 var propertySearchResult = getPropertyFromParameterPath(operationArguments, parameterPath);
378 if (!propertySearchResult.propertyFound) {
379 propertySearchResult = getPropertyFromParameterPath(serviceClient, parameterPath);
380 }
381 var useDefaultValue = false;
382 if (!propertySearchResult.propertyFound) {
383 useDefaultValue =
384 parameterMapper.required ||
385 (parameterPath[0] === "options" && parameterPath.length === 2);
386 }
387 value = useDefaultValue ? parameterMapper.defaultValue : propertySearchResult.propertyValue;
388 }
389 // Serialize just for validation purposes.
390 var parameterPathString = getPathStringFromParameterPath(parameterPath, parameterMapper);
391 serializer.serialize(parameterMapper, value, parameterPathString);
392 }
393 }
394 else {
395 if (parameterMapper.required) {
396 value = {};
397 }
398 for (var propertyName in parameterPath) {
399 var propertyMapper = parameterMapper.type.modelProperties[propertyName];
400 var propertyPath = parameterPath[propertyName];
401 var propertyValue = getOperationArgumentValueFromParameterPath(serviceClient, operationArguments, propertyPath, propertyMapper, serializer);
402 // Serialize just for validation purposes.
403 var propertyPathString = getPathStringFromParameterPath(propertyPath, propertyMapper);
404 serializer.serialize(propertyMapper, propertyValue, propertyPathString);
405 if (propertyValue !== undefined) {
406 if (!value) {
407 value = {};
408 }
409 value[propertyName] = propertyValue;
410 }
411 }
412 }
413 return value;
414}
415function getPropertyFromParameterPath(parent, parameterPath) {
416 var result = { propertyFound: false };
417 var i = 0;
418 for (; i < parameterPath.length; ++i) {
419 var parameterPathPart = parameterPath[i];
420 // Make sure to check inherited properties too, so don't use hasOwnProperty().
421 if (parent != undefined && parameterPathPart in parent) {
422 parent = parent[parameterPathPart];
423 }
424 else {
425 break;
426 }
427 }
428 if (i === parameterPath.length) {
429 result.propertyValue = parent;
430 result.propertyFound = true;
431 }
432 return result;
433}
434export function flattenResponse(_response, responseSpec) {
435 var parsedHeaders = _response.parsedHeaders;
436 var bodyMapper = responseSpec && responseSpec.bodyMapper;
437 var addOperationResponse = function (obj) {
438 return Object.defineProperty(obj, "_response", {
439 value: _response,
440 });
441 };
442 if (bodyMapper) {
443 var typeName = bodyMapper.type.name;
444 if (typeName === "Stream") {
445 return addOperationResponse(__assign(__assign({}, parsedHeaders), { blobBody: _response.blobBody, readableStreamBody: _response.readableStreamBody }));
446 }
447 var modelProperties_1 = (typeName === "Composite" && bodyMapper.type.modelProperties) || {};
448 var isPageableResponse = Object.keys(modelProperties_1).some(function (k) { return modelProperties_1[k].serializedName === ""; });
449 if (typeName === "Sequence" || isPageableResponse) {
450 // We're expecting a sequece(array) make sure that the response body is in the
451 // correct format, if not make it an empty array []
452 var parsedBody = Array.isArray(_response.parsedBody) ? _response.parsedBody : [];
453 var arrayResponse = __spreadArrays(parsedBody);
454 for (var _i = 0, _a = Object.keys(modelProperties_1); _i < _a.length; _i++) {
455 var key = _a[_i];
456 if (modelProperties_1[key].serializedName) {
457 arrayResponse[key] = _response.parsedBody[key];
458 }
459 }
460 if (parsedHeaders) {
461 for (var _b = 0, _c = Object.keys(parsedHeaders); _b < _c.length; _b++) {
462 var key = _c[_b];
463 arrayResponse[key] = parsedHeaders[key];
464 }
465 }
466 addOperationResponse(arrayResponse);
467 return arrayResponse;
468 }
469 if (typeName === "Composite" || typeName === "Dictionary") {
470 return addOperationResponse(__assign(__assign({}, parsedHeaders), _response.parsedBody));
471 }
472 }
473 if (bodyMapper ||
474 _response.request.method === "HEAD" ||
475 utils.isPrimitiveType(_response.parsedBody)) {
476 // primitive body types and HEAD booleans
477 return addOperationResponse(__assign(__assign({}, parsedHeaders), { body: _response.parsedBody }));
478 }
479 return addOperationResponse(__assign(__assign({}, parsedHeaders), _response.parsedBody));
480}
481//# sourceMappingURL=serviceClient.js.map
\No newline at end of file