{"version":3,"file":"index.cjs","names":["cause?: unknown","data: unknown","response: Response","refreshPromise: Promise<Tokens> | null","newTokens: Tokens","fullConfig: Required<ManagementApiClientConfig>","url: URL","response: Response","error"],"sources":["../src/errors.ts","../src/auth.ts","../src/index.ts"],"sourcesContent":["/**\n * Error thrown when a network request fails.\n */\nexport class FetchError extends Error {\n  constructor(\n    message: string,\n    /** The underlying error that caused the fetch to fail. */\n    public override readonly cause?: unknown,\n  ) {\n    super(message);\n    this.name = \"FetchError\";\n  }\n}\n\n/**\n * Error thrown when authentication fails.\n */\nexport class AuthError extends Error {\n  constructor(\n    message: string,\n    /** Whether the refresh token is invalid/expired and the user needs to re-authenticate. */\n    public readonly refreshTokenInvalid = false,\n  ) {\n    super(message);\n    this.name = \"AuthError\";\n  }\n}\n","import { AuthError, FetchError } from \"./errors\";\nimport type { ManagementApiClientConfig, Tokens } from \"./index\";\n\n// JWT utilities\n\nfunction decodeJwtPayload(token: string): Record<string, unknown> {\n  const parts = token.split(\".\");\n  const payload = parts[1];\n  if (parts.length !== 3 || payload === undefined) {\n    throw new Error(\"Invalid JWT format\");\n  }\n  // Base64url decode: replace URL-safe chars and add padding\n  const base64 = payload.replace(/-/g, \"+\").replace(/_/g, \"/\");\n  const padded = base64 + \"=\".repeat((4 - (base64.length % 4)) % 4);\n  const decoded = atob(padded);\n  return JSON.parse(decoded) as Record<string, unknown>;\n}\n\nexport function extractWorkspaceId(accessToken: string): string {\n  const payload = decodeJwtPayload(accessToken);\n  const workspaceId = payload[\"workspace_id\"];\n  if (typeof workspaceId !== \"string\") {\n    throw new Error(\"workspace_id not found in access token\");\n  }\n  return workspaceId;\n}\n\n// PKCE utilities\n\nfunction base64urlEncode(buffer: Uint8Array): string {\n  const bytes = Array.from(buffer);\n  const base64 = btoa(String.fromCharCode(...bytes));\n  return base64.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n\nexport function generateRandomString(length: number): string {\n  const array = new Uint8Array(length);\n  crypto.getRandomValues(array);\n  return base64urlEncode(array);\n}\n\nexport async function generateCodeChallenge(verifier: string): Promise<string> {\n  const encoder = new TextEncoder();\n  const data = encoder.encode(verifier);\n  const hash = await crypto.subtle.digest(\"SHA-256\", data);\n  return base64urlEncode(new Uint8Array(hash));\n}\n\n// Token exchange utilities\n\nexport function tokenUrl(\n  config: Required<Pick<ManagementApiClientConfig, \"authBaseUrl\">>,\n): string {\n  return `${config.authBaseUrl}/token`;\n}\n\nexport type TokenResponse =\n  | { status: \"success\"; accessToken: string; refreshToken: string }\n  | { status: \"error\"; error: string; refreshTokenInvalid: boolean };\n\nfunction formatOAuthError(data: unknown): string {\n  if (typeof data === \"object\" && data !== null) {\n    const errorData = data as Record<string, unknown>;\n    const error = errorData[\"error\"];\n    const description = errorData[\"error_description\"];\n    if (typeof error === \"string\") {\n      return typeof description === \"string\"\n        ? `${error}: ${description}`\n        : error;\n    }\n  }\n  return \"Unknown error\";\n}\n\nexport async function parseTokenResponse(\n  response: Response,\n): Promise<TokenResponse> {\n  let data: unknown;\n  try {\n    data = await response.json();\n  } catch {\n    return {\n      status: \"error\",\n      error: `Failed to parse token response (status ${response.status})`,\n      refreshTokenInvalid: false,\n    };\n  }\n\n  if (response.status >= 400 && response.status < 500) {\n    const errorMessage = formatOAuthError(data);\n    // invalid_grant typically means the refresh token is expired or revoked\n    const isInvalidGrant =\n      typeof data === \"object\" &&\n      data !== null &&\n      (data as Record<string, unknown>)[\"error\"] === \"invalid_grant\";\n    return {\n      status: \"error\",\n      error: errorMessage,\n      refreshTokenInvalid: isInvalidGrant,\n    };\n  }\n\n  if (response.status !== 200) {\n    return {\n      status: \"error\",\n      error: `Token request failed with status ${response.status}`,\n      refreshTokenInvalid: false,\n    };\n  }\n\n  if (\n    typeof data !== \"object\" ||\n    !data ||\n    typeof (data as Record<string, unknown>)[\"access_token\"] !== \"string\" ||\n    typeof (data as Record<string, unknown>)[\"refresh_token\"] !== \"string\"\n  ) {\n    return {\n      status: \"error\",\n      error: \"Invalid token response format\",\n      refreshTokenInvalid: false,\n    };\n  }\n\n  const tokenData = data as { access_token: string; refresh_token: string };\n  return {\n    status: \"success\",\n    accessToken: tokenData.access_token,\n    refreshToken: tokenData.refresh_token,\n  };\n}\n\nexport async function refreshAccessToken(\n  config: Required<Pick<ManagementApiClientConfig, \"clientId\" | \"authBaseUrl\">>,\n  refreshToken: string,\n): Promise<TokenResponse> {\n  const body = new URLSearchParams({\n    grant_type: \"refresh_token\",\n    refresh_token: refreshToken,\n    client_id: config.clientId,\n  });\n\n  let response: Response;\n  try {\n    response = await fetch(tokenUrl(config), {\n      method: \"POST\",\n      headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n      body,\n    });\n  } catch {\n    return {\n      status: \"error\",\n      error: \"Network error during token refresh\",\n      refreshTokenInvalid: false,\n    };\n  }\n\n  return parseTokenResponse(response);\n}\n\nfunction tokensEqual(a: Tokens | null, b: Tokens | null): boolean {\n  return (\n    a?.workspaceId === b?.workspaceId &&\n    a?.accessToken === b?.accessToken &&\n    a?.refreshToken === b?.refreshToken\n  );\n}\n\nexport function createTokenRefreshingFetch(\n  config: Required<ManagementApiClientConfig>,\n) {\n  let refreshPromise: Promise<Tokens> | null = null;\n\n  const doRefresh = async (tokensThatFailed: Tokens): Promise<Tokens> => {\n    const withRefreshLock =\n      config.tokenStorage.withRefreshLock?.bind(config.tokenStorage) ??\n      (<T>(fn: () => Promise<T>) => fn());\n\n    return withRefreshLock(async () => {\n      const currentTokens = await config.tokenStorage.getTokens();\n      if (!currentTokens) {\n        throw new AuthError(\"No tokens available. Please log in first.\");\n      }\n\n      if (!tokensEqual(currentTokens, tokensThatFailed)) {\n        return currentTokens;\n      }\n\n      if (!currentTokens.refreshToken) {\n        throw new AuthError(\"No refresh token available. Please log in again.\");\n      }\n\n      const result = await refreshAccessToken(\n        config,\n        currentTokens.refreshToken,\n      );\n\n      if (result.status === \"error\") {\n        if (result.refreshTokenInvalid) {\n          if (config.tokenStorage.clearTokensIfCurrent) {\n            await config.tokenStorage.clearTokensIfCurrent(currentTokens);\n          } else {\n            await config.tokenStorage.clearTokens();\n          }\n        }\n        throw new AuthError(result.error, result.refreshTokenInvalid);\n      }\n\n      const newTokens: Tokens = {\n        accessToken: result.accessToken,\n        refreshToken: result.refreshToken,\n        workspaceId: extractWorkspaceId(result.accessToken),\n      };\n      await config.tokenStorage.setTokens(newTokens);\n\n      return newTokens;\n    });\n  };\n\n  const refreshTokens = async (tokensThatFailed: Tokens): Promise<Tokens> => {\n    if (refreshPromise) {\n      return refreshPromise;\n    }\n\n    refreshPromise = doRefresh(tokensThatFailed).finally(() => {\n      refreshPromise = null;\n    });\n\n    return refreshPromise;\n  };\n\n  return async function tokenRefreshingFetch(\n    request: globalThis.Request,\n  ): Promise<Response> {\n    request.signal.throwIfAborted();\n\n    const tokens = await config.tokenStorage.getTokens();\n    if (!tokens) {\n      throw new AuthError(\"No tokens available. Please log in first.\");\n    }\n\n    const requestCloneForRetry = request.clone();\n    request.headers.set(\"Authorization\", `Bearer ${tokens.accessToken}`);\n\n    let response: Response;\n    try {\n      response = await fetch(request);\n    } catch (error) {\n      request.signal.throwIfAborted();\n      throw new FetchError(\"Network request failed\", error);\n    }\n\n    if (response.status === 401) {\n      request.signal.throwIfAborted();\n\n      const newTokens = await refreshTokens(tokens);\n      requestCloneForRetry.headers.set(\n        \"Authorization\",\n        `Bearer ${newTokens.accessToken}`,\n      );\n      try {\n        response = await fetch(requestCloneForRetry);\n      } catch (error) {\n        request.signal.throwIfAborted();\n        throw new FetchError(\n          \"Network request failed after token refresh\",\n          error,\n        );\n      }\n    }\n\n    return response;\n  };\n}\n","import type { ClientOptions } from \"openapi-fetch\";\nimport createOpenAPIClient from \"openapi-fetch\";\nimport type { paths } from \"./api\";\nimport {\n  createTokenRefreshingFetch,\n  extractWorkspaceId,\n  generateCodeChallenge,\n  generateRandomString,\n  parseTokenResponse,\n  tokenUrl,\n} from \"./auth\";\nimport { AuthError, FetchError } from \"./errors\";\n\nexport type * from \"./api\";\nexport { AuthError, FetchError } from \"./errors\";\n\nconst DEFAULT_API_BASE_URL = \"https://api.prisma.io\";\nconst DEFAULT_AUTH_BASE_URL = \"https://auth.prisma.io\";\n\n// ============================================================================\n// Public Types\n// ============================================================================\n\nexport type Tokens = {\n  /*\n   * This is the workspace ID of the workspace that the tokens are valid for.\n   * It is extracted from the access token payload.\n   */\n  workspaceId: string;\n  /*\n   * This is the access token that can be used to make requests to the API.\n   */\n  accessToken: string;\n  /*\n   * This is the refresh token that can be used to refresh the access token.\n   * Only present if the scope includes 'offline_access'.\n   */\n  refreshToken?: string;\n};\n\n/**\n * Implement this interface to store and retrieve tokens from your environment.\n */\nexport interface TokenStorage {\n  /*\n   * Implement this method to provide the tokens to the SDK.\n   */\n  getTokens(): Promise<Tokens | null>;\n  /*\n   * Implement this method to store new or updated tokens when the SDK has successfully authenticated or refreshed tokens.\n   */\n  setTokens(tokens: Tokens): Promise<void>;\n  /*\n   * Implement this method to clear the tokens when the user logs out or the refresh token is invalid..\n   */\n  clearTokens(): Promise<void>;\n  /*\n   * Optionally serialize refresh attempts across processes.\n   */\n  withRefreshLock?<T>(fn: () => Promise<T>): Promise<T>;\n  /*\n   * Optionally clear tokens only if the stored value still matches the caller's stale view.\n   */\n  clearTokensIfCurrent?(tokens: Tokens): Promise<void>;\n}\n\n/**\n * Configuration options for creating a Management API instance.\n */\nexport type ManagementApiClientConfig = {\n  /** The OAuth client ID for authentication. */\n  clientId: string;\n  /** The URI to redirect to after OAuth authentication. */\n  redirectUri: string;\n  /** Implementation for storing and retrieving tokens. */\n  tokenStorage: TokenStorage;\n  /** Base URL for API requests. Defaults to 'https://api.prisma.io'. */\n  apiBaseUrl?: string;\n  /** Base URL for authentication requests. Defaults to 'https://auth.prisma.io'. */\n  authBaseUrl?: string;\n};\n\n/**\n * Options for generating an OAuth login URL.\n */\nexport type LoginUrlOptions = {\n  /** The OAuth scopes to request (e.g., 'workspace:admin offline_access'). */\n  scope: string;\n  /** Additional query parameters to include in the authorization URL (e.g. UTM parameters). */\n  additionalParams?: Record<string, string>;\n};\n\nexport type AsyncCallOptions = {\n  signal?: AbortSignal;\n};\n\n/**\n * A typed API client for making requests to the Management API.\n */\nexport type ManagementApiClient = ReturnType<typeof createOpenAPIClient<paths>>;\n\n/**\n * Result from generating an OAuth login URL.\n */\nexport type LoginResult = {\n  /** The authorization URL to redirect the user to. */\n  url: string;\n  /** The state parameter for CSRF protection. Must be stored and verified in the callback. */\n  state: string;\n  /** The PKCE code verifier. Must be stored and provided when handling the callback. */\n  verifier: string;\n};\n\n/**\n * Options for handling the OAuth callback after user authentication.\n */\nexport type HandleCallbackOptions = {\n  /** The full callback URL including query parameters. */\n  callbackUrl: string | URL;\n  /** The PKCE code verifier that was generated with the login URL. */\n  verifier: string;\n  /** The state parameter that was generated with the login URL, used for CSRF protection. */\n  expectedState: string;\n};\n\n/**\n * The Management API SDK instance with authentication handling.\n */\nexport type ManagementApiSdk = {\n  /** The typed API client for making requests. */\n  client: ManagementApiClient;\n  /** Generate an OAuth login URL with PKCE. */\n  getLoginUrl(\n    options: LoginUrlOptions,\n    asyncOptions?: AsyncCallOptions,\n  ): Promise<LoginResult>;\n  /** Handle the OAuth callback, exchange the code for tokens, and store them. */\n  handleCallback(\n    options: HandleCallbackOptions,\n    asyncOptions?: AsyncCallOptions,\n  ): Promise<void>;\n  /** Clear stored tokens and log out. */\n  logout(asyncOptions?: AsyncCallOptions): Promise<void>;\n};\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Creates a raw API client without authentication handling.\n * Useful if you want to manage authentication yourself.\n */\nexport function createManagementApiClient(\n  options: ClientOptions & { token?: string },\n): ManagementApiClient {\n  const clientOptions = {\n    ...options,\n    baseUrl: options.baseUrl ?? DEFAULT_API_BASE_URL,\n    headers: {\n      ...options.headers,\n      Authorization: options.token ? `Bearer ${options.token}` : undefined,\n    },\n  };\n  delete clientOptions.token;\n  return createOpenAPIClient<paths>(clientOptions);\n}\n\n/**\n * Creates a Management API instance with OAuth authentication and automatic token refresh.\n */\nexport function createManagementApiSdk(\n  config: ManagementApiClientConfig,\n): ManagementApiSdk {\n  const fullConfig: Required<ManagementApiClientConfig> = {\n    ...config,\n    apiBaseUrl: config.apiBaseUrl ?? DEFAULT_API_BASE_URL,\n    authBaseUrl: config.authBaseUrl ?? DEFAULT_AUTH_BASE_URL,\n  };\n\n  const client = createManagementApiClient({\n    baseUrl: fullConfig.apiBaseUrl,\n    fetch: createTokenRefreshingFetch(fullConfig),\n  });\n\n  client.use({\n    onError({ error, request }) {\n      request.signal.throwIfAborted();\n      if (error instanceof FetchError || error instanceof AuthError) {\n        return error;\n      }\n      return new FetchError(\"API request failed\", error);\n    },\n  });\n\n  async function getLoginUrl(\n    options: LoginUrlOptions,\n    asyncOptions?: AsyncCallOptions,\n  ): Promise<LoginResult> {\n    asyncOptions?.signal?.throwIfAborted();\n\n    const state = generateRandomString(16);\n    const verifier = generateRandomString(32);\n    const challenge = await generateCodeChallenge(verifier);\n\n    asyncOptions?.signal?.throwIfAborted();\n\n    const authUrl = new URL(`${fullConfig.authBaseUrl}/authorize`);\n    authUrl.searchParams.set(\"response_type\", \"code\");\n    authUrl.searchParams.set(\"client_id\", fullConfig.clientId);\n    authUrl.searchParams.set(\"redirect_uri\", fullConfig.redirectUri);\n    authUrl.searchParams.set(\"scope\", options.scope);\n    authUrl.searchParams.set(\"state\", state);\n    authUrl.searchParams.set(\"code_challenge\", challenge);\n    authUrl.searchParams.set(\"code_challenge_method\", \"S256\");\n\n    if (options.additionalParams) {\n      for (const [key, value] of Object.entries(options.additionalParams)) {\n        authUrl.searchParams.set(key, value);\n      }\n    }\n\n    return { url: authUrl.toString(), state, verifier };\n  }\n\n  async function handleCallback(\n    options: HandleCallbackOptions,\n    asyncOptions?: AsyncCallOptions,\n  ): Promise<void> {\n    let url: URL;\n    try {\n      url =\n        typeof options.callbackUrl === \"string\"\n          ? new URL(options.callbackUrl)\n          : options.callbackUrl;\n    } catch {\n      throw new AuthError(\"Invalid callback URL\");\n    }\n    const params = url.searchParams;\n\n    const error = params.get(\"error\");\n    if (error) {\n      const errorDescription = params.get(\"error_description\");\n      throw new AuthError(\n        errorDescription ? `${error}: ${errorDescription}` : error,\n      );\n    }\n\n    const code = params.get(\"code\");\n    const state = params.get(\"state\");\n\n    if (!code) {\n      throw new AuthError(\"No authorization code found in callback URL\");\n    }\n\n    if (state !== options.expectedState) {\n      throw new AuthError(\"Invalid state parameter. Possible CSRF attack.\");\n    }\n\n    asyncOptions?.signal?.throwIfAborted();\n\n    const body = new URLSearchParams({\n      grant_type: \"authorization_code\",\n      code,\n      redirect_uri: fullConfig.redirectUri,\n      client_id: fullConfig.clientId,\n      code_verifier: options.verifier,\n    });\n\n    let response: Response;\n    try {\n      response = await fetch(tokenUrl(fullConfig), {\n        method: \"POST\",\n        headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n        body,\n      });\n    } catch (error) {\n      throw new FetchError(\"Network error during token exchange\", error);\n    }\n\n    const result = await parseTokenResponse(response);\n\n    if (result.status === \"error\") {\n      throw new AuthError(result.error);\n    }\n\n    await fullConfig.tokenStorage.setTokens({\n      accessToken: result.accessToken,\n      refreshToken: result.refreshToken,\n      workspaceId: extractWorkspaceId(result.accessToken),\n    });\n  }\n\n  async function logout(asyncOptions?: AsyncCallOptions): Promise<void> {\n    asyncOptions?.signal?.throwIfAborted();\n    await fullConfig.tokenStorage.clearTokens();\n  }\n\n  return {\n    client,\n    getLoginUrl,\n    handleCallback,\n    logout,\n  };\n}\n"],"mappings":"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"}