{"version":3,"file":"NetworkClient.mjs","sources":["../../../../../../core/src/NetworkClient.ts"],"sourcesContent":["import { AnalyticsEvent } from './Events';\nimport { ResponseCommon, StytchAPIError, StytchAPISchemaError, StytchAPIUnreachableError } from './public';\n\ntype SDKRequestMethodAndBody =\n  | {\n      method: 'GET' | 'DELETE';\n      body?: null;\n    }\n  | {\n      method: 'POST' | 'PUT';\n      body?: Record<string, unknown>;\n    };\n\nexport type SDKRequestInfo = SDKRequestMethodAndBody & {\n  url: string;\n  additionalMetadata?: Record<string, string>;\n};\n\nexport interface SDKTelemetry {\n  event_id: string;\n  app_session_id: string;\n  persistent_id: string;\n  client_sent_at: string;\n  timezone: string;\n\n  // Logged in user data\n  // Why don't we generate this from the session_token in the auth header?\n  // - We don't want to tie analytics ingest to session validation. There's no need to put\n  //   that kind of pressure on API, and ingest could be moved to somewhere that doesn't\n  //   have the ability to validate tokens\n  // - For bulk event batches, we want to keep track of whether or not a user was logged\n  //   in at each event. If we have 10 events, the user logs in at event 5, then they'll have\n  //   a token when they log the batch, but we want to know that they were not logged in for the\n  //   first 4 events\n\n  // Versioning\n  app: {\n    identifier: string;\n    version?: string;\n  };\n  os?: {\n    identifier?: string;\n    version?: string;\n  };\n  device?: {\n    model?: string;\n    screen_size?: string;\n  };\n  sdk: {\n    identifier: string;\n    version: string;\n  };\n}\n\nexport type AdditionalTelemetryData =\n  | { stytch_user_id?: string; stytch_session_id?: string }\n  | { stytch_member_id?: string; stytch_member_session_id?: string };\n\nexport interface INetworkClient {\n  createTelemetryBlob(additionalMetadata?: SDKRequestInfo['additionalMetadata']): SDKTelemetry;\n\n  fetchSDK: <T extends ResponseCommon>(info: SDKRequestInfo) => Promise<T>;\n\n  retriableFetchSDK: <T extends ResponseCommon>(info: RetriableSDKRequestInfo) => Promise<T>;\n\n  logEvent<E extends AnalyticsEvent>({\n    name,\n    details,\n    error,\n  }: {\n    name: E['name'];\n    details: E['details'];\n    error?: { error_code?: string; error_description?: string; http_status_code?: string };\n  }): void;\n\n  // @deprecated Use the new sessions.updateSession() method instead\n  updateSessionToken: (sessionToken: string | null) => void;\n}\n\nexport type RetriableSDKRequestInfo = SDKRequestInfo & {\n  retryCallback: (e: RetriableError, info: SDKBaseRequestInfo) => Promise<SDKBaseRequestInfo>;\n};\n\nexport type RetriableSDKBaseRequestInfo = SDKBaseRequestInfo & {\n  retryCallback: (e: RetriableError, info: SDKBaseRequestInfo) => Promise<SDKBaseRequestInfo>;\n};\n\nexport enum RetriableErrorType {\n  RequiredCaptcha = 'CAPTCHA required',\n}\n\nexport class RetriableError extends Error {\n  type: RetriableErrorType;\n\n  constructor(type: RetriableErrorType) {\n    super(type);\n    this.type = type;\n  }\n}\n\nexport async function retriableFetchSDK<T extends ResponseCommon>({\n  method,\n  finalURL,\n  basicAuthHeader,\n  xSDKClientHeader,\n  xSDKParentHostHeader,\n  body,\n  retryCallback,\n}: RetriableSDKBaseRequestInfo): Promise<T> {\n  let req: SDKBaseRequestInfo = {\n    method,\n    finalURL,\n    basicAuthHeader,\n    xSDKClientHeader,\n    xSDKParentHostHeader,\n    body,\n  };\n\n  try {\n    return await baseFetchSDK<T>(req);\n  } catch (err) {\n    if (err instanceof RetriableError) {\n      req = await retryCallback(err, req);\n      return await baseFetchSDK<T>(req);\n    }\n    throw err;\n  }\n}\n\nexport type SDKBaseRequestInfo = {\n  basicAuthHeader: string;\n  xSDKClientHeader: string;\n  xSDKParentHostHeader?: string;\n  body: SDKRequestInfo['body'];\n  method: SDKRequestInfo['method'];\n  finalURL: string;\n};\n\nexport async function baseFetchSDK<T extends ResponseCommon>({\n  method,\n  finalURL,\n  basicAuthHeader,\n  xSDKClientHeader,\n  xSDKParentHostHeader,\n  body,\n}: SDKBaseRequestInfo): Promise<T> {\n  const headers: Record<string, string> = {\n    Authorization: basicAuthHeader,\n    'Content-Type': 'application/json',\n    'X-SDK-Client': xSDKClientHeader,\n  };\n\n  if (xSDKParentHostHeader) {\n    headers['X-SDK-Parent-Host'] = xSDKParentHostHeader;\n  }\n\n  const fetchOpts: RequestInit = {\n    method,\n    headers,\n    body: body && JSON.stringify(body),\n    credentials: 'include',\n  };\n\n  let resp;\n  try {\n    resp = await fetch(finalURL, fetchOpts);\n    /* eslint-disable  @typescript-eslint/no-explicit-any */\n  } catch (e: any) {\n    if (e.message === 'Failed to fetch') {\n      throw new StytchAPIUnreachableError('Unable to contact our servers.');\n    }\n    throw e;\n  }\n\n  // We only return 200 from WB endpoints, but just in case let's accept all 2xx errors\n  if (resp.status <= 299) {\n    try {\n      const respData = await resp.json();\n      return respData.data;\n    } catch {\n      throw new StytchAPIUnreachableError('Invalid JSON response from our servers.');\n    }\n  }\n\n  // 99% of errors will be well-formed JSON errors with an appropriate content-type set\n  if (resp.status !== 200 && resp.headers.get('content-type')?.includes('application/json')) {\n    let respError;\n    try {\n      respError = await resp.json();\n    } catch {\n      // Error was not JSON- but the content type said it was! This means the server lied to us, which it should never do...\n      throw new StytchAPIUnreachableError('Invalid or no response from server');\n    }\n    // If this looks like a JSONSchema validation error, it probably means the caller isn't using\n    // typescript and gave us a bad type.\n    if ('body' in respError || 'params' in respError || 'query' in respError) {\n      throw new StytchAPISchemaError(respError);\n    }\n    throw new StytchAPIError(respError);\n  }\n\n  // Finally handle the other 1% of errors (Captcha errors, network errors, 503s, etc.)\n  let respData;\n  try {\n    respData = await resp.text();\n  } catch {\n    throw new StytchAPIUnreachableError('Invalid response from our servers.');\n  }\n  if (respData.includes('Captcha required')) {\n    throw new RetriableError(RetriableErrorType.RequiredCaptcha);\n  }\n  throw new StytchAPIUnreachableError('Invalid response from our servers.');\n}\n\nexport async function baseSubmitFormSDK({\n  method,\n  finalURL,\n  basicAuthHeader,\n  xSDKClientHeader,\n  xSDKParentHostHeader,\n  body,\n}: SDKBaseRequestInfo): Promise<void> {\n  const bodyParams = (body || {}) as Record<string, string>;\n  const finalBody: Record<string, string> = {\n    ...bodyParams,\n    __Authorization: basicAuthHeader,\n    '__X-SDK-Client': xSDKClientHeader,\n  };\n\n  if (xSDKParentHostHeader) {\n    finalBody['__X-SDK-Parent-Host'] = xSDKParentHostHeader;\n  }\n\n  const children: HTMLInputElement[] = Object.entries(finalBody).map(([key, value]) => {\n    const input = document.createElement('input');\n    input.type = 'hidden';\n    input.name = key;\n    input.value = value;\n    return input;\n  });\n\n  const form = document.createElement('form');\n  form.method = method;\n  form.action = finalURL;\n  form.append(...children);\n\n  document.body.appendChild(form);\n  form.submit();\n}\n"],"names":["RetriableErrorType","RetriableError","Error","type","retriableFetchSDK","method","finalURL","basicAuthHeader","xSDKClientHeader","xSDKParentHostHeader","body","retryCallback","req","baseFetchSDK","err","headers","Authorization","fetchOpts","JSON","stringify","credentials","resp","fetch","e","message","StytchAPIUnreachableError","status","respData","json","data","get","includes","respError","StytchAPISchemaError","StytchAPIError","text","baseSubmitFormSDK","bodyParams","finalBody","__Authorization","children","Object","entries","map","key","value","input","document","createElement","name","form","action","append","appendChild","submit"],"mappings":"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"}