UNPKG

@azure/core-client

Version:

Core library for interfacing with AutoRest generated code

148 lines 7.02 kB
// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. import { createPipelineRequest } from "@azure/core-rest-pipeline"; import { createClientPipeline } from "./pipeline.js"; import { flattenResponse } from "./utils.js"; import { getCachedDefaultHttpClient } from "./httpClientCache.js"; import { getOperationRequestInfo } from "./operationHelpers.js"; import { getRequestUrl } from "./urlHelpers.js"; import { getStreamingResponseStatusCodes } from "./interfaceHelpers.js"; import { logger } from "./log.js"; /** * Initializes a new instance of the ServiceClient. */ export class ServiceClient { /** * The ServiceClient constructor * @param options - The service client options that govern the behavior of the client. */ constructor(options = {}) { var _a, _b; this._requestContentType = options.requestContentType; this._endpoint = (_a = options.endpoint) !== null && _a !== void 0 ? _a : options.baseUri; if (options.baseUri) { logger.warning("The baseUri option for SDK Clients has been deprecated, please use endpoint instead."); } this._allowInsecureConnection = options.allowInsecureConnection; this._httpClient = options.httpClient || getCachedDefaultHttpClient(); this.pipeline = options.pipeline || createDefaultPipeline(options); if ((_b = options.additionalPolicies) === null || _b === void 0 ? void 0 : _b.length) { for (const { policy, position } of options.additionalPolicies) { // Sign happens after Retry and is commonly needed to occur // before policies that intercept post-retry. const afterPhase = position === "perRetry" ? "Sign" : undefined; this.pipeline.addPolicy(policy, { afterPhase, }); } } } /** * Send the provided httpRequest. */ async sendRequest(request) { return this.pipeline.sendRequest(this._httpClient, request); } /** * Send an HTTP request that is populated using the provided OperationSpec. * @typeParam T - The typed result of the request, based on the 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. */ async sendOperationRequest(operationArguments, operationSpec) { const endpoint = operationSpec.baseUrl || this._endpoint; if (!endpoint) { throw new Error("If operationSpec.baseUrl is not specified, then the ServiceClient must have a endpoint string property that contains the base URL to use."); } // Templatized URLs sometimes reference properties on the ServiceClient child class, // so we have to pass `this` below in order to search these properties if they're // not part of OperationArguments const url = getRequestUrl(endpoint, operationSpec, operationArguments, this); const request = createPipelineRequest({ url, }); request.method = operationSpec.httpMethod; const operationInfo = getOperationRequestInfo(request); operationInfo.operationSpec = operationSpec; operationInfo.operationArguments = operationArguments; const contentType = operationSpec.contentType || this._requestContentType; if (contentType && operationSpec.requestBody) { request.headers.set("Content-Type", contentType); } const options = operationArguments.options; if (options) { const requestOptions = options.requestOptions; if (requestOptions) { if (requestOptions.timeout) { request.timeout = requestOptions.timeout; } if (requestOptions.onUploadProgress) { request.onUploadProgress = requestOptions.onUploadProgress; } if (requestOptions.onDownloadProgress) { request.onDownloadProgress = requestOptions.onDownloadProgress; } if (requestOptions.shouldDeserialize !== undefined) { operationInfo.shouldDeserialize = requestOptions.shouldDeserialize; } if (requestOptions.allowInsecureConnection) { request.allowInsecureConnection = true; } } if (options.abortSignal) { request.abortSignal = options.abortSignal; } if (options.tracingOptions) { request.tracingOptions = options.tracingOptions; } } if (this._allowInsecureConnection) { request.allowInsecureConnection = true; } if (request.streamResponseStatusCodes === undefined) { request.streamResponseStatusCodes = getStreamingResponseStatusCodes(operationSpec); } try { const rawResponse = await this.sendRequest(request); const flatResponse = flattenResponse(rawResponse, operationSpec.responses[rawResponse.status]); if (options === null || options === void 0 ? void 0 : options.onResponse) { options.onResponse(rawResponse, flatResponse); } return flatResponse; } catch (error) { if (typeof error === "object" && (error === null || error === void 0 ? void 0 : error.response)) { const rawResponse = error.response; const flatResponse = flattenResponse(rawResponse, operationSpec.responses[error.statusCode] || operationSpec.responses["default"]); error.details = flatResponse; if (options === null || options === void 0 ? void 0 : options.onResponse) { options.onResponse(rawResponse, flatResponse, error); } } throw error; } } } function createDefaultPipeline(options) { const credentialScopes = getCredentialScopes(options); const credentialOptions = options.credential && credentialScopes ? { credentialScopes, credential: options.credential } : undefined; return createClientPipeline(Object.assign(Object.assign({}, options), { credentialOptions })); } function getCredentialScopes(options) { if (options.credentialScopes) { return options.credentialScopes; } if (options.endpoint) { return `${options.endpoint}/.default`; } if (options.baseUri) { return `${options.baseUri}/.default`; } if (options.credential && !options.credentialScopes) { throw new Error(`When using credentials, the ServiceClientOptions must contain either a endpoint or a credentialScopes. Unable to create a bearerTokenAuthenticationPolicy`); } return undefined; } //# sourceMappingURL=serviceClient.js.map