@typespec/ts-http-runtime
Version:
Isomorphic client library for making HTTP requests in node.js and browser.
228 lines (227 loc) • 8.64 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var urlHelpers_exports = {};
__export(urlHelpers_exports, {
appendQueryParams: () => appendQueryParams,
buildBaseUrl: () => buildBaseUrl,
buildRequestUrl: () => buildRequestUrl,
replaceAll: () => replaceAll
});
module.exports = __toCommonJS(urlHelpers_exports);
function isQueryParameterWithOptions(x) {
if (typeof x !== "object" || x === null || !Object.hasOwn(x, "value")) {
return false;
}
const value = x.value;
return typeof value?.toString === "function";
}
function buildRequestUrl(endpoint, routePath, pathParameters, options = {}) {
if (routePath.startsWith("https://") || routePath.startsWith("http://")) {
return routePath;
}
endpoint = buildBaseUrl(endpoint, options);
const updatedRoutePath = buildRoutePath(routePath, pathParameters, options);
const requestUrl = appendQueryParams(appendPath(endpoint, updatedRoutePath), options);
const url = new URL(requestUrl);
return url.toString();
}
function appendPath(endpoint, pathToAppend) {
const endpointSearchStart = endpoint.indexOf("?");
const pathSearchStart = pathToAppend.indexOf("?");
const endpointParts = endpointSearchStart !== -1 ? [endpoint.substring(0, endpointSearchStart), endpoint.substring(endpointSearchStart + 1)] : [endpoint, ""];
const pathParts = pathSearchStart !== -1 ? [pathToAppend.substring(0, pathSearchStart), pathToAppend.substring(pathSearchStart + 1)] : [pathToAppend, ""];
const combinedSearch = [endpointParts[1], pathParts[1].replaceAll("?", "&")].filter(Boolean).join("&");
const baseEndpoint = endpointParts[0].replace(/(^[^:]+:\/\/[^/]+)\/\/+/, "$1/");
const basePathToAppend = pathParts[0];
let combinedUrl = baseEndpoint;
if (!baseEndpoint.endsWith("/") && !basePathToAppend.startsWith("/") && basePathToAppend !== "") {
combinedUrl += `/${basePathToAppend}`;
} else if (baseEndpoint.endsWith("/") && basePathToAppend.startsWith("/")) {
combinedUrl += basePathToAppend.substring(1);
} else {
combinedUrl += basePathToAppend;
}
if (combinedSearch) {
combinedUrl += `?${combinedSearch}`;
}
return combinedUrl;
}
function getQueryParamValue(key, allowReserved, style, param) {
let separator;
if (style === "pipeDelimited") {
separator = "|";
} else if (style === "spaceDelimited") {
separator = "%20";
} else {
separator = ",";
}
let paramValues;
if (Array.isArray(param)) {
paramValues = param;
} else if (typeof param === "object" && param.toString === Object.prototype.toString) {
paramValues = Object.entries(param).flat();
} else {
paramValues = [param];
}
const value = paramValues.map((p) => {
if (p === null || p === void 0) {
return "";
}
if (!p.toString || typeof p.toString !== "function") {
throw new Error(`Query parameters must be able to be represented as string, ${key} can't`);
}
const rawValue = p.toISOString !== void 0 ? p.toISOString() : p.toString();
return allowReserved ? rawValue : encodeURIComponent(rawValue);
}).join(separator);
return `${allowReserved ? key : encodeURIComponent(key)}=${value}`;
}
function simpleParseQueryParams(queryString) {
const result = /* @__PURE__ */ new Map();
if (!queryString || queryString[0] !== "?") {
return result;
}
queryString = queryString.slice(1);
const pairs = queryString.split("&");
for (const pair of pairs) {
const eqIndex = pair.indexOf("=");
const name = eqIndex === -1 ? pair : pair.substring(0, eqIndex);
const value = eqIndex === -1 ? "" : pair.substring(eqIndex + 1);
const existingValue = result.get(name);
if (existingValue !== void 0) {
if (Array.isArray(existingValue)) {
existingValue.push(value);
} else {
result.set(name, [existingValue, value]);
}
} else {
result.set(name, value);
}
}
return result;
}
function appendQueryParams(url, options = {}) {
if (!options.queryParameters) {
return url;
}
const parsedUrl = new URL(url);
const queryParams = options.queryParameters;
const existingParams = simpleParseQueryParams(parsedUrl.search);
const newParamStrings = [];
for (const key of Object.keys(queryParams)) {
const param = queryParams[key];
if (param === void 0 || param === null) {
continue;
}
const hasMetadata = isQueryParameterWithOptions(param);
const rawValue = hasMetadata ? param.value : param;
const explode = hasMetadata ? param.explode ?? false : false;
const style = hasMetadata && param.style ? param.style : "form";
if (explode) {
if (Array.isArray(rawValue)) {
for (const item of rawValue) {
newParamStrings.push(
getQueryParamValue(key, options.skipUrlEncoding ?? false, style, item)
);
}
} else if (rawValue !== null && typeof rawValue === "object") {
for (const [actualKey, value] of Object.entries(rawValue)) {
newParamStrings.push(
getQueryParamValue(actualKey, options.skipUrlEncoding ?? false, style, value)
);
}
} else {
throw new Error("explode can only be set to true for objects and arrays");
}
} else {
newParamStrings.push(
getQueryParamValue(key, options.skipUrlEncoding ?? false, style, rawValue)
);
}
}
for (const paramString of newParamStrings) {
const eqIndex = paramString.indexOf("=");
const name = paramString.substring(0, eqIndex);
const value = paramString.substring(eqIndex + 1);
const existingValue = existingParams.get(name);
if (existingValue !== void 0) {
if (Array.isArray(existingValue)) {
if (!existingValue.includes(value)) {
existingValue.push(value);
}
} else if (existingValue !== value) {
existingParams.set(name, [existingValue, value]);
}
} else {
existingParams.set(name, value);
}
}
const searchPieces = [];
for (const [name, value] of existingParams) {
if (Array.isArray(value)) {
for (const subValue of value) {
searchPieces.push(`${name}=${subValue}`);
}
} else {
searchPieces.push(`${name}=${value}`);
}
}
parsedUrl.search = searchPieces.length ? `?${searchPieces.join("&")}` : "";
return parsedUrl.toString();
}
function buildBaseUrl(endpoint, options) {
if (!options.pathParameters) {
return endpoint;
}
const pathParams = options.pathParameters;
for (const [key, param] of Object.entries(pathParams)) {
if (param === void 0 || param === null) {
throw new Error(`Path parameters ${key} must not be undefined or null`);
}
if (!param.toString || typeof param.toString !== "function") {
throw new Error(`Path parameters must be able to be represented as string, ${key} can't`);
}
let value = param.toISOString !== void 0 ? param.toISOString() : String(param);
if (!options.skipUrlEncoding) {
value = encodeURIComponent(param);
}
endpoint = replaceAll(endpoint, `{${key}}`, value) ?? "";
}
return endpoint;
}
function buildRoutePath(routePath, pathParameters, options = {}) {
for (const pathParam of pathParameters) {
const allowReserved = typeof pathParam === "object" && (pathParam.allowReserved ?? false);
let value = typeof pathParam === "object" ? pathParam.value : pathParam;
if (!options.skipUrlEncoding && !allowReserved) {
value = encodeURIComponent(value);
}
routePath = routePath.replace(/\{[\w-]+\}/, String(value));
}
return routePath;
}
function replaceAll(value, searchValue, replaceValue) {
return !value || !searchValue ? value : value.split(searchValue).join(replaceValue || "");
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
appendQueryParams,
buildBaseUrl,
buildRequestUrl,
replaceAll
});
//# sourceMappingURL=urlHelpers.js.map