Permalink
Cannot retrieve contributors at this time
264 lines (264 sloc)
12.9 KB
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
codeql-action/node_modules/@azure/core-http/dist-esm/src/webResource.js
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright (c) Microsoft Corporation. | |
// Licensed under the MIT license. | |
import { HttpHeaders, isHttpHeadersLike } from "./httpHeaders"; | |
import { Serializer } from "./serializer"; | |
import { generateUuid } from "./util/utils"; | |
export function isWebResourceLike(object) { | |
if (object && typeof object === "object") { | |
const castObject = object; | |
if (typeof castObject.url === "string" && | |
typeof castObject.method === "string" && | |
typeof castObject.headers === "object" && | |
isHttpHeadersLike(castObject.headers) && | |
typeof castObject.validateRequestProperties === "function" && | |
typeof castObject.prepare === "function" && | |
typeof castObject.clone === "function") { | |
return true; | |
} | |
} | |
return false; | |
} | |
/** | |
* Creates a new WebResource object. | |
* | |
* This class provides an abstraction over a REST call by being library / implementation agnostic and wrapping the necessary | |
* properties to initiate a request. | |
*/ | |
export class WebResource { | |
constructor(url, method, body, query, headers, streamResponseBody, withCredentials, abortSignal, timeout, onUploadProgress, onDownloadProgress, proxySettings, keepAlive, decompressResponse, streamResponseStatusCodes) { | |
this.streamResponseBody = streamResponseBody; | |
this.streamResponseStatusCodes = streamResponseStatusCodes; | |
this.url = url || ""; | |
this.method = method || "GET"; | |
this.headers = isHttpHeadersLike(headers) ? headers : new HttpHeaders(headers); | |
this.body = body; | |
this.query = query; | |
this.formData = undefined; | |
this.withCredentials = withCredentials || false; | |
this.abortSignal = abortSignal; | |
this.timeout = timeout || 0; | |
this.onUploadProgress = onUploadProgress; | |
this.onDownloadProgress = onDownloadProgress; | |
this.proxySettings = proxySettings; | |
this.keepAlive = keepAlive; | |
this.decompressResponse = decompressResponse; | |
this.requestId = this.headers.get("x-ms-client-request-id") || generateUuid(); | |
} | |
/** | |
* Validates that the required properties such as method, url, headers["Content-Type"], | |
* headers["accept-language"] are defined. It will throw an error if one of the above | |
* mentioned properties are not defined. | |
*/ | |
validateRequestProperties() { | |
if (!this.method) { | |
throw new Error("WebResource.method is required."); | |
} | |
if (!this.url) { | |
throw new Error("WebResource.url is required."); | |
} | |
} | |
/** | |
* Prepares the request. | |
* @param options - Options to provide for preparing the request. | |
* @returns Returns the prepared WebResource (HTTP Request) object that needs to be given to the request pipeline. | |
*/ | |
prepare(options) { | |
if (!options) { | |
throw new Error("options object is required"); | |
} | |
if (options.method === undefined || | |
options.method === null || | |
typeof options.method.valueOf() !== "string") { | |
throw new Error("options.method must be a string."); | |
} | |
if (options.url && options.pathTemplate) { | |
throw new Error("options.url and options.pathTemplate are mutually exclusive. Please provide exactly one of them."); | |
} | |
if ((options.pathTemplate === undefined || | |
options.pathTemplate === null || | |
typeof options.pathTemplate.valueOf() !== "string") && | |
(options.url === undefined || | |
options.url === null || | |
typeof options.url.valueOf() !== "string")) { | |
throw new Error("Please provide exactly one of options.pathTemplate or options.url."); | |
} | |
// set the url if it is provided. | |
if (options.url) { | |
if (typeof options.url !== "string") { | |
throw new Error('options.url must be of type "string".'); | |
} | |
this.url = options.url; | |
} | |
// set the method | |
if (options.method) { | |
const validMethods = ["GET", "PUT", "HEAD", "DELETE", "OPTIONS", "POST", "PATCH", "TRACE"]; | |
if (validMethods.indexOf(options.method.toUpperCase()) === -1) { | |
throw new Error('The provided method "' + | |
options.method + | |
'" is invalid. Supported HTTP methods are: ' + | |
JSON.stringify(validMethods)); | |
} | |
} | |
this.method = options.method.toUpperCase(); | |
// construct the url if path template is provided | |
if (options.pathTemplate) { | |
const { pathTemplate, pathParameters } = options; | |
if (typeof pathTemplate !== "string") { | |
throw new Error('options.pathTemplate must be of type "string".'); | |
} | |
if (!options.baseUrl) { | |
options.baseUrl = "https://management.azure.com"; | |
} | |
const baseUrl = options.baseUrl; | |
let url = baseUrl + | |
(baseUrl.endsWith("/") ? "" : "/") + | |
(pathTemplate.startsWith("/") ? pathTemplate.slice(1) : pathTemplate); | |
const segments = url.match(/({[\w-]*\s*[\w-]*})/gi); | |
if (segments && segments.length) { | |
if (!pathParameters) { | |
throw new Error(`pathTemplate: ${pathTemplate} has been provided. Hence, options.pathParameters must also be provided.`); | |
} | |
segments.forEach(function (item) { | |
const pathParamName = item.slice(1, -1); | |
const pathParam = pathParameters[pathParamName]; | |
if (pathParam === null || | |
pathParam === undefined || | |
!(typeof pathParam === "string" || typeof pathParam === "object")) { | |
const stringifiedPathParameters = JSON.stringify(pathParameters, undefined, 2); | |
throw new Error(`pathTemplate: ${pathTemplate} contains the path parameter ${pathParamName}` + | |
` however, it is not present in parameters: ${stringifiedPathParameters}.` + | |
`The value of the path parameter can either be a "string" of the form { ${pathParamName}: "some sample value" } or ` + | |
`it can be an "object" of the form { "${pathParamName}": { value: "some sample value", skipUrlEncoding: true } }.`); | |
} | |
if (typeof pathParam.valueOf() === "string") { | |
url = url.replace(item, encodeURIComponent(pathParam)); | |
} | |
if (typeof pathParam.valueOf() === "object") { | |
if (!pathParam.value) { | |
throw new Error(`options.pathParameters[${pathParamName}] is of type "object" but it does not contain a "value" property.`); | |
} | |
if (pathParam.skipUrlEncoding) { | |
url = url.replace(item, pathParam.value); | |
} | |
else { | |
url = url.replace(item, encodeURIComponent(pathParam.value)); | |
} | |
} | |
}); | |
} | |
this.url = url; | |
} | |
// append query parameters to the url if they are provided. They can be provided with pathTemplate or url option. | |
if (options.queryParameters) { | |
const queryParameters = options.queryParameters; | |
if (typeof queryParameters !== "object") { | |
throw new Error(`options.queryParameters must be of type object. It should be a JSON object ` + | |
`of "query-parameter-name" as the key and the "query-parameter-value" as the value. ` + | |
`The "query-parameter-value" may be fo type "string" or an "object" of the form { value: "query-parameter-value", skipUrlEncoding: true }.`); | |
} | |
// append question mark if it is not present in the url | |
if (this.url && this.url.indexOf("?") === -1) { | |
this.url += "?"; | |
} | |
// construct queryString | |
const queryParams = []; | |
// We need to populate this.query as a dictionary if the request is being used for Sway's validateRequest(). | |
this.query = {}; | |
for (const queryParamName in queryParameters) { | |
const queryParam = queryParameters[queryParamName]; | |
if (queryParam) { | |
if (typeof queryParam === "string") { | |
queryParams.push(queryParamName + "=" + encodeURIComponent(queryParam)); | |
this.query[queryParamName] = encodeURIComponent(queryParam); | |
} | |
else if (typeof queryParam === "object") { | |
if (!queryParam.value) { | |
throw new Error(`options.queryParameters[${queryParamName}] is of type "object" but it does not contain a "value" property.`); | |
} | |
if (queryParam.skipUrlEncoding) { | |
queryParams.push(queryParamName + "=" + queryParam.value); | |
this.query[queryParamName] = queryParam.value; | |
} | |
else { | |
queryParams.push(queryParamName + "=" + encodeURIComponent(queryParam.value)); | |
this.query[queryParamName] = encodeURIComponent(queryParam.value); | |
} | |
} | |
} | |
} // end-of-for | |
// append the queryString | |
this.url += queryParams.join("&"); | |
} | |
// add headers to the request if they are provided | |
if (options.headers) { | |
const headers = options.headers; | |
for (const headerName of Object.keys(options.headers)) { | |
this.headers.set(headerName, headers[headerName]); | |
} | |
} | |
// ensure accept-language is set correctly | |
if (!this.headers.get("accept-language")) { | |
this.headers.set("accept-language", "en-US"); | |
} | |
// ensure the request-id is set correctly | |
if (!this.headers.get("x-ms-client-request-id") && !options.disableClientRequestId) { | |
this.headers.set("x-ms-client-request-id", this.requestId); | |
} | |
// default | |
if (!this.headers.get("Content-Type")) { | |
this.headers.set("Content-Type", "application/json; charset=utf-8"); | |
} | |
// set the request body. request.js automatically sets the Content-Length request header, so we need not set it explicitly | |
this.body = options.body; | |
if (options.body !== undefined && options.body !== null) { | |
// body as a stream special case. set the body as-is and check for some special request headers specific to sending a stream. | |
if (options.bodyIsStream) { | |
if (!this.headers.get("Transfer-Encoding")) { | |
this.headers.set("Transfer-Encoding", "chunked"); | |
} | |
if (this.headers.get("Content-Type") !== "application/octet-stream") { | |
this.headers.set("Content-Type", "application/octet-stream"); | |
} | |
} | |
else { | |
if (options.serializationMapper) { | |
this.body = new Serializer(options.mappers).serialize(options.serializationMapper, options.body, "requestBody"); | |
} | |
if (!options.disableJsonStringifyOnBody) { | |
this.body = JSON.stringify(options.body); | |
} | |
} | |
} | |
if (options.spanOptions) { | |
this.spanOptions = options.spanOptions; | |
} | |
if (options.tracingContext) { | |
this.tracingContext = options.tracingContext; | |
} | |
this.abortSignal = options.abortSignal; | |
this.onDownloadProgress = options.onDownloadProgress; | |
this.onUploadProgress = options.onUploadProgress; | |
return this; | |
} | |
/** | |
* Clone this WebResource HTTP request object. | |
* @returns The clone of this WebResource HTTP request object. | |
*/ | |
clone() { | |
const result = new WebResource(this.url, this.method, this.body, this.query, this.headers && this.headers.clone(), this.streamResponseBody, this.withCredentials, this.abortSignal, this.timeout, this.onUploadProgress, this.onDownloadProgress, this.proxySettings, this.keepAlive, this.decompressResponse, this.streamResponseStatusCodes); | |
if (this.formData) { | |
result.formData = this.formData; | |
} | |
if (this.operationSpec) { | |
result.operationSpec = this.operationSpec; | |
} | |
if (this.shouldDeserialize) { | |
result.shouldDeserialize = this.shouldDeserialize; | |
} | |
if (this.operationResponseGetter) { | |
result.operationResponseGetter = this.operationResponseGetter; | |
} | |
return result; | |
} | |
} | |
//# sourceMappingURL=webResource.js.map |