@itwin/itwins-client
Version:
iTwins client for the iTwin platform
168 lines • 7.52 kB
TypeScript
import type { AccessToken } from "@itwin/core-bentley";
import type { BentleyAPIResponse, Method, RequestConfig } from "./types/CommonApiTypes";
import { ParameterMapping } from "./types/typeUtils";
/**
* Base client class providing common functionality for iTwins API requests.
* Handles authentication, request configuration, and query string building, and error validation.
*/
export declare abstract class BaseBentleyAPIClient {
/**
* The max redirects for iTwins API endpoints.
* The max redirects can be customized via the constructor parameter or automatically
* modified based on the IMJS_MAX_REDIRECTS environment variable.
*
* @readonly
*/
protected readonly _maxRedirects: number;
/**
* Creates a new BaseClient instance for API operations
* @param maxRedirects - Optional custom max redirects, defaults to 5
*
* @example
* ```typescript
* // Use default max redirects
* const client = new BaseClient();
*
* // Use custom max redirects
* const client = new BaseClient(10);
* ```
*/
constructor(maxRedirects?: number);
/**
* Sends a generic API request with type safety and response validation.
* Handles authentication, error responses, and data extraction automatically.
* Error responses follow APIM standards for consistent error handling.
*
* @param accessToken - The client access token for authentication
* @param method - The HTTP method type (GET, POST, DELETE, etc.)
* @param url - The complete URL of the request endpoint
* @param data - Optional payload data for the request body
* @param headers - Optional additional request headers
* @returns Promise that resolves to the parsed API response with type safety
*/
protected sendGenericAPIRequest<TResponse = unknown, TData = unknown>(accessToken: AccessToken, method: Method, url: string, data?: TData, headers?: Record<string, string>, allowRedirects?: boolean): Promise<BentleyAPIResponse<TResponse>>;
/**
* Follows redirects using the fetch default 'follow' behavior.
* Used for environments where manual redirect returns opaque responses.
*
* @param requestOptions - The original request options
* @returns Promise that resolves to the final API response
*/
private followRedirectWithFetchFollow;
/**
* Handles 302 redirect responses by validating and following the redirect.
*
* @param response - The 302 redirect response
* @param accessToken - The client access token
* @param method - The HTTP method
* @param data - Optional request payload
* @param headers - Optional request headers (will be forwarded to redirect)
* @param redirectCount - Current redirect depth
* @returns Promise that resolves to the final API response
*/
private followRedirect;
/**
* Processes a non-redirect HTTP response.
*
* @param response - The HTTP response to process
* @returns Promise that resolves to a typed API response
*/
private processResponse;
/**
* Creates a generic internal server error response.
*
* @returns A 500 error response for internal exceptions
*/
private createInternalServerError;
/**
* Verifies that a redirect response is valid and safe to follow.
* Performs three critical validations:
* 1. Checks redirect count to prevent infinite loops
* 2. Ensures Location header is present
* 3. Validates redirect URL for security
*
* @param response - The 302 redirect response to verify
* @param redirectCount - Current redirect depth
* @returns Verification result with either error or validated redirect URL
*/
private checkRedirectValidity;
/**
* Validates that a redirect URL is secure and targets a trusted APIM Bentley domain.
*
* This method enforces security requirements for following HTTP redirects:
* - URL must use HTTPS protocol (not HTTP)
* - Domain must be a Bentley-owned domain (*api.bentley.com)
*
* @param url - The redirect URL to validate
* @returns True if the URL is valid and safe to follow
* @throws Error if the URL is invalid, uses HTTP, or targets an untrusted domain
*
* @remarks
* This validation is critical for security when following 302 redirects in federated
* architecture scenarios. It prevents redirect attacks that could leak authentication
* credentials to malicious domains.
*
* @example
* ```typescript
* // Valid URLs
* this.validateRedirectUrl("https://api.bentley.com/resource");
* // Invalid URLs (will throw)
* this.validateRedirectUrl("https://evil-tuna.com/phishing/"); // Non-Bentley domain
* this.validateRedirectUrl("https://bentley.com.evil.com/fake"); // Domain spoofing attempt
* ```
*/
private validateRedirectUrlSecurity;
/**
* Creates request configuration options with authentication headers.
* Validates required parameters and sets up proper content type for JSON requests.
*
* @param accessTokenString - The client access token string for authorization
* @param method - The HTTP method type (GET, POST, DELETE, etc.)
* @param url - The complete URL of the request endpoint
* @param data - Optional payload data to be JSON stringified for the request body
* @param headers - Optional additional request headers to include
* @returns RequestConfig object with method, URL, body, and headers configured
* @throws Will throw an error if access token or URL are missing/invalid
*/
protected createRequestOptions<TData>(accessTokenString: string, method: Method, url: string, data?: TData, headers?: Record<string, string>): RequestConfig;
/**
* Builds a query string to be appended to a URL from query arguments
* @param parameterMapping - Parameter mapping configuration that maps object properties to query parameter names
* @param queryArg - Object containing queryable properties for filtering
* @returns Query string with parameters applied, ready to append to a URL
*
* @example
* ```typescript
* const queryString = this.getQueryStringArg(
* ITwinsAccess.ITWINS_QUERY_PARAM_MAPPING,
* {
* search: "Building A",
* top: 10,
* subClass: "Asset"
* }
* );
* // Returns: "$search=Building%20A&$top=10&subClass=Asset"
* ```
*/
protected getQueryStringArg<T>(parameterMapping: ParameterMapping<NonNullable<T>>, queryArg?: T): string;
/**
* Helper method to build query parameter array from mapping.
* Uses exhaustive parameter mapping to ensure type safety and prevent missing parameters.
* Automatically handles URL encoding and filters out excluded parameters.
*
* @param queryArg - Object containing queryable properties
* @param mapping - Parameter mapping configuration that maps object properties to query parameter names
* @returns Array of formatted query parameter strings ready for URL construction
*
* @example
* ```typescript
* const params = this.buildQueryParams(
* { search: "Building A", top: 10 },
* { search: "$search", top: "$top" }
* );
* // Returns: ["$search=Building%20A", "$top=10"]
* ```
*/
private buildQueryParams;
}
//# sourceMappingURL=BaseBentleyAPIClient.d.ts.map