{"version":3,"sources":["../../../src/api/widgets-api-client.ts"],"sourcesContent":["import { QueryKey, useQueryClient } from \"@tanstack/react-query\";\nimport {\n  AuthTokenQueryData,\n  authTokenQueryKey,\n  useApi,\n} from \"./api-provider.js\";\nimport { ApiError, FetchError } from \"./errors.js\";\nimport { getAuthHeaders, parseErrorResponse } from \"./utils.js\";\nimport { ExpiredTokenError, IncorrectPermissionsError } from \"../lib/errors.js\";\n\ntype WidgetsApiClient<T> = (data: {\n  url: string;\n  method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\";\n  params?: Record<string, any>;\n  headers?: Record<string, any>;\n  data?: BodyType<unknown>;\n  signal?: AbortSignal;\n}) => Promise<T>;\n\nexport const useWidgetsApiClient = <T>(): WidgetsApiClient<T> => {\n  const { authToken, baseUrl, elevatedAccess, widgetType } = useApi();\n  const queryClient = useQueryClient();\n\n  return async ({ url: pathname, method, params, data }) => {\n    const url = new URL(baseUrl);\n    url.pathname = pathname;\n\n    if (params) {\n      const cleanParams = Object.fromEntries(\n        Object.entries(params).filter(([_, value]) => value !== undefined),\n      );\n      url.search = new URLSearchParams(cleanParams).toString();\n    }\n\n    const queryType = method.toLowerCase() === \"get\" ? \"query\" : \"mutation\";\n    const buildHeaders = (token: string | undefined) => ({\n      ...getAuthHeaders(token),\n      ...(elevatedAccess && queryType === \"mutation\"\n        ? { \"x-elevated-access-token\": elevatedAccess.token }\n        : {}),\n      \"WorkOS-Widgets-Type\": widgetType,\n      \"Content-Type\": \"application/json\",\n    });\n\n    const sendRequest = (token: string | undefined) =>\n      fetch(url, {\n        method,\n        cache: \"no-store\",\n        headers: buildHeaders(token),\n        ...(data ? { body: JSON.stringify(data) } : {}),\n      }).catch((error) => {\n        throw new FetchError({\n          message: `Failed to ${method} ${url.toString()}`,\n          queryType,\n          context: { error },\n        });\n      });\n\n    let response = await sendRequest(authToken);\n\n    // On 403, try to re-mint the auth token and retry the request once. This\n    // handles the window-focus race (data query fires before authToken refetch\n    // resolves) and clock-skew cases where the proactive refresh timer in\n    // ApiProvider didn't catch the expiration in time.\n    if (response.status === 403) {\n      const tokenQueryKey = authTokenQueryKey(widgetType);\n\n      try {\n        await queryClient.refetchQueries({ queryKey: tokenQueryKey });\n      } catch (error) {\n        // If the host app's authToken function threw (the most common true\n        // \"session expired\"), surface this as ExpiredTokenError instead of\n        // letting the 403 fall through to IncorrectPermissionsError.\n        throw new ExpiredTokenError({\n          context: { status: 403, queryType, refetchError: error },\n        });\n      }\n\n      const refreshed =\n        queryClient.getQueryData<AuthTokenQueryData>(tokenQueryKey);\n      const freshToken = refreshed?.authToken;\n\n      if (freshToken && freshToken !== authToken) {\n        response = await sendRequest(freshToken);\n      }\n    }\n\n    if (!response.ok) {\n      const { message, status } = await parseErrorResponse(response);\n      const ctx = {\n        message,\n        status,\n        queryType,\n      } as const;\n\n      if (status === 403) {\n        const refreshed = queryClient.getQueryData<AuthTokenQueryData>(\n          authTokenQueryKey(widgetType),\n        );\n        const exp = refreshed?.exp;\n        if (exp !== undefined && exp * 1000 <= Date.now()) {\n          throw new ExpiredTokenError({ context: ctx });\n        }\n        throw new IncorrectPermissionsError({ context: ctx });\n      }\n\n      throw new ApiError(ctx);\n    }\n\n    return response.json();\n  };\n};\n\nexport type ErrorType<ErrorData> = ErrorData;\n\nexport type BodyType<BodyData> = BodyData & { headers?: any };\n\nexport const useWidgetsApiQueryOptions = <\n  QueryOptions extends { queryKey: QK },\n  QK extends QueryKey,\n>(\n  queryOptions: QueryOptions,\n) => {\n  const { permissions, baseUrl } = useApi();\n  const queryKey = [\n    // initial query key needs to go first to allow invalidation of the query name to work\n    ...queryOptions.queryKey,\n    permissions,\n    baseUrl,\n  ] as unknown as QK;\n\n  return {\n    ...queryOptions,\n    queryKey: queryKey as QK,\n  };\n};\n"],"mappings":"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","names":["import_errors"]}