@metis-w/api-client
Version:
Modern TypeScript HTTP API client with dynamic routes, parameterized endpoints, interceptors, and advanced features
71 lines • 3.06 kB
JavaScript
import { Sanitizer } from "../security";
import { URLBuilder, DataSerializer, camelToKebab, convertObjectKeys, } from "../../utils";
export class RequestBuilder {
/**
* Merges user-provided config with default values
* @param config - User-provided request configuration
* @param defaultConfig - Default configuration values
*/
static mergeConfig(config, defaultConfig) {
return {
method: config.method || "GET",
url: config.url || "",
data: config.data || null,
params: config.params || {},
signal: config.signal || null,
timeout: config.timeout ?? defaultConfig.timeout,
headers: config.headers ?? defaultConfig.headers,
withCredentials: config.withCredentials ?? defaultConfig.withCredentials,
retries: config.retries ?? defaultConfig.retries,
retryDelay: config.retryDelay ?? defaultConfig.retryDelay,
useKebabCase: config.useKebabCase ?? defaultConfig.useKebabCase,
defaultMethod: config.defaultMethod ?? defaultConfig.defaultMethod,
methodRules: config.methodRules ?? defaultConfig.methodRules,
};
}
/**
* Builds a complete URL from base URL, path, and query parameters
* @param baseUrl - The base URL for the API
* @param path - The endpoint path to append to the base URL
* @param params - Optional query parameters to include in the URL
* @param useKebabCase - Whether to convert path segments to kebab-case
*/
static buildUrl(baseUrl, path, params, useKebabCase) {
const sanitizedPath = Sanitizer.sanitizePath(path);
const formattedPath = useKebabCase
? this.convertPathToKebab(sanitizedPath)
: sanitizedPath;
const builder = new URLBuilder(baseUrl).segment(formattedPath);
if (params && Object.keys(params).length) {
const formattedParams = useKebabCase
? convertObjectKeys(params, camelToKebab)
: params;
builder.query(formattedParams);
}
return builder.build();
}
/**
* Builds request headers, sanitizing them and adding Content-Type if necessary
* @param configHeaders - Headers from the request configuration
* @param data - Optional data to determine Content-Type
*/
static buildHeaders(configHeaders, data) {
const sanitizedHeaders = Sanitizer.sanitizeHeaders(configHeaders);
const contentType = DataSerializer.getContentType(data);
if (contentType) {
sanitizedHeaders["Content-Type"] = contentType;
}
return sanitizedHeaders;
}
/**
* Converts a path string to kebab-case, ensuring each segment is formatted correctly
* @param path - The path to convert
*/
static convertPathToKebab(path) {
return path
.split("/")
.map((segment) => camelToKebab(segment))
.join("/");
}
}
//# sourceMappingURL=request-builder.js.map