{"version":3,"file":"auth.cjs","names":["ReadableJsonStream"],"sources":["../src/auth.ts"],"sourcesContent":["import { ReadableJsonStream } from \"./utils/stream.js\";\nimport { GooglePlatformType } from \"./types.js\";\n\nexport type GoogleAbstractedClientOpsMethod = \"GET\" | \"POST\" | \"DELETE\";\n\nexport type GoogleAbstractedClientOpsResponseType = \"json\" | \"stream\" | \"blob\";\n\nexport type GoogleAbstractedClientOps = {\n  url?: string;\n  method?: GoogleAbstractedClientOpsMethod;\n  headers?: Record<string, string>;\n  data?: unknown;\n  responseType?: GoogleAbstractedClientOpsResponseType;\n  signal?: AbortSignal;\n};\n\nexport interface GoogleAbstractedClient {\n  request: (opts: GoogleAbstractedClientOps) => unknown;\n  getProjectId: () => Promise<string>;\n  get clientType(): string;\n}\n\nexport abstract class GoogleAbstractedFetchClient implements GoogleAbstractedClient {\n  abstract get clientType(): string;\n\n  abstract getProjectId(): Promise<string>;\n\n  abstract request(opts: GoogleAbstractedClientOps): unknown;\n\n  _fetch: typeof fetch = fetch;\n\n  async _buildData(res: Response, opts: GoogleAbstractedClientOps) {\n    switch (opts.responseType) {\n      case \"json\":\n        return res.json();\n      case \"stream\":\n        return new ReadableJsonStream(res.body);\n      default:\n        return res.blob();\n    }\n  }\n\n  /**\n   * Build and throw a standardised Google request error.\n   * Both the `!res.ok` path (native fetch) and the catch path (gaxios)\n   * funnel through here so the caller always sees the same shape.\n   */\n  protected _throwRequestError(\n    status: number,\n    body: string | undefined,\n    response: unknown,\n    context: {\n      url: string;\n      opts: GoogleAbstractedClientOps;\n      fetchOptions?: Record<string, unknown>;\n    }\n  ): never {\n    const message = body\n      ? `Google request failed with status code ${status}: ${body}`\n      : `Google request failed with status code ${status}`;\n    const error = new Error(message);\n    // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n    (error as any).response = response;\n    // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n    (error as any).details = context;\n    throw error;\n  }\n\n  async _request(\n    url: string | undefined,\n    opts: GoogleAbstractedClientOps,\n    additionalHeaders: Record<string, string>\n  ) {\n    if (url == null) throw new Error(\"Missing URL\");\n    const fetchOptions: {\n      method?: string;\n      headers: Record<string, string>;\n      body?: string;\n      signal?: AbortSignal;\n    } = {\n      method: opts.method,\n      headers: {\n        \"Content-Type\": \"application/json\",\n        ...(opts.headers ?? {}),\n        ...(additionalHeaders ?? {}),\n      },\n      signal: opts.signal,\n    };\n    if (opts.data !== undefined) {\n      if (typeof opts.data === \"string\") {\n        fetchOptions.body = opts.data;\n      } else {\n        fetchOptions.body = JSON.stringify(opts.data);\n      }\n    }\n\n    const context = { url, opts, fetchOptions };\n\n    let res: Response;\n    try {\n      res = await this._fetch(url, fetchOptions);\n    } catch (fetchError) {\n      // The _fetch implementation (e.g. GAuthClient using google-auth-library)\n      // may throw its own error (e.g. GaxiosError) for non-2xx responses\n      // before we can handle them here. Extract what we can from the error\n      // and re-throw with a useful, formatted message.\n      /* oxlint-disable @typescript-eslint/no-explicit-any */\n      const err = fetchError as any;\n      const status = err?.response?.status ?? err?.status;\n\n      if (status != null) {\n        let body: string | undefined;\n\n        if (err?.response?.data != null) {\n          if (typeof err.response.data === \"string\") {\n            body = err.response.data;\n          } else if (typeof err.response.data === \"object\") {\n            try {\n              body = JSON.stringify(err.response.data);\n            } catch {\n              // best effort\n            }\n          }\n        }\n\n        this._throwRequestError(\n          status,\n          body,\n          err?.response ?? { status },\n          context\n        );\n      }\n\n      // No status info available — re-throw the original error as-is\n      throw fetchError;\n      /* eslint-enable @typescript-eslint/no-explicit-any */\n    }\n\n    if (!res.ok) {\n      const body = await res.text();\n      this._throwRequestError(res.status, body, res, context);\n    }\n\n    const data = await this._buildData(res, opts);\n    return {\n      data,\n      config: {},\n      status: res.status,\n      statusText: res.statusText,\n      headers: res.headers,\n      request: { responseURL: res.url },\n    };\n  }\n}\n\nexport class ApiKeyGoogleAuth extends GoogleAbstractedFetchClient {\n  apiKey: string;\n\n  constructor(apiKey: string) {\n    super();\n    this.apiKey = apiKey;\n  }\n\n  get clientType(): string {\n    return \"apiKey\";\n  }\n\n  getProjectId(): Promise<string> {\n    throw new Error(\"APIs that require a project ID cannot use an API key\");\n    // Perhaps we could implement this if needed:\n    // https://cloud.google.com/docs/authentication/api-keys#get-info\n  }\n\n  request(opts: GoogleAbstractedClientOps): unknown {\n    const authHeader = {\n      \"X-Goog-Api-Key\": this.apiKey,\n    };\n    return this._request(opts.url, opts, authHeader);\n  }\n}\n\nexport function aiPlatformScope(platform: GooglePlatformType): string[] {\n  switch (platform) {\n    case \"gai\":\n      return [\"https://www.googleapis.com/auth/generative-language\"];\n    default:\n      return [\"https://www.googleapis.com/auth/cloud-platform\"];\n  }\n}\n\nexport function ensureAuthOptionScopes<AuthOptions>(\n  authOption: AuthOptions | undefined,\n  scopeProperty: string,\n  scopesOrPlatform: string[] | GooglePlatformType | undefined\n): AuthOptions {\n  // If the property is already set, return it\n  if (authOption && Object.hasOwn(authOption, scopeProperty)) {\n    return authOption;\n  }\n\n  // Otherwise add it\n  const scopes: string[] = Array.isArray(scopesOrPlatform)\n    ? (scopesOrPlatform as string[])\n    : aiPlatformScope(scopesOrPlatform ?? \"gcp\");\n  return {\n    [scopeProperty]: scopes,\n    ...(authOption ?? {}),\n  } as AuthOptions;\n}\n"],"mappings":";;AAsBA,IAAsB,8BAAtB,MAAoF;CAOlF,SAAuB;CAEvB,MAAM,WAAW,KAAe,MAAiC;AAC/D,UAAQ,KAAK,cAAb;GACE,KAAK,OACH,QAAO,IAAI,MAAM;GACnB,KAAK,SACH,QAAO,IAAIA,eAAAA,mBAAmB,IAAI,KAAK;GACzC,QACE,QAAO,IAAI,MAAM;;;;;;;;CASvB,mBACE,QACA,MACA,UACA,SAKO;EACP,MAAM,UAAU,OACZ,0CAA0C,OAAO,IAAI,SACrD,0CAA0C;EAC9C,MAAM,QAAQ,IAAI,MAAM,QAAQ;AAE/B,QAAc,WAAW;AAEzB,QAAc,UAAU;AACzB,QAAM;;CAGR,MAAM,SACJ,KACA,MACA,mBACA;AACA,MAAI,OAAO,KAAM,OAAM,IAAI,MAAM,cAAc;EAC/C,MAAM,eAKF;GACF,QAAQ,KAAK;GACb,SAAS;IACP,gBAAgB;IAChB,GAAI,KAAK,WAAW,EAAE;IACtB,GAAI,qBAAqB,EAAE;IAC5B;GACD,QAAQ,KAAK;GACd;AACD,MAAI,KAAK,SAAS,KAAA,EAChB,KAAI,OAAO,KAAK,SAAS,SACvB,cAAa,OAAO,KAAK;MAEzB,cAAa,OAAO,KAAK,UAAU,KAAK,KAAK;EAIjD,MAAM,UAAU;GAAE;GAAK;GAAM;GAAc;EAE3C,IAAI;AACJ,MAAI;AACF,SAAM,MAAM,KAAK,OAAO,KAAK,aAAa;WACnC,YAAY;GAMnB,MAAM,MAAM;GACZ,MAAM,SAAS,KAAK,UAAU,UAAU,KAAK;AAE7C,OAAI,UAAU,MAAM;IAClB,IAAI;AAEJ,QAAI,KAAK,UAAU,QAAQ;SACrB,OAAO,IAAI,SAAS,SAAS,SAC/B,QAAO,IAAI,SAAS;cACX,OAAO,IAAI,SAAS,SAAS,SACtC,KAAI;AACF,aAAO,KAAK,UAAU,IAAI,SAAS,KAAK;aAClC;;AAMZ,SAAK,mBACH,QACA,MACA,KAAK,YAAY,EAAE,QAAQ,EAC3B,QACD;;AAIH,SAAM;;AAIR,MAAI,CAAC,IAAI,IAAI;GACX,MAAM,OAAO,MAAM,IAAI,MAAM;AAC7B,QAAK,mBAAmB,IAAI,QAAQ,MAAM,KAAK,QAAQ;;AAIzD,SAAO;GACL,MAAA,MAFiB,KAAK,WAAW,KAAK,KAAK;GAG3C,QAAQ,EAAE;GACV,QAAQ,IAAI;GACZ,YAAY,IAAI;GAChB,SAAS,IAAI;GACb,SAAS,EAAE,aAAa,IAAI,KAAK;GAClC;;;AAIL,IAAa,mBAAb,cAAsC,4BAA4B;CAChE;CAEA,YAAY,QAAgB;AAC1B,SAAO;AACP,OAAK,SAAS;;CAGhB,IAAI,aAAqB;AACvB,SAAO;;CAGT,eAAgC;AAC9B,QAAM,IAAI,MAAM,uDAAuD;;CAKzE,QAAQ,MAA0C;EAChD,MAAM,aAAa,EACjB,kBAAkB,KAAK,QACxB;AACD,SAAO,KAAK,SAAS,KAAK,KAAK,MAAM,WAAW;;;AAIpD,SAAgB,gBAAgB,UAAwC;AACtE,SAAQ,UAAR;EACE,KAAK,MACH,QAAO,CAAC,sDAAsD;EAChE,QACE,QAAO,CAAC,iDAAiD;;;AAI/D,SAAgB,uBACd,YACA,eACA,kBACa;AAEb,KAAI,cAAc,OAAO,OAAO,YAAY,cAAc,CACxD,QAAO;CAIT,MAAM,SAAmB,MAAM,QAAQ,iBAAiB,GACnD,mBACD,gBAAgB,oBAAoB,MAAM;AAC9C,QAAO;GACJ,gBAAgB;EACjB,GAAI,cAAc,EAAE;EACrB"}