import { z } from 'zod'; import { HBAClient } from 'roblox-bat'; import { type ParsedChallenge, type AnyError } from 'parse-roblox-errors'; export type { AnyError } from 'parse-roblox-errors'; type RequestMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'; type RequestFormat = 'json' | 'text' | 'form-data'; type SerializationMethod = Record; type EndpointBase = { method: RequestMethod; path: string; baseUrl: string; serializationMethod?: SerializationMethod; requestFormat?: RequestFormat; errors?: { status: number; description?: string; }[]; scopes?: string[]; }; export type EndpointSchema = EndpointBase & { parameters?: any; body?: any; response: any; }; /** * This is a hack to allow us to show the parameters and response types of an endpoint * as the inferred types of the parameters and response properties. */ export type EndpointGeneric = EndpointBase & { parameters?: T; body?: E; response: U; }; type InferZodObjectOptional = { [K in keyof T]: T[K] extends z.ZodOptional | z.ZodDefault ? K : never; }[keyof T]; type InferZodObjectRequired = { [K in keyof T]: T[K] extends z.ZodOptional | z.ZodDefault ? never : K; }[keyof T]; type Merge = T & U extends object ? { [K in keyof (T & U)]: (T & U)[K]; } : T & U; type InferNonEmpty>> = Merge<{ [K in InferZodObjectRequired]: z.infer; }, { [K in InferZodObjectOptional]?: z.infer; }>; declare const endpoint: >, U extends z.ZodTypeAny, E extends z.ZodTypeAny | undefined = undefined>(endpoint: EndpointGeneric) => EndpointGeneric, z.infer, E extends z.ZodTypeAny ? z.infer : undefined>; type IsExactlyUndefined = [T] extends [undefined] ? ([undefined] extends [T] ? true : false) : false; type ExtractParams> = S['parameters'] extends undefined ? IsExactlyUndefined extends true ? undefined : { body: S['body']; } : IsExactlyUndefined extends true ? S['parameters'] : S['parameters'] & { body: S['body']; }; type ExtractResponse> = S['response']; type RetryOptions = { retries?: number; retryDelay?: number; }; type ErrorOptions = { throwOnError?: boolean; }; type CacheOptions = { cacheTime?: number; cacheKey?: string; cacheType?: 'memory' | 'local' | 'chrome'; }; type RequestOptions = RequestInit & RetryOptions & ErrorOptions & CacheOptions & { returnRaw?: R; }; export declare const hbaClient: HBAClient; export type PoolRotation = 'none' | 'random' | 'round-robin'; /** * Event data passed to the cookie refresh callback when Roblox rotates a cookie. */ export type CookieRefreshEvent = { /** The old cookie value that was used in the request */ oldCookie: string; /** The new cookie value received from Roblox */ newCookie: string; /** The index in the cookie pool that was updated (0 for single cookie, should not be -1 in normal operation) */ poolIndex: number; }; /** * Callback function invoked when Roblox rotates a .ROBLOSECURITY cookie. * Use this to persist the new cookie value to your storage (env vars, database, etc.). * * @param event - Contains the old cookie, new cookie, and pool index * @returns void or Promise * * @example * ```ts * configureServer({ * cookies: process.env.ROBLOX_COOKIE, * onCookieRefresh: async (event) => { * // Update your environment variable or database * await updateDatabaseCookie(event.newCookie); * console.log('Cookie rotated! Old cookie index:', event.poolIndex); * } * }); * ``` */ export type CookieRefreshCallback = (event: CookieRefreshEvent) => void | Promise; export type ServerConfig = { /** * Pool of .ROBLOSECURITY cookie values (without the cookie name prefix). * Can be a single string or an array for multiple accounts. * Used for classic Roblox web API authentication. */ cookies?: string | string[]; /** * How to select cookies from the pool. * - 'none': Use the first cookie only (default for single cookie) * - 'random': Pick a random cookie per request * - 'round-robin': Cycle through cookies sequentially * Default: 'round-robin' when multiple cookies provided, 'none' for single cookie */ cookieRotation?: PoolRotation; /** * OpenCloud API key for apis.roblox.com endpoints. * Automatically applied as 'x-api-key' header for OpenCloud requests. */ cloudKey?: string; /** * Custom user agents pool. If not provided, uses built-in defaults. * Set to empty array to disable user agent injection. */ userAgents?: string[]; /** * How to select user agents from the pool. * - 'none': Use first/consistent UA for the session * - 'random': Pick a random UA per request * - 'round-robin': Cycle through UAs sequentially * Default: 'none' */ userAgentRotation?: PoolRotation; /** * Callback invoked when Roblox rotates a .ROBLOSECURITY cookie. * Roblox is gradually implementing cookie rotation for security. * Use this callback to persist the new cookie value to your storage. * * The internal cookie pool is automatically updated, so you only need * this callback if you want to persist the new cookie across restarts. * * @example * ```ts * configureServer({ * cookies: process.env.ROBLOX_COOKIE, * onCookieRefresh: async ({ oldCookie, newCookie, poolIndex }) => { * await db.updateCookie(poolIndex, newCookie); * console.log('Cookie rotated for account', poolIndex); * } * }); * ``` */ onCookieRefresh?: CookieRefreshCallback; }; /** * Configures RoZod for server/Node.js environments. * Sets default cookies and user-agents that will be automatically applied to all requests. * * @param config The server configuration options. * @example * ```ts * // Single account * configureServer({ cookies: '_|WARNING:-DO-NOT-SHARE-THIS...' }); * * // Multiple accounts with round-robin rotation (default) * configureServer({ * cookies: [ * '_|WARNING:-DO-NOT-SHARE-THIS-1...', * '_|WARNING:-DO-NOT-SHARE-THIS-2...', * '_|WARNING:-DO-NOT-SHARE-THIS-3...', * ], * }); * * // Multiple accounts with random selection * configureServer({ * cookies: ['cookie1', 'cookie2', 'cookie3'], * cookieRotation: 'random', * }); * * // With custom user agents and rotation * configureServer({ * cookies: ['...'], * userAgents: ['MyBot/1.0', 'MyBot/2.0'], * userAgentRotation: 'round-robin', * }); * * // Disable user agent injection * configureServer({ cookies: '...', userAgents: [] }); * ``` */ export declare function configureServer(config: ServerConfig): void; /** * Clears the server configuration. */ export declare function clearServerConfig(): void; /** * Gets the current server configuration (read-only copy, excluding internal state). */ export declare function getServerConfig(): Readonly; /** * Updates a specific cookie in the cookie pool by index. * Useful for manually updating cookies when you receive rotation events through other means. * * @param index - The index in the cookie pool to update (0 for single cookie) * @param newCookie - The new cookie value * @returns true if the cookie was updated, false if the index was invalid * * @example * ```ts * // Update the first (or only) cookie * updateCookie(0, 'new_cookie_value'); * * // Update a specific account in a pool * updateCookie(2, 'new_cookie_for_account_3'); * ``` */ export declare function updateCookie(index: number, newCookie: string): boolean; /** * Gets the current cookie values from the pool. * Useful for debugging or persisting all current cookie values. * * @returns Array of current cookie values, or empty array if none configured */ export declare function getCookies(): string[]; /** * Result of a manual cookie refresh operation. */ export type RefreshCookieResult = { success: boolean; /** The new cookie value if refresh was successful */ newCookie?: string; /** Error message if refresh failed */ error?: string; /** The index in the cookie pool that was refreshed */ poolIndex: number; }; /** * Proactively refreshes a cookie session using Roblox's session refresh endpoint. * This creates a new session and invalidates the old one, returning the new cookie. * * Use this to manually trigger cookie rotation before the automatic rotation kicks in, * or to refresh cookies on a schedule to ensure they don't expire. * * This function uses the library's internal fetch mechanism, which includes: * - Automatic CSRF token handling * - Hardware-backed authentication (HBA) signatures * - Generic challenge handling (if configured) * * @param cookieIndex - Index in the cookie pool to refresh (default: 0). Ignored if using single cookie. * @returns Result object with success status and new cookie value if successful * * @example * ```ts * // Refresh the default/first cookie * const result = await refreshCookie(); * if (result.success) { * console.log('New cookie:', result.newCookie); * // Persist the new cookie to your storage * await db.updateCookie(result.poolIndex, result.newCookie); * } * * // Refresh a specific cookie in the pool * const result = await refreshCookie(2); // Refresh third account * * // Refresh all cookies in a pool * const cookies = getCookies(); * for (let i = 0; i < cookies.length; i++) { * const result = await refreshCookie(i); * if (result.success) { * await db.updateCookie(i, result.newCookie); * } * } * ``` */ export declare function refreshCookie(cookieIndex?: number): Promise; declare let handleGenericChallengeFn: ((challenge: ParsedChallenge) => Promise | ParsedChallenge | undefined) | undefined; /** * Allows you to set the function that will be used to handle Roblox generic challenges, i.e. captchas, two-step verification. * @param fn The function to use. */ export declare function setHandleGenericChallenge(fn: typeof handleGenericChallengeFn): void; /** * Allows you to change the Crypto Key pair used by the internal hardware-based authentication signatures. This should only be used in a NodeJS context. * * @param keys The crypto key pair. */ export declare function changeHBAKeys(keys?: CryptoKeyPair): void; interface TypedJsonResponse extends Response { json: () => Promise; } /** * Fetches the data from the given endpoint and returns it. * * @param endpoint The endpoint to fetch from. * @param params The parameters to pass to the endpoint. * @param requestOptions Any additional options to pass to fetch. * @returns The response from the endpoint. */ declare function fetchApi(endpoint: S, params: ExtractParams, requestOptions: Omit, 'returnRaw'> & { returnRaw: true; }): Promise>>; declare function fetchApi(endpoint: S & { parameters: undefined; }, params: ExtractParams | undefined, requestOptions: Omit, 'returnRaw'> & { returnRaw: true; }): Promise>>; declare function fetchApi(endpoint: S, params: ExtractParams, requestOptions: Omit, 'throwOnError' | 'returnRaw'> & { throwOnError: true; returnRaw?: false; }): Promise>; declare function fetchApi(endpoint: S & { parameters: undefined; }, params: ExtractParams | undefined, requestOptions: Omit, 'throwOnError' | 'returnRaw'> & { throwOnError: true; returnRaw?: false; }): Promise>; declare function fetchApi(endpoint: S, params: ExtractParams, requestOptions?: Omit, 'returnRaw'> & { returnRaw?: false; }): Promise | AnyError>; declare function fetchApi(endpoint: S & { parameters: undefined; }, params?: ExtractParams, requestOptions?: Omit, 'returnRaw'> & { returnRaw?: false; }): Promise | AnyError>; /** * Fetches the data from the given endpoint and returns it. * * @param endpoint The endpoint to fetch from. * @param params Optional parameters to pass to the endpoint. * @param requestOptions Any additional options to pass to fetch. * @returns The response from the endpoint. */ declare function fetchApi(endpoint: S, params: ExtractParams | undefined, requestOptions?: RequestOptions): Promise> : ExtractResponse | AnyError>; export declare function isAnyErrorResponse(value: T | AnyError): value is AnyError; export declare function isAnyErrorResponse(value: T[] | AnyError): value is AnyError; /** * Fetches the data from the given endpoint, but splits the request into multiple requests if the specified parameter is larger than max specified. * * @param endpoint The endpoint to fetch from. * @param params The parameters to pass to the endpoint. * @param max The maximum number of items to pass to the endpoint. * @param transform A function that accepts the endpoint response and transforms it into the desired type. * @param requestOptions Any additional options to pass to fetch. * @returns The transformed response from the endpoint. * @example * ```ts * const data = await fetchApiSplit(getV1gamesicons, { universeIds: [1, 2, 3, 4, 5] }, { universeIds: 100 }, (response) => response.data); * console.log(data); // [[{ "targetId": 0, "state": "Completed", "imageUrl": "..." }], ...] * ``` */ declare function fetchApiSplit>(endpoint: S, params: ExtractParams, max?: Partial<{ [K in keyof ExtractParams]: number; }>, transform?: (response: ExtractResponse) => T, requestOptions?: RequestOptions): Promise; /** * Fetches all pages of results for the given endpoint and parameters. * * @param endpoint The endpoint to fetch. * @param initialParams The initial parameters to use for the endpoint. * @param requestOptions The options to use when making requests. * @param limit The maximum number of pages to fetch. * @returns An array of all results. */ declare function fetchApiPages(endpoint: S, initialParams: ExtractParams, requestOptions?: RequestOptions, limit?: number): Promise> | AnyError>; /** * Fetches all pages of results for the given endpoint and parameters. * This is a generator function that yields each page as it is fetched. * * @param endpoint The endpoint to fetch. * @param initialParams The initial parameters to use for the endpoint. * @param requestOptions The options to use when making requests. * @param limit The maximum number of pages to fetch. * @returns An array of all results. * @yields The next page of results. * @example * ```ts * const pages = fetchApiPagesGenerator(getV1badgesicons, { badgeIds: [1, 2, 3] }); * for await (const page of pages) { * console.log(page.data); * } * ``` */ declare function fetchApiPagesGenerator(endpoint: S, initialParams: ExtractParams, requestOptions?: RequestOptions, limit?: number): AsyncGenerator | AnyError, void, unknown>; export { fetchApi, fetchApiSplit, fetchApiPages, fetchApiPagesGenerator, ExtractResponse, ExtractParams, endpoint };