{"version":3,"file":"abstract-http.cjs","sources":["../../../../src/core/http/abstract-http.ts"],"sourcesContent":["import type { LoggerInterface } from '../../logger'\nimport type {\n  AjaxIdempotency,\n  TypeCallOptions,\n  TypeCallParams,\n  TypeHttp,\n  ICallBatchOptions,\n  BatchCommandsArrayUniversal,\n  BatchCommandsObjectUniversal,\n  BatchNamedCommandsUniversal,\n  ICallBatchResult\n} from '../../types/http'\nimport type { RestrictionManagerStats, RestrictionParams } from '../../types/limiters'\nimport type { AuthActions, AuthData } from '../../types/auth'\nimport type { AxiosInstance, AxiosRequestConfig } from 'axios'\nimport type { Result } from '../result'\nimport type { SuccessPayload } from '../../types/payloads'\nimport axios, { AxiosError } from 'axios'\nimport { LoggerFactory } from '../../logger'\nimport { RequestIdGenerator } from '../request-id-generator'\nimport { ParamsFactory } from './limiters/params-factory'\nimport { RestrictionManager } from './limiters/manager'\nimport { AjaxError } from './ajax-error'\nimport { parseErrorPayload } from './parse-error-payload'\nimport { AjaxResult } from './ajax-result'\nimport { redactSensitiveParams } from './redact'\nimport { HTTP_OPTION_KEYS, pickHttpOptions } from './http-options'\nimport { Type } from '../../tools/type'\nimport { isBrowserLikeRuntime } from '../../tools/environment'\nimport { ApiVersion } from '../../types/b24'\nimport { SdkError } from '../sdk-error'\n\n// Logger payloads are truncated so a large params / result / error body can't\n// flood a wired logger sink. Shared by the post/send, post/response, and\n// post/catchError log callsites (#236).\n// `value` is deliberately `unknown` rather than `string`: every callsite feeds it\n// `JSON.stringify(...)`, whose return type is a lying `string` — it actually\n// returns the VALUE `undefined` for `undefined`, a function, or a symbol. A\n// success body with no `result` key (`rest.documentation.openapi`) and an\n// AxiosError with no `response` (network failure, timeout, CORS) both hit that\n// case, and reading `.length` off it threw a `TypeError` from inside the logging\n// call — which the request path then re-wrapped as `JSSDK_UNKNOWN_ERROR` /\n// status 0, destroying the real error. Coercing here keeps the guarantee at the\n// one place all three callsites share, so a new callsite can't reintroduce it. (#338)\nconst LOG_MAX_LENGTH = 300\nconst LOG_SLICE_LENGTH = 100\nexport function truncateForLog(value: unknown): string {\n  const text = typeof value === 'string' ? value : String(value)\n  return text.length > LOG_MAX_LENGTH\n    ? text.slice(0, LOG_SLICE_LENGTH) + '...'\n    : text\n}\n\n/**\n * Header for a per-request idempotency key on `restApi:v3`. Sent in this\n * casing; read back case-insensitively, because the portal answers lowercased\n * and axios normalises differently per adapter.\n */\nexport const IDEMPOTENCY_KEY_HEADER = 'Idempotency-Key'\nconst IDEMPOTENCY_KEY_HEADER_LOWER = 'idempotency-key'\nconst IDEMPOTENT_REPLAYED_HEADER_LOWER = 'idempotent-replayed'\n\n/**\n * A valid idempotency key: 1-255 printable ASCII characters, no whitespace and\n * no control characters, as the portal's reference states.\n *\n * Checked before the key reaches axios so a malformed one fails as a readable\n * SDK error rather than as an opaque `ERR_INVALID_CHAR` out of Node's HTTP\n * client (or a silent rejection in a browser). The bound is the documented\n * one; a portal that later widens it would need this widened with it.\n */\nconst IDEMPOTENCY_KEY_RE = /^[\\u0021-\\u007E]{1,255}$/\n\n/**\n * Picks the two idempotency headers out of a response header bag, by\n * lowercased name.\n *\n * Deliberately two named headers rather than the whole bag: putting arbitrary\n * response headers on a public result object would also put them into every\n * wired logger sink, and the SDK does not know what a portal or a proxy in\n * front of it may add there.\n *\n * Returns `undefined` when neither header is present, so an ordinary response\n * carries no extra field at all.\n */\nexport function readIdempotencyHeaders(headers: unknown): AjaxIdempotency | undefined {\n  if (null === headers || typeof headers !== 'object') {\n    return undefined\n  }\n\n  let key: string | undefined\n  let replayed: boolean | undefined\n\n  for (const [name, rawValue] of Object.entries(headers as Record<string, unknown>)) {\n    const lowerName = name.toLowerCase()\n\n    // A repeated header name reaches us as an array through Node's http\n    // adapter. Bitrix24 does not send either of these twice, but a proxy in\n    // front of it may — and reading the array itself would stringify to\n    // `true,true`, which matches nothing and would swallow a real replay.\n    const value = Array.isArray(rawValue) ? rawValue[0] : rawValue\n\n    if (IDEMPOTENCY_KEY_HEADER_LOWER === lowerName && typeof value === 'string') {\n      key = value\n    } else if (IDEMPOTENT_REPLAYED_HEADER_LOWER === lowerName) {\n      // The portal sends the string `true`; accept the boolean too, since an\n      // adapter or a test double may have parsed it already.\n      replayed = true === value || 'true' === String(value).trim().toLowerCase()\n    }\n  }\n\n  if (undefined === key && undefined === replayed) {\n    return undefined\n  }\n\n  return { key, replayed: replayed ?? false }\n}\n\nexport type AjaxResponse<T = unknown> = {\n  status: number\n  payload: SuccessPayload<T>\n  /** Present only when the response carried an idempotency header. */\n  idempotency?: AjaxIdempotency\n}\n\nexport type TypePrepareParams = TypeCallParams & {\n  data?: Record<string, any>\n  auth?: string\n}\n\n/**\n * Does this runtime apply CORS to an outbound request?\n *\n * One question, one predicate: {@link isBrowserLikeRuntime}, which is true for a\n * browser and for all three worker kinds. This wrapper exists so the call sites\n * below read as the question they are actually asking — a credential decision —\n * rather than as a runtime check whose relevance the reader has to reconstruct.\n *\n * It used to probe `WorkerGlobalScope` here, beside a `getEnvironment()` that\n * called a worker a server. Two near-identical predicates invited exactly the\n * \"simplification\" that would have reopened the worker case, in a code path\n * whose failure mode is a request that never leaves the browser (#505). The\n * worker now has a name of its own, and this is a rename of that name.\n */\nfunction isCorsEnforcedRuntime(): boolean {\n  return isBrowserLikeRuntime()\n}\n\n/**\n * Which axios adapter to ask for, when there is a reason to ask at all.\n *\n * Axios walks its default `['xhr', 'http', 'fetch']` and takes the first\n * supported* entry, so anywhere `XMLHttpRequest` exists — a window, a dedicated\n * worker, a shared worker — it picks **XHR** and never reaches `fetch`. That is a\n * 1999 API chosen by ordering rather than by merit: no streaming, no\n * `AbortSignal` beyond `abort()`, and headers that arrive as one folded string.\n *\n * So in a browser-like runtime this asks for `fetch` instead. Everywhere else —\n * Node, most obviously — nothing is returned and axios decides for itself: there\n * XHR does not exist, the `http` adapter is already what gets picked, and it is\n * the better one for that runtime.\n *\n * Guarded on `fetch` actually being there rather than on a version check, since\n * the point is to reach it, not to assert an era.\n *\n * **One behaviour moves with it.** The fetch adapter reads `maxRedirects`, as\n * `redirect: 'manual'`; the XHR adapter ignores it outright. The only branch that\n * sets it in a browser is the query-auth one below, which exists to stop an\n * access token following a redirect — so the change is that the guard now bites\n * where it used to be inert: a redirecting deployment gets an opaque response\n * (status 0, empty body) instead of a silent hop carrying the credential.\n *\n * Opaque is not the same as rejected. `settle` resolves any response whose\n * status is falsy *before* `validateStatus` is consulted, and unlike the XHR\n * adapter — which rejects `status === 0` as `ECONNABORTED` on its own — the\n * fetch adapter has no such guard, so that blocked redirect would otherwise\n * reach the caller as an empty **success**. `_makeAxiosRequest` states it\n * instead, on the branch that asked for `maxRedirects: 0` and nowhere else.\n *\n * Returned as a spread-able object rather than a value so \"no opinion\" and\n * \"`undefined` on purpose\" stay distinguishable, and placed **before** the\n * caller's `options` so an explicit `adapter` always wins.\n */\n/**\n * Options objects whose dropped keys have already been reported, so the second\n * transport built from the same object stays quiet. Weak, so nothing here keeps\n * a caller's config alive.\n */\nconst reportedHttpOptions = new WeakSet<object>()\n\nfunction preferredAdapter(): { adapter?: 'fetch' } {\n  // `isBrowserLikeRuntime`, not `isCorsEnforcedRuntime`: the two are the same\n  // predicate today, and this is not a credential decision — it asks which\n  // adapter belongs in this runtime. Naming the question it asks is what keeps\n  // the two free to diverge.\n  if (!isBrowserLikeRuntime()) {\n    return {}\n  }\n\n  return 'function' === typeof globalThis.fetch ? { adapter: 'fetch' } : {}\n}\n\n/**\n * Abstract base class for all Bitrix24 REST API HTTP transports.\n *\n * Provides shared infrastructure used by {@link HttpV2} and {@link HttpV3}: Axios instance\n * lifecycle, auth token management (including coalesced refresh on 401), rate/operating/adaptive\n * limiting via {@link RestrictionManager}, request-id generation, structured logging with\n * payload truncation, and request metrics. Concrete subclasses implement version-specific\n * batch strategies.\n *\n * @link https://bitrix24.github.io/b24jssdk/\n */\nexport abstract class AbstractHttp implements TypeHttp {\n  protected _clientAxios: AxiosInstance\n  protected _authActions: AuthActions\n  protected _requestIdGenerator: RequestIdGenerator\n  protected _restrictionManager: RestrictionManager\n\n  /**\n   * In-flight token refresh, shared so concurrent 401s coalesce into a single\n   * `refreshAuth()` round-trip — avoids OAuth refresh-token reuse errors when a\n   * burst of requests expires together. (#182)\n   */\n  protected _pendingRefresh: Promise<AuthData> | null = null\n\n  protected _logger: LoggerInterface\n\n  protected _isClientSideWarning: boolean = false\n  protected _clientSideWarningMessage: string = ''\n\n  protected _version: ApiVersion\n\n  protected _metrics = {\n    totalRequests: 0,\n    successfulRequests: 0,\n    failedRequests: 0,\n    totalDuration: 0,\n    byMethod: new Map<string, { count: number, totalDuration: number }>(),\n    lastErrors: [] as Array<{ method: string, error: string, timestamp: number }>\n  }\n\n  constructor(\n    authActions: AuthActions,\n    options?: null | object,\n    restrictionParams?: Partial<RestrictionParams>\n  ) {\n    this._version = ApiVersion.v2\n\n    this._logger = LoggerFactory.createNullLogger()\n\n    const defaultHeaders: Record<string, string> = {}\n\n    if (this.isServerSide()) {\n      defaultHeaders['User-Agent'] = '__SDK_USER_AGENT__/__SDK_VERSION__'\n    }\n\n    this._authActions = authActions\n    this._requestIdGenerator = new RequestIdGenerator()\n\n    // Filtered rather than spread as given: `TypeHttpOptions` names the keys a\n    // caller may set, but a type cannot enforce that. Excess-property checking\n    // fires only on a direct object literal with no overlapping key, so one\n    // allowed key beside `transformRequest` — or a variable, or a call from\n    // plain JavaScript — used to carry anything straight into axios. See\n    // `pickHttpOptions`, which is also where the key list lives.\n    const { picked: httpOptions, dropped: droppedHttpOptions } = pickHttpOptions(options)\n\n    this._clientAxios = axios.create({\n      timeout: 30_000,\n      timeoutErrorMessage: 'Request timeout exceeded',\n      ...preferredAdapter(),\n      ...httpOptions,\n      // headers last so the merged default + caller headers aren't wiped by an\n      // `options.headers` (or the previous `headers: undefined`) spread (#144).\n      // Read from `options` rather than from the filtered config: the merge\n      // predates `TypeHttpOptions` and is left as it was. The SDK's own\n      // `Content-Type` is decided per request and beats anything set here\n      // (measured, lowercase spelling included); `Authorization` is per-request\n      // only on the OAuth header branch, so on a webhook an instance header of\n      // that name does reach the wire — which is one more reason the type does\n      // not offer this key.\n      headers: {\n        ...defaultHeaders,\n        ...((options as any)?.headers ?? {})\n      }\n    })\n\n    // Once per options object, not once per transport: a `B24Hook` builds\n    // `HttpV2` and `HttpV3` from the same object, and two identical warnings\n    // naming neither transport read as a bug in the warning.\n    if (droppedHttpOptions.length > 0 && !reportedHttpOptions.has(options as object)) {\n      reportedHttpOptions.add(options as object)\n\n      // Names only, never values: a `headers` entry a caller tried to set here\n      // can carry an `Authorization` token, and this reaches whatever sink the\n      // app wired up. Forced, because the default logger is silent and a\n      // silently ignored option is the failure this guard exists to prevent.\n      LoggerFactory.forcedLog(\n        this._logger,\n        'warning',\n        'httpOptions: keys not accepted at construction were dropped',\n        {\n          dropped: droppedHttpOptions.join(', '),\n          accepted: HTTP_OPTION_KEYS.join(', '),\n          hint: 'set them on getHttpClient(version).ajaxClient.defaults instead'\n        }\n      ).catch(() => {})\n    }\n\n    /**\n     * Basic parameters of restrictions\n     */\n    const params: RestrictionParams = {\n      ...ParamsFactory.getDefault(),\n      ...restrictionParams\n    }\n\n    this._restrictionManager = new RestrictionManager(params)\n  }\n\n  get apiVersion(): ApiVersion {\n    return this._version\n  }\n\n  get ajaxClient(): AxiosInstance {\n    return this._clientAxios\n  }\n\n  // region Logger ////\n  public setLogger(logger: LoggerInterface): void {\n    this._logger = logger\n    this._restrictionManager.setLogger(this._logger)\n  }\n\n  public getLogger(): LoggerInterface {\n    return this._logger\n  }\n  // endregion ////\n\n  // region RestrictionManager ////\n  public async setRestrictionManagerParams(params: RestrictionParams): Promise<void> {\n    await this._restrictionManager.setConfig(params)\n  }\n\n  public getRestrictionManagerParams(): RestrictionParams {\n    return this._restrictionManager.getParams()\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public getStats(): RestrictionManagerStats & {\n    adaptiveDelayAvg: number\n    errorCounts: Record<string, number>\n    totalRequests: number\n    successfulRequests: number\n    failedRequests: number\n    totalDuration: number\n    byMethod: Map<string, { count: number, totalDuration: number }>\n    lastErrors: { method: string, error: string, timestamp: number }[]\n  } {\n    return {\n      ...this._restrictionManager.getStats(),\n      totalRequests: this._metrics.totalRequests,\n      successfulRequests: this._metrics.successfulRequests,\n      failedRequests: this._metrics.failedRequests,\n      totalDuration: this._metrics.totalDuration,\n      byMethod: this._metrics.byMethod,\n      lastErrors: this._metrics.lastErrors\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public async reset(): Promise<void> {\n    this._metrics.totalRequests = 0\n    this._metrics.successfulRequests = 0\n    this._metrics.failedRequests = 0\n    this._metrics.totalDuration = 0\n    this._metrics.byMethod.clear()\n    this._metrics.lastErrors = []\n\n    return this._restrictionManager.reset()\n  }\n  // endregion ////\n\n  // region Metrics ////\n  protected _updateMetrics(\n    method: string,\n    isSuccess: boolean,\n    duration: number,\n    error?: unknown\n  ): void {\n    this._metrics.totalRequests++\n\n    if (isSuccess) {\n      this._metrics.successfulRequests++\n    } else {\n      this._metrics.failedRequests++\n\n      if (error instanceof AjaxError) {\n        this._metrics.lastErrors.push({\n          method,\n          error: error.message,\n          timestamp: Date.now()\n        })\n\n        if (this._metrics.lastErrors.length > 100) {\n          this._metrics.lastErrors = this._metrics.lastErrors.slice(-100)\n        }\n      }\n    }\n\n    // Metrics by Method\n    if (!this._metrics.byMethod.has(method)) {\n      this._metrics.byMethod.set(method, { count: 0, totalDuration: 0 })\n    }\n\n    const methodMetrics = this._metrics.byMethod.get(method)!\n    methodMetrics.count++\n    methodMetrics.totalDuration += duration\n  }\n  // endregion ////\n\n  // region Actions Call ////\n  // region batch ////\n  public abstract batch<T = unknown>(\n    calls: BatchCommandsArrayUniversal | BatchCommandsObjectUniversal | BatchNamedCommandsUniversal,\n    options?: ICallBatchOptions\n  ): Promise<Result<ICallBatchResult<T>>>\n  // endregion ////\n\n  protected _validateParams(requestId: string, method: string, params: TypeCallParams): void {\n    // Checking for cyclic references (especially important when logging)\n    try {\n      JSON.stringify(params)\n    } catch (error) {\n      throw new AjaxError({\n        code: 'JSSDK_INVALID_PARAMS',\n        description: 'Parameters contain circular references',\n        status: 400,\n        requestInfo: { method, params, requestId },\n        originalError: error\n      })\n    }\n\n    // Size check (It is especially important for batch)\n    // const paramsSize = JSON.stringify(params).length\n    // if (paramsSize > 1024 * 1024) { // 1MB\n    //   throw new AjaxError({\n    //     code: 'JSSDK_PARAMS_TOO_LARGE',\n    //     description: `Parameters too large: ${(paramsSize / 1024 / 1024).toFixed(2)}MB`,\n    //     status: 400,\n    //     requestInfo: { method, params, requestId },\n    //     originalError: null\n    //   })\n    // }\n  }\n\n  /**\n   * Calling the RestApi function\n   * @param method - REST API method name\n   * @param params - Parameters for the method.\n   * @param requestId - Request id\n   * @param options - Per-request transport options (currently `idempotencyKey`)\n   * @returns Promise with AjaxResult\n   */\n  public async call<T = unknown>(method: string, params: TypeCallParams, requestId?: string, options?: TypeCallOptions): Promise<AjaxResult<T>> {\n    requestId = requestId ?? this._requestIdGenerator.getRequestId()\n    const maxRetries = this._restrictionManager.getParams().maxRetries!\n\n    this._validateParams(requestId, method, params)\n    this._logRequest(requestId, method, params)\n\n    // Built once, before the retry loop, and threaded down as config rather\n    // than as options. Three reasons, all of them found the hard way:\n    // a malformed key must fail as `JSSDK_HTTP_INVALID_IDEMPOTENCY_KEY` — built\n    // inside the loop it was thrown inside the try, converted by\n    // `_convertToAjaxError`, and reached the caller as `JSSDK_UNKNOWN_ERROR`;\n    // `HttpV2`'s dropped-key warning belongs to the call, not to each attempt;\n    // and the same config must go out on every attempt, since a retry of one\n    // operation has to carry the same key. (#462)\n    const requestConfig = this._prepareRequestConfig(requestId, method, options)\n\n    let lastError: AjaxError | null = null\n    const startTime = Date.now()\n\n    for (let attempt = 0; attempt < maxRetries; attempt++) {\n      try {\n        this._logAttempt(requestId, method, attempt + 1, maxRetries)\n\n        // Apply operating limits via the manager\n        await this._restrictionManager.applyOperatingLimits(requestId, method, params)\n\n        // 3. We execute the request taking into account authorization, rate limit, and update operating statistics.\n        const result = await this._executeSingleCall<T>(requestId, method, params, requestConfig)\n        const duration = Date.now() - startTime\n\n        // 6. Updating statistics\n        this._restrictionManager.resetErrors(method)\n        this._updateMetrics(method, true, duration)\n\n        // Log the results\n        this._logSuccessfulRequest(requestId, method, duration)\n        return result\n      } catch (error: unknown) {\n        lastError = this._convertToAjaxError(requestId, error, method, params)\n\n        const duration = Date.now() - startTime\n\n        this._restrictionManager.incrementError(method)\n        this._updateMetrics(method, false, duration, lastError)\n\n        // Log the results\n        this._logFailedRequest(requestId, method, attempt + 1, maxRetries, lastError)\n\n        if (attempt + 1 < maxRetries) {\n          const waitTime = await this._restrictionManager.handleError(requestId, method, params, lastError, attempt)\n          // We don't repeat if waitTime === 0\n          if (waitTime > 0) {\n            this._restrictionManager.incrementStats('limitHits')\n\n            this._logAttemptRetryWaiteDelay(requestId, method, waitTime, attempt + 1, maxRetries)\n            await this._restrictionManager.waiteDelay(waitTime)\n\n            this._restrictionManager.incrementStats('retries')\n\n            continue\n          }\n        }\n\n        if (attempt + 1 === maxRetries) {\n          this._logAllAttemptsExhausted(requestId, method, attempt + 1, maxRetries)\n        }\n\n        /**\n         * We decide whether to return the error inside an `AjaxResult` or throw.\n         *\n         * Delegated to the manager rather than tested here against one list:\n         * the decision now also has a category branch for `restApi:v3`, and\n         * splitting it across two files is how the payload parsing came to\n         * disagree with itself (#423, #460).\n         */\n        if (this._restrictionManager.isSoftError(lastError)) {\n          return this._createAjaxResultWithErrorFromResponse<T>(lastError, requestId, method, params)\n        }\n        throw lastError\n      }\n    }\n\n    // Unreachable on normal exhaustion — the final attempt throws `lastError` (its\n    // real code) above. Only reached when maxRetries < 1: the loop never runs and\n    // there is no lastError to surface. (#143)\n    throw new AjaxError({\n      code: 'JSSDK_CALL_ALL_ATTEMPTS_EXHAUSTED',\n      description: 'All attempts exhausted',\n      status: lastError?.status || 500,\n      requestInfo: { method, params, requestId },\n      originalError: lastError?.originalError || null\n    })\n  }\n\n  protected _convertToAjaxError(requestId: string, error: unknown, method: string, params: TypeCallParams): AjaxError {\n    if (error instanceof AjaxError) {\n      return error\n    }\n\n    if (error instanceof AxiosError) {\n      return this._convertAxiosErrorToAjaxError(requestId, error, method, params)\n    }\n\n    return this._convertUnknownErrorToAjaxError(requestId, error, method, params)\n  }\n\n  protected _convertAxiosErrorToAjaxError(requestId: string, axiosError: AxiosError, method: string, params: TypeCallParams): AjaxError {\n    const errorCode = `${axiosError.code || 'JSSDK_AXIOS_ERROR'}`\n    const errorDescription = axiosError.message\n    const status = axiosError.response?.status || 0\n\n    // Handling network errors\n    if (errorCode === 'ERR_NETWORK') {\n      return new AjaxError({\n        code: 'NETWORK_ERROR',\n        description: 'Network connection failed',\n        status: 0,\n        requestInfo: { method, params, requestId },\n        originalError: axiosError\n      })\n    }\n\n    // Handling timeout\n    if (errorCode === 'ECONNABORTED' || axiosError.message.includes('timeout')) {\n      return new AjaxError({\n        code: 'REQUEST_TIMEOUT',\n        description: 'Request timeout exceeded',\n        status: 408,\n        requestInfo: { method, params, requestId },\n        originalError: axiosError\n      })\n    }\n\n    // Shared with `AjaxResult.#processErrors()`. Which of the two runs depends on\n    // whether the code is soft or hard — not something a caller controls — so\n    // they have to agree, and when this was written out in both places they did\n    // not: neither read `validation[].field` (#423).\n    const parsed = parseErrorPayload(axiosError.response?.data, errorCode, errorDescription)\n\n    return new AjaxError({\n      code: parsed?.code ?? errorCode,\n      description: parsed?.description ?? errorDescription,\n      status,\n      validation: parsed?.validation,\n      isV3Envelope: parsed?.isV3Envelope,\n      requestInfo: { method, params, requestId },\n      originalError: axiosError\n    })\n  }\n\n  protected _convertUnknownErrorToAjaxError(requestId: string, error: unknown, method: string, params: TypeCallParams): AjaxError {\n    return new AjaxError({\n      code: 'JSSDK_UNKNOWN_ERROR',\n      description: error instanceof Error ? error.message : String(error),\n      status: 0,\n      requestInfo: { method, params, requestId },\n      originalError: error\n    })\n  }\n\n  // region Execute Single Call ////\n  /**\n   * Performs a single call with\n   * - 401 error handling\n   * - rate limit check\n   * - updating operating statistics\n   */\n  protected async _executeSingleCall<T = unknown>(requestId: string, method: string, params: TypeCallParams, requestConfig?: AxiosRequestConfig): Promise<AjaxResult<T>> {\n    this._checkClientSideWarning(requestId)\n    const authData = await this._ensureAuth(requestId)\n    const response = await this._makeRequestWithAuthRetry<T>(requestId, method, params, authData, requestConfig)\n\n    return this._createAjaxResultFromResponse<T>(response, requestId, method, params)\n  }\n\n  // Get/update authorization\n  protected async _ensureAuth(requestId: string): Promise<AuthData> {\n    let authData = this._authActions.getAuthData()\n    if (authData === false) {\n      this._logRefreshingAuthToken(requestId)\n      authData = await this._refreshAuth()\n    }\n    return authData\n  }\n\n  /**\n   * Refresh the auth token, coalescing concurrent callers onto a single\n   * in-flight `refreshAuth()` so a burst of 401s triggers exactly one refresh\n   * round-trip. The slot clears once the refresh settles. (#182)\n   */\n  protected _refreshAuth(): Promise<AuthData> {\n    if (this._pendingRefresh) {\n      return this._pendingRefresh\n    }\n    const refresh = this._authActions.refreshAuth()\n    this._pendingRefresh = refresh\n    // Clear the slot once settled; the extra no-op catch keeps this cleanup\n    // chain from surfacing as an unhandled rejection — callers still receive\n    // the rejection through the returned promise.\n    refresh.finally(() => {\n      this._pendingRefresh = null\n    }).catch(() => {})\n    return refresh\n  }\n\n  // Execute the request with 401 error handling\n  protected async _makeRequestWithAuthRetry<T>(requestId: string, method: string, params: TypeCallParams, authData: AuthData, requestConfig?: AxiosRequestConfig): Promise<AjaxResponse<T>> {\n    try {\n      // 4. Apply the rate limit through the manager\n      await this._restrictionManager.checkRateLimit(requestId, method)\n\n      return await this._makeAxiosRequest<T>(requestId, method, params, authData, requestConfig)\n    } catch (error) {\n      if (error instanceof AxiosError) {\n        this.getLogger().info(\n          `post/catchError`, {\n            requestId,\n            status: error.status,\n            // Redact in case a future portal response embeds credentials in\n            // the error body (today it doesn't, but the channel is open) (#39),\n            // and cap the length so a large error body can't flood the sink (#236).\n            responseData: truncateForLog(JSON.stringify(redactSensitiveParams(error?.response?.data), null, 0))\n          }\n        ).catch(() => {})\n      }\n\n      // Normalize to AjaxError first: axios throws a raw AxiosError here, whose\n      // Bitrix `code` (e.g. `expired_token`) is only populated by conversion. The\n      // 401 auth-retry check must run against the converted error — otherwise the\n      // `instanceof AjaxError` guard in `_isAuthError` is always false and the\n      // refresh-and-retry branch below is dead code. (#182)\n      const ajaxError = this._convertToAjaxError(requestId, error, method, params)\n\n      // If this is an authorization error (401), then we try to update the token and repeat\n      if (this._isAuthError(ajaxError)) {\n        this._logAuthErrorDetected(requestId)\n        this._logRefreshingAuthToken(requestId)\n\n        const refreshedAuthData = await this._refreshAuth()\n\n        // 4. Apply the rate limit through the manager\n        await this._restrictionManager.checkRateLimit(requestId, method)\n\n        return await this._makeAxiosRequest<T>(requestId, method, params, refreshedAuthData, requestConfig)\n      }\n\n      // Non-auth error: rethrow the already-converted AjaxError (idempotent in\n      // `call()`'s catch) instead of the raw AxiosError. (#182)\n      throw ajaxError\n    }\n  }\n\n  protected async _makeAxiosRequest<T>(requestId: string, method: string, params: TypeCallParams, authData: AuthData, requestConfig?: AxiosRequestConfig): Promise<AjaxResponse<T>> {\n    let methodFormatted = this._prepareMethod(requestId, method, this.getBaseUrl())\n\n    // A `restApi:v3` batch sends its commands AS the request body — a bare\n    // top-level array, no envelope (see `HttpV3.batch`). Everything else sends an\n    // object, and `_prepareParams` is built for that: it spreads `params` into a\n    // fresh object, which turns an array into `{ '0': …, '1': … }`, and then adds\n    // the OAuth `auth` as one more top-level entry.\n    //\n    // The portal iterates every top-level entry of a batch body and demands\n    // `method` and `query` on each, so that extra entry rejects the whole batch\n    // with `INVALIDSELECTEXCEPTION` before a command runs. Three cases follow,\n    // decided by where the credential can live:\n    //\n    // 1. A webhook authenticates through the URL, so the body can be the array\n    //    the portal's grammar describes. Measured live: accepted.\n    // 2. A non-hook transport on a server sends the token in the standard\n    //    header, which the portal accepts and prefers over any body or query\n    //    parameter (`rest/lib/oauth/auth.php`, `getAuthKey()`).\n    // 3. A non-hook transport **where CORS applies** cannot use that header: the\n    //    portal answers the preflight with `Access-Control-Allow-Headers: origin,\n    //    content-type, accept` (`CRestUtil::sendHeaders()`), so asking for\n    //    `Authorization` fails the preflight and the request never leaves. The\n    //    credential goes in the **query string** instead — `?auth=<token>`,\n    //    which the portal reads through the same dictionary as a body `auth`\n    //    (`CRestUtil::getRequestData()` merges GET and POST with\n    //    `array_replace`, so `getAuthKey()` cannot tell the two apart). Measured\n    //    accepted on a live portal. A query parameter costs nothing on a\n    //    preflight the request is already making for its `Content-Type`.\n    //\n    //    This is the one place the SDK puts an OAuth token in a URL, so the\n    //    reasoning is worth keeping: in a frame app the token is in the page's\n    //    JavaScript already — devtools, the body of every non-batch call — so\n    //    the query string reveals it to nobody who could not already read it.\n    //    What it does add is a server-side record: `?auth=` reaches the portal's\n    //    access log and, when an administrator switches the module's diagnostic\n    //    logger on, its `REQUEST_URI` field. That was weighed and accepted; the\n    //    alternative was leaving every browser app unable to batch on v3 at all,\n    //    since this SDK is the only official one that runs in a browser.\n    //\n    //    Delete this branch the day `authorization` appears in the portal's\n    //    `Access-Control-Allow-Headers` — then a browser takes the same header\n    //    path as a server and nothing else here needs to change.\n    //\n    // Case 3 asks about CORS rather than about \"is this a server\", because those\n    // are not the same question. Both are answered by `isBrowserLikeRuntime()`,\n    // which counts a worker as browser-like: a worker has no `window.document`,\n    // so the older DOM test read it as a server and would have given it the\n    // header — in a context where CORS applies exactly as it does on the main\n    // thread. See {@link isCorsEnforcedRuntime}.\n    //\n    // The webhook case is not conditioned on any of this: it adds no header, so\n    // there is no preflight to fail. Its body does change shape everywhere,\n    // browser included — from `{ '0': … }` to the array — which the portal reads\n    // identically, because PHP's `json_decode` cannot tell a list from a map with\n    // sequential integer keys.\n    //\n    // Gated on the version AND the method, not merely on the body being an array.\n    // `TypeCallParams` carries an index signature, so an array satisfies it, and\n    // `getHttpClient(ApiVersion.v2).call('task.commentitem.getlist', [taskId, …])`\n    // — the documented positional shape for the legacy `task.*` family — reaches\n    // this function with an array on `restApi:v2`. Everything reasoned about\n    // above is about a v3 batch; on v2 the body would change shape AND the\n    // credential would move to a header whose acceptance nothing here has\n    // established. The comment describes one case, so the code tests for that\n    // one case.\n    const isV3Batch = ApiVersion.v3 === this._version && 'batch' === method\n    const isBareArrayBody = isV3Batch && Array.isArray(params)\n    // Load-bearing, not defensive: `AuthHookManager` returns the webhook secret\n    // as `access_token` (`hook/auth.ts`), so dropping this term would put a\n    // portal-wide secret into an `Authorization` header.\n    const isHook = 'hook' === authData.refresh_token\n    // An absent or empty token would go out as the literal `Bearer undefined`.\n    // `_prepareParams` used to drop it silently — `JSON.stringify` omits an\n    // `undefined` value — so require a real one rather than put a nonsense\n    // credential on the wire. Trimmed, because a token of blanks is not a token\n    // and `Bearer   ` is a malformed header rather than a failed authentication:\n    // it earns a portal error that names neither the header nor the token, where\n    // the body fallback at least fails the way this transport already fails.\n    const hasAccessToken = 'string' === typeof authData.access_token && authData.access_token.trim().length > 0\n    // An idempotent call needs the token out of the body too: the portal\n    // fingerprints the raw body for `Idempotency-Key`, so a token in it makes a\n    // retry after the token rotates look like a different request (422\n    // `IDEMPOTENCYKEYREUSED`) instead of a replay. Measured in #570.\n    const hasIdempotencyKey = ApiVersion.v3 === this._version\n      && 'string' === typeof (requestConfig?.headers as Record<string, unknown> | undefined)?.[IDEMPOTENCY_KEY_HEADER]\n    const authOutOfBody = (isBareArrayBody || hasIdempotencyKey) && !isHook && hasAccessToken\n    const canSendAuthHeader = authOutOfBody && !isCorsEnforcedRuntime()\n    // Same conditions as the header, on the other side of the CORS question: a\n    // browser cannot send `Authorization`, so the token rides in the query\n    // string. A hook is excluded for the same reason it is excluded above — its\n    // credential is already in the URL path, and `_prepareParams` skips it.\n    //\n    // This branch takes `maxRedirects: 0` as well, for a narrower reason than\n    // the header does. A credential in a query string does not follow a redirect\n    // the way a header does: `follow-redirects` re-sends `Authorization` to a\n    // same-host or subdomain hop, whereas a redirect target is whatever\n    // `Location` names and carries the original query only if the server echoes\n    // it back. Some do — an nginx or Apache rule built from `$request_uri` on a\n    // scheme or trailing-slash hop preserves the query string, and the hop is\n    // then a token handed to whatever serves the target.\n    //\n    // Whether the option bites depends on the adapter, and that is not decided\n    // by \"is this a browser\". `getAdapter()` walks the default\n    // `['xhr', 'http', 'fetch']` and takes the first *supported* entry. XHR is\n    // supported wherever `XMLHttpRequest` exists — a window, a dedicated worker,\n    // a shared worker — and the XHR adapter ignores `maxRedirects` outright. A\n    // **service worker** has no `XMLHttpRequest`, so the list falls through\n    // `http` (Node only) to `fetch`, and the fetch adapter does read it, as\n    // `redirect: 'manual'`. Inert on the common path, load-bearing on that one:\n    // reason enough to set it rather than reason to leave it out.\n    const useQueryAuth = authOutOfBody && isCorsEnforcedRuntime()\n    const sendBareArray = isBareArrayBody && (isHook || canSendAuthHeader || useQueryAuth)\n\n    const paramsFormatted = sendBareArray\n      ? params as unknown as TypePrepareParams\n      : this._prepareParams(authData, params)\n\n    if (authOutOfBody && !sendBareArray) {\n      delete paramsFormatted.auth\n    }\n\n    // Merged into whatever the caller's own config already carries — today the\n    // `Idempotency-Key` header — rather than replacing it.\n    //\n    // `maxRedirects: 0` comes with a credential outside the body — the header or\n    // the query string — and only with it. A credential in\n    // the body was safe across a redirect by accident: a 301/302 turns POST into\n    // GET and drops the body, so the old `auth` never travelled. A header does —\n    // `follow-redirects` strips `Authorization` when the host changes, but keeps\n    // it for the same host and for a **subdomain**, so a portal answering\n    // `301 Location: https://cdn.<portal>/…` would hand the token to whatever\n    // serves that name.\n    //\n    // Set here rather than on the axios instance because the instance carries\n    // every request the SDK makes, and a redirect somewhere in that traffic may\n    // be load-bearing for someone. This branch is different: it is reached only\n    // by a v3 batch or an idempotent v3 call on a non-hook transport. For the\n    // batch there was no working behaviour to preserve; an idempotent call did\n    // follow a redirect before, with its token in a body the redirect dropped,\n    // so it failed there anyway — now it fails legibly. A deployment that does\n    // redirect gets an error instead of a silent hop with a credential attached —\n    // a legible 301 through `validateStatus` on the Node adapter, and on `fetch`,\n    // where `redirect: 'manual'` is what `maxRedirects: 0` becomes and the\n    // response carries no status of its own, the explicit status-0 check after\n    // the `post` below (axios resolves an opaque response rather than rejecting\n    // it).\n    //\n    // Before the spread, not after, so it is a default rather than a lock: a\n    // transport that overrides `_prepareRequestConfig` — `HttpV2` already does —\n    // can hand back a `maxRedirects` and win. `TypeCallOptions` carries no such\n    // field today, so there is no way for an ordinary caller to reopen it, which\n    // is the right way round for a credential.\n    // The portal reads a `filter` value as a boolean only when the body is JSON.\n    // Under `application/x-www-form-urlencoded`, `ACTIVE: false` arrives as the\n    // string `\"false\"`, the condition is dropped, and the call answers with rows\n    // it should have excluded — no error on either side. Measured on\n    // `user.get` (`filter: { ACTIVE: false }` → 0 rows as JSON, 1 as form data,\n    // against the same portal in the same minute).\n    //\n    // The SDK has always sent JSON, but never asked for it: axios picks\n    // `application/json` on its own for a plain-object body. That default is\n    // reachable — `ajaxClient` is public and the docs encourage touching it to\n    // raise `defaults.timeout` — so one header on the instance silently breaks\n    // every boolean filter portal-wide.\n    //\n    // Per request rather than on the instance, deliberately: a caller who posts\n    // `FormData` through `ajaxClient` themselves still gets the multipart\n    // boundary axios computes for them. This states what the SDK's own traffic\n    // depends on without deciding anything for traffic it does not own.\n    //\n    // Spread first inside `headers`, so anything a transport puts in\n    // `requestConfig.headers` overrides it; none does today. What this does not\n    // reach is a request interceptor installed on the public `ajaxClient` — that\n    // runs after the config is assembled and can still replace the header (and\n    // with it the encoding). Documented rather than defended: the instance is\n    // public on purpose.\n    const jsonBody = { 'Content-Type': 'application/json' }\n\n    const effectiveConfig: AxiosRequestConfig | undefined = canSendAuthHeader\n      ? {\n          maxRedirects: 0,\n          ...requestConfig,\n          headers: {\n            ...jsonBody,\n            ...requestConfig?.headers,\n            Authorization: `Bearer ${authData.access_token}`\n          }\n        }\n      : useQueryAuth\n        ? {\n            maxRedirects: 0,\n            ...requestConfig,\n            headers: { ...jsonBody, ...requestConfig?.headers }\n          }\n        : {\n            ...requestConfig,\n            headers: { ...jsonBody, ...requestConfig?.headers }\n          }\n\n    // `paramsFormatted` carries the OAuth `auth` (access_token) for non-hook flows;\n    // log a redacted copy so the secret never enters logger context, while axios\n    // still receives the original below. (#39)\n    // The `Authorization` header is deliberately NOT logged, and nothing here may\n    // start logging it: `redactSensitiveParams` walks `params` and never touches\n    // headers, so a token put into logger context would arrive in the clear —\n    // the #39 defect, in a channel neither the redactor nor the local\n    // `no-credential-in-logger` rule can see. Pinned by a test rather than left\n    // to this comment.\n    const paramsFormattedForLog = JSON.stringify(redactSensitiveParams(paramsFormatted), null, 0)\n\n    this.getLogger().info(\n      `post/send`, {\n        requestId,\n        method,\n        params: truncateForLog(paramsFormattedForLog)\n      }\n    ).catch(() => {})\n\n    if (useQueryAuth) {\n      // `_prepareMethod` may or may not have emitted a query string already\n      // (an idempotent non-batch call on a server, if a caller forced the fetch\n      // adapter's CORS mode, would too), so ask.\n      const separator = methodFormatted.includes('?') ? '&' : '?'\n      methodFormatted += `${separator}auth=${encodeURIComponent(authData.access_token)}`\n    }\n\n    const response = await this._clientAxios.post<SuccessPayload<T>>(methodFormatted, paramsFormatted, effectiveConfig)\n\n    // A blocked redirect is not an error on every adapter, so say so here.\n    // `settle` resolves any response with a falsy status before `validateStatus`\n    // runs, and the fetch adapter — what a browser now gets — turns\n    // `redirect: 'manual'` into an opaque response: status 0, empty body, no\n    // headers. The XHR adapter rejected that shape itself (`ECONNABORTED`);\n    // fetch does not, so without this the caller gets a successful, silently\n    // empty answer to a request the SDK deliberately refused to follow.\n    //\n    // The **effective** value, not only the per-request one: `maxRedirects` is\n    // an allowed `httpOptions` key, and an instance-level `0` makes every\n    // request `redirect: 'manual'` on the fetch adapter — where the per-request\n    // config is absent, which left a blocked redirect resolving as an empty\n    // success on an ordinary call.\n    //\n    // That scope is wider than the SDK's own branch, and deliberately so: an\n    // opaque response carries nothing to tell a blocked redirect from a dropped\n    // connection, and a request that asked not to follow redirects is better\n    // answered with an error than with a silently empty success. The cost is\n    // that a caller who sets `maxRedirects: 0` themselves puts every status-0\n    // answer in this bucket, retries included — stated in the error text and on\n    // the Http page rather than left to be discovered. A caller who does not set\n    // it is unaffected: the only branches that set it are a `restApi:v3` batch\n    // and an idempotent `restApi:v3` call, both on a non-hook transport.\n    const effectiveMaxRedirects = effectiveConfig?.maxRedirects\n      ?? this._clientAxios.defaults.maxRedirects\n\n    if (0 === effectiveMaxRedirects && 0 === response.status) {\n      throw new AjaxError({\n        code: 'JSSDK_HTTP_REDIRECT_BLOCKED',\n        description: 'This request does not follow redirects (`maxRedirects: 0`) and the answer carried no status of its own — '\n          + 'which is what a refused redirect looks like on the fetch adapter, and what a dropped connection can look like too. '\n          + 'The SDK sets `maxRedirects: 0` on a `restApi:v3` batch and on a `restApi:v3` call with `idempotencyKey`, both on a '\n          + 'non-hook transport, because they carry an access token a redirect would take along. Point the SDK at the final URL instead.',\n        status: 0,\n        requestInfo: { method, params, requestId }\n      })\n    }\n\n    // Redact the log-bound copy only; callers still receive the untouched\n    // `response.data` below. First-party success bodies don't embed credentials\n    // today, but an OAuth-relay method (or a future method returning a canonical\n    // key) would otherwise leak `access_token` / `refresh_token` / etc. into any\n    // wired logger sink — mirror the `post/send` redaction on the success path. (#69)\n    // A v3 method outside the `result` envelope (e.g. `rest.documentation.openapi`)\n    // makes this `undefined` rather than a string; `truncateForLog` coerces it. (#338)\n    // `?.` on the body itself, not only on `.result`: a success is not always an\n    // object. An HTTP 200 whose body is `null` made this line throw, and the\n    // request path then re-wrapped that `TypeError` as `JSSDK_UNKNOWN_ERROR` —\n    // a fine response reaching the caller as an unrecognisable failure, the same\n    // shape as #338 and #456 one field over.\n    const resultFormattedForLog = JSON.stringify(redactSensitiveParams(response.data?.result), null, 0)\n    this.getLogger().info(\n      `post/response`, {\n        requestId,\n        // responseFull: JSON.stringify(response.data, null, 2),\n        result: truncateForLog(resultFormattedForLog),\n        time: JSON.stringify(response.data?.time, null, 0)\n      }\n    ).catch(() => {})\n\n    const idempotency = readIdempotencyHeaders(response.headers)\n\n    return {\n      status: response.status,\n      payload: response.data,\n      ...(idempotency ? { idempotency } : {})\n    }\n  }\n\n  /**\n   * Builds the per-request axios config for one call, or `undefined` when the\n   * call needs none.\n   *\n   * A `protected` hook rather than a branch inside `_makeAxiosRequest` because\n   * the two transports genuinely disagree about one option: `HttpV2` overrides\n   * it to drop `idempotencyKey`, since the v2 endpoint ignores the header and a\n   * key that is silently dropped leaves a caller believing a retry is\n   * deduplicated when it is not. It is the mechanism for that disagreement, not\n   * a speculative extension point — a subclass overriding it owes the same\n   * contract: return per-request axios config, or `undefined` for none.\n   *\n   * @throws {SdkError} `JSSDK_HTTP_INVALID_IDEMPOTENCY_KEY` when the key is not\n   *   1-255 printable ASCII characters.\n   * @throws {SdkError} `JSSDK_HTTP_IDEMPOTENCY_KEY_BROWSER` when a v3 call with a\n   *   key runs where CORS applies (#573).\n   */\n  protected _prepareRequestConfig(_requestId: string, _method: string, options?: TypeCallOptions): AxiosRequestConfig | undefined {\n    const idempotencyKey = options?.idempotencyKey\n\n    if (undefined === idempotencyKey) {\n      return undefined\n    }\n\n    if (!IDEMPOTENCY_KEY_RE.test(idempotencyKey)) {\n      // Static text only — never the key itself. `SdkError` does not run its\n      // description through `redactSensitiveParams`, and a caller is free to\n      // build a key out of business identifiers.\n      throw new SdkError({\n        code: 'JSSDK_HTTP_INVALID_IDEMPOTENCY_KEY',\n        description: '`idempotencyKey` must be 1-255 printable ASCII characters with no whitespace or control characters. '\n          + 'A `crypto.randomUUID()` value satisfies this. See https://apidocs.bitrix24.ru/api-reference/rest-v3.html',\n        status: 500\n      })\n    }\n\n    // A browser never sends it: the portal's CORS preflight allows only\n    // `origin, content-type, accept`, and no query or body form is honoured\n    // (measured, #573). Fail here, before anything is sent, instead of as a\n    // network error the retry loop would repeat.\n    if (ApiVersion.v3 === this._version && isCorsEnforcedRuntime()) {\n      throw new SdkError({\n        code: 'JSSDK_HTTP_IDEMPOTENCY_KEY_BROWSER',\n        description: '`idempotencyKey` cannot be used from a browser: the portal\\'s CORS preflight does not allow the '\n          + '`Idempotency-Key` header, so a cross-origin request carrying it is refused. Make idempotent writes from a server. See https://github.com/bitrix24/b24jssdk/issues/573',\n        status: 500\n      })\n    }\n\n    return { headers: { [IDEMPOTENCY_KEY_HEADER]: idempotencyKey } }\n  }\n\n  protected _isAuthError(error: unknown): boolean {\n    if (!(error instanceof AjaxError)) {\n      return false\n    }\n\n    return (\n      error.status === 401\n      && ['expired_token', 'invalid_token'].includes(error.code)\n    )\n  }\n\n  protected async _createAjaxResultFromResponse<T>(response: AjaxResponse<T>, requestId: string, method: string, params: TypeCallParams): Promise<AjaxResult<T>> {\n    const result = new AjaxResult<T>({\n      answer: response.payload,\n      query: { method, params, requestId },\n      status: response.status,\n      idempotency: response.idempotency\n    })\n\n    // 5. Update operating statistics — only when the portal sent a `time` block.\n    // It does not always: `rest.documentation.openapi` answers with the OpenAPI\n    // document at the top level, with neither a `result` envelope nor `time`.\n    // The `time!` assertion that used to stand here claimed otherwise, and\n    // `OperatingLimiter.updateStats()` destructured the absent block — so a\n    // perfectly good HTTP 200 came back to the caller as an exception.\n    if (result.isSuccess) {\n      const time = result.getData()?.time\n      if (time) {\n        await this._restrictionManager.updateStats(requestId, method, time)\n      }\n    }\n\n    return result\n  }\n\n  /**\n   * Turns an error the transport already built into the soft `AjaxResult` a\n   * caller receives, for the codes in `RestrictionManager.exceptionCodeForSoft`.\n   *\n   * It used to rebuild the error from a synthetic answer holding only `code` and\n   * `message`, so the portal's real body was discarded here — which is why\n   * `validation` was unreachable even though `_convertAxiosErrorToAjaxError` had\n   * just parsed it (#423).\n   *\n   * The error is now **carried** rather than re-derived: the synthetic `answer`\n   * is kept so `_data` still describes the failure for anything reading it, but\n   * it is no longer what produces the error — which also means the two can no\n   * longer disagree. `validation` is deliberately not copied into that synthetic\n   * answer: nothing parses it back out, so it would be dead weight that a future\n   * refactor could mistake for the source of truth.\n   *\n   * The carried error keeps its `originalError` — the raw `AxiosError`, whose\n   * `config.url` holds the webhook secret. It is non-enumerable (see\n   * `SdkError`), so spreads and `JSON.stringify` still cannot reach it, but it\n   * is now readable via `result.getErrors()` on this path as well as on the\n   * throwing one. That is deliberate: the two paths differ only in how the error\n   * is delivered, and a caller debugging one should not find less on the other.\n   */\n  protected _createAjaxResultWithErrorFromResponse<T>(ajaxError: AjaxError, requestId: string, method: string, params: TypeCallParams): AjaxResult<T> {\n    return new AjaxResult<T>({\n      answer: {\n        error: {\n          code: ajaxError.code,\n          message: ajaxError.message\n        }\n      },\n      query: { method, params, requestId },\n      status: ajaxError.status,\n      // The error itself, not a reconstruction: it was parsed from the portal's\n      // body a moment ago, and re-deriving it here would fold the validation\n      // messages onto a description that already holds them (#423).\n      error: ajaxError\n    })\n  }\n  // endregion ////\n  // endregion ////\n\n  // region Prepare ////\n  /**\n   * Builds the request URL: the method path plus the SDK telemetry query params\n   * (`bx24_request_id` / `bx24_sdk_ver` / `bx24_sdk_type` — request tracing and\n   * SDK identification, not auth material).\n   *\n   * Carve-out for the legacy positional `task.*` methods (`task.commentitem.*`,\n   * `task.checklistitem.*`, `task.elapseditem.*`, …): these read the request\n   * **query string positionally**, so appending the telemetry params shifts\n   * `Param #0` and the server rejects the call —\n   * `WRONG_ARGUMENTS: Param #0 (taskId) ... expected integer, but given\n   * something else`. Verified live against a portal: the same\n   * `task.commentitem.getlist` / `task.checklistitem.getlist` call succeeds\n   * without the telemetry params and fails with them; modern `tasks.task.*`\n   * (named params) is unaffected. So telemetry is omitted only for methods whose\n   * name STARTS WITH `task.`.\n   *\n   * Shared by v2 and v3 (rather than per-transport): once the v3 method\n   * allowlist was dropped (#259) a positional `task.*` method can be routed via\n   * `actions.v3.*` too, so v3 needs the same suppression — keeping the rule in\n   * one place stops the two transports drifting apart again (#207).\n   *\n   * The match is anchored (`^task\\.`): only legacy positional `task.*` methods\n   * are suppressed. Modern named-param methods `tasks.task.*` / `bizproc.task.*`\n   * do NOT start with `task.`, so they KEEP telemetry and stay traceable — the\n   * boundary was pinned live in #271/#272 (`tasks.task.list` works WITH\n   * telemetry; legacy `task.*` breaks WITH it). Bitrix24 method names are\n   * lowercase by convention, so the case-sensitive match is sufficient.\n   *\n   * @see https://apidocs.bitrix24.com/settings/how-to-call-rest-api/data-encoding.html#order-of-parameters\n   */\n  protected _prepareMethod(requestId: string, method: string, baseUrl: string): string {\n    const methodUrl = `/${encodeURIComponent(method)}`\n\n    if (/^task\\./.test(method)) {\n      return `${baseUrl}${methodUrl}`\n    }\n\n    const queryParams = new URLSearchParams({\n      [this._requestIdGenerator.getQueryStringParameterName()]: requestId,\n      [this._requestIdGenerator.getQueryStringSdkParameterName()]: '__SDK_VERSION__',\n      [this._requestIdGenerator.getQueryStringSdkTypeParameterName()]: '__SDK_USER_AGENT__'\n    })\n    return `${baseUrl}${methodUrl}?${queryParams.toString()}`\n  }\n\n  /**\n   * Processes function parameters and adds authorization\n   */\n  protected _prepareParams(authData: AuthData, params: TypeCallParams): TypePrepareParams {\n    const result: TypePrepareParams = { ...params }\n\n    /** @memo we skip auth for hook */\n    if (authData.refresh_token !== 'hook') {\n      result.auth = authData.access_token\n    }\n\n    if (result?.data && 'start' in result.data) {\n      const { start, ...dataWithoutStart } = result.data\n      result.data = dataWithoutStart\n    }\n\n    return result\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public setClientSideWarning(\n    value: boolean,\n    message: string\n  ): void {\n    this._isClientSideWarning = value\n    this._clientSideWarningMessage = message\n  }\n  // endregion ////\n\n  // region Tools ////\n  /**\n   * Tests whether the code is running outside a browser-like runtime — that is,\n   * on a server. The inverse of {@link isBrowserLikeRuntime}, and a worker is\n   * **not** server-side: it has no DOM, but the browser's rules apply to it.\n   *\n   * @return {boolean}\n   * @protected\n   */\n  protected isServerSide(): boolean {\n    return !isBrowserLikeRuntime()\n  }\n\n  /**\n   * Get the BX24 account address with the path based on the API version\n   */\n  public getBaseUrl(): string {\n    return this._authActions.getTargetOriginWithPath().get(this._version)!\n  }\n  // endregion ////\n\n  // region Log ////\n  /**\n   * Redaction contract: runs caller params through {@link redactSensitiveParams}\n   * (see `redact.ts`) so credential-bearing keys are masked before they reach any\n   * logger context. (#39, #73)\n   * @see redactSensitiveParams\n   */\n  protected _sanitizeParams(params: TypeCallParams): Record<string, unknown> {\n    return redactSensitiveParams(params)\n  }\n\n  /**\n   * Redaction contract: params are redacted via {@link _sanitizeParams} →\n   * {@link redactSensitiveParams} before logging. (#73)\n   * @see redactSensitiveParams\n   */\n  protected _logRequest(requestId: string, method: string, params: TypeCallParams): void {\n    this.getLogger().debug(`http request starting`, {\n      requestId,\n      method,\n      params: this._sanitizeParams(params),\n      api: this.apiVersion,\n      timestamp: Date.now()\n    }).catch(() => {})\n  }\n\n  protected _logAttempt(requestId: string, method: string, attempt: number, maxRetries: number): void {\n    this.getLogger().info(`http request attempt`, {\n      requestId,\n      method,\n      api: this.apiVersion,\n      attempt: {\n        current: attempt,\n        max: maxRetries\n      }\n    }).catch(() => {})\n  }\n\n  protected _logRefreshingAuthToken(requestId: string): void {\n    this.getLogger().info(`http refreshing auth token`, {\n      requestId,\n      api: this.apiVersion\n    }).catch(() => {})\n  }\n\n  protected _logAuthErrorDetected(requestId: string): void {\n    this.getLogger().info(`http auth error detected`, {\n      requestId,\n      api: this.apiVersion\n    }).catch(() => {})\n  }\n\n  protected _logSuccessfulRequest(requestId: string, method: string, duration: number): void {\n    this.getLogger().debug(`http request successful`, {\n      requestId,\n      method,\n      api: this.apiVersion,\n      duration: {\n        ms: duration,\n        sec: Number.parseFloat((duration / 1000).toFixed(2))\n      }\n    }).catch(() => {})\n  }\n\n  protected _logFailedRequest(\n    requestId: string,\n    method: string,\n    attempt: number,\n    maxRetries: number,\n    error: AjaxError\n  ): void {\n    this.getLogger().debug(`http request failed`, {\n      requestId,\n      method,\n      api: this.apiVersion,\n      attempt: {\n        current: attempt,\n        max: maxRetries\n      },\n      error: {\n        code: error.code,\n        message: error.message,\n        status: error.status\n      }\n    }).catch(() => {})\n  }\n\n  protected _logAttemptRetryWaiteDelay(\n    requestId: string,\n    method: string,\n    wait: number,\n    attempt: number,\n    maxRetries: number\n  ): void {\n    this.getLogger().debug(\n      `http wait ${(wait / 1000).toFixed(2)} sec.`,\n      {\n        requestId,\n        method,\n        api: this.apiVersion,\n        wait: wait,\n        attempt: {\n          current: attempt,\n          max: maxRetries\n        }\n      }\n    ).catch(() => {})\n  }\n\n  protected _logAllAttemptsExhausted(requestId: string, method: string, attempt: number, maxRetries: number): void {\n    this.getLogger().warning(`http all retry attempts exhausted`, {\n      requestId,\n      method,\n      api: this.apiVersion,\n      attempt: {\n        current: attempt,\n        max: maxRetries\n      }\n    }).catch(() => {})\n  }\n\n  protected _logBatchStart(\n    requestId: string,\n    calls: BatchCommandsArrayUniversal | BatchCommandsObjectUniversal | BatchNamedCommandsUniversal,\n    options: ICallBatchOptions\n  ): void {\n    const callCount = Array.isArray(calls)\n      ? calls.length\n      : Object.keys(calls).length\n\n    this.getLogger().debug(`http batch request starting `, {\n      requestId,\n      callCount,\n      api: this.apiVersion,\n      isHaltOnError: options.isHaltOnError,\n      timestamp: Date.now()\n    }).catch(() => {})\n  }\n\n  protected _logBatchCompletion(requestId: string, total: number, errors: number): void {\n    this.getLogger().debug(`http batch request completed`, {\n      requestId,\n      api: this.apiVersion,\n      totalCalls: total,\n      successful: total - errors,\n      failed: errors,\n      successRate: total > 0 ? ((total - errors) / (total) * 100).toFixed(1) + '%' : '??'\n    }).catch(() => {})\n  }\n\n  // Check client-side warnings\n  protected _checkClientSideWarning(requestId: string): void {\n    if (\n      this._isClientSideWarning\n      && !this.isServerSide()\n      && Type.isStringFilled(this._clientSideWarningMessage)\n    ) {\n      LoggerFactory.forcedLog(\n        this.getLogger(),\n        'warning',\n        this._clientSideWarningMessage,\n        {\n          requestId,\n          code: 'JSSDK_CLIENT_SIDE_WARNING'\n        }\n      )\n    }\n  }\n  // endregion ////\n}\n"],"names":["isBrowserLikeRuntime","ApiVersion","LoggerFactory","RequestIdGenerator","httpOptions","pickHttpOptions","axios","HTTP_OPTION_KEYS","ParamsFactory","RestrictionManager","AjaxError","AxiosError","parseErrorPayload","redactSensitiveParams","SdkError","AjaxResult","Type"],"mappings":"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"}