Sign In

@runapi.ai/core

Package Overview
Dependencies
Maintainers
1
Versions
22
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@runapi.ai/core - npm Package Compare versions

Comparing version
0.3.4
to
0.3.5
+310
dist/chunk-V4WM5LRA.mjs
// src/constants.ts
var TIMEOUTS = {
/**
* Default HTTP request timeout (15 minutes).
* AI generation APIs can take significant time to complete.
*/
HTTP_REQUEST: 9e5,
/**
* Default polling timeout (15 minutes).
* Matches HTTP_REQUEST to allow long-running tasks to complete.
*/
POLLING_MAX_WAIT: 9e5,
/**
* Default polling interval (2 seconds).
* How often to check task status during polling.
*/
POLLING_INTERVAL: 2e3
};
var RETRY_CONFIG = {
/**
* Maximum number of retry attempts.
*/
MAX_RETRIES: 2,
/**
* Base delay between retries (500ms).
* Actual delay uses exponential backoff.
*/
BASE_DELAY: 500,
/**
* Maximum delay between retries (5 seconds).
* Caps the exponential backoff.
*/
MAX_DELAY: 5e3
};
var DEFAULT_BASE_URL = "https://runapi.ai";
var SDK_USER_AGENT = "runapi-sdk-js";
// src/retry.ts
function getRetryDelayMs(attempt, baseDelayMs, maxDelayMs) {
const exponential = baseDelayMs * Math.pow(2, attempt);
const capped = Math.min(exponential, maxDelayMs);
const jitter = Math.random() * capped * 0.5;
return Math.min(maxDelayMs, capped + jitter);
}
function isRetryableStatus(status) {
return status === 429 || status >= 500;
}
function isIdempotentMethod(method) {
return ["GET", "HEAD", "PUT", "DELETE", "OPTIONS"].includes(method);
}
function parseRetryAfterMs(response) {
const retryAfter = response.headers.get("retry-after");
if (!retryAfter) {
return void 0;
}
const numeric = Number(retryAfter);
if (!Number.isNaN(numeric)) {
return numeric * 1e3;
}
const dateMs = Date.parse(retryAfter);
if (!Number.isNaN(dateMs)) {
return Math.max(0, dateMs - Date.now());
}
return void 0;
}
// src/errors.ts
var RunApiError = class extends Error {
/** Explicit machine-readable reason when one was provided. */
code;
/** HTTP status code if available. */
status;
/** Request ID from response headers. */
requestId;
/** Parsed response body or error details. */
details;
constructor(message, options = {}) {
super(message, options);
this.name = "RunApiError";
this.code = options.code;
this.status = options.status;
this.requestId = options.requestId;
this.details = options.details;
}
};
var AuthenticationError = class extends RunApiError {
constructor(message, options = {}) {
super(message, { code: "authentication", ...options });
this.name = "AuthenticationError";
}
};
var RateLimitError = class extends RunApiError {
/** Suggested retry delay in milliseconds from `Retry-After` header. */
retryAfterMs;
constructor(message, options = {}) {
super(message, { code: "rate_limit", ...options });
this.name = "RateLimitError";
this.retryAfterMs = options.retryAfterMs;
}
};
var InsufficientCreditsError = class extends RunApiError {
constructor(message, options = {}) {
super(message, { code: "insufficient_credits", ...options });
this.name = "InsufficientCreditsError";
}
};
var NotFoundError = class extends RunApiError {
constructor(message, options = {}) {
super(message, { code: "not_found", ...options });
this.name = "NotFoundError";
}
};
var ValidationError = class extends RunApiError {
constructor(message, options = {}) {
super(message, { code: "validation", ...options });
this.name = "ValidationError";
}
};
var ConflictError = class extends RunApiError {
constructor(message, options = {}) {
super(message, { code: "conflict", ...options });
this.name = "ConflictError";
}
};
var ServiceUnavailableError = class extends RunApiError {
constructor(message, options = {}) {
super(message, { code: "service_unavailable", ...options });
this.name = "ServiceUnavailableError";
}
};
var NetworkError = class extends RunApiError {
constructor(message, options = {}) {
super(message, { code: "network", ...options });
this.name = "NetworkError";
}
};
var TimeoutError = class extends RunApiError {
constructor(message, options = {}) {
super(message, { code: "timeout", ...options });
this.name = "TimeoutError";
}
};
var TaskTimeoutError = class extends RunApiError {
constructor(message, options = {}) {
super(message, { code: "task_timeout", ...options });
this.name = "TaskTimeoutError";
}
};
var TaskFailedError = class extends RunApiError {
constructor(message, options = {}) {
super(message, { code: "task_failed", ...options });
this.name = "TaskFailedError";
}
};
var DEFAULT_ERROR_MESSAGE = "Request failed";
var HTML_MARKER = /<!doctype|<html/i;
function extractMessageFromUnknown(value) {
if (typeof value === "string" && value.trim()) {
return value.trim();
}
if (value && typeof value === "object") {
const maybeMessage = value.message;
if (typeof maybeMessage === "string" && maybeMessage.trim()) {
return maybeMessage.trim();
}
const maybeDetail = value.detail;
if (typeof maybeDetail === "string" && maybeDetail.trim()) {
return maybeDetail.trim();
}
}
return void 0;
}
function extractErrorMessage(body) {
if (typeof body === "string") {
if (!body.trim()) {
return void 0;
}
if (HTML_MARKER.test(body)) {
return void 0;
}
return body.trim();
}
if (!body || typeof body !== "object") {
return void 0;
}
const maybeError = body.error;
const errorMessage = extractMessageFromUnknown(maybeError);
if (errorMessage) {
return errorMessage;
}
const maybeMessage = body.message;
if (typeof maybeMessage === "string" && maybeMessage.trim()) {
return maybeMessage.trim();
}
const maybeDetail = body.detail;
if (typeof maybeDetail === "string" && maybeDetail.trim()) {
return maybeDetail.trim();
}
const maybeErrorMessage = body.errorMessage;
if (typeof maybeErrorMessage === "string" && maybeErrorMessage.trim()) {
return maybeErrorMessage.trim();
}
const maybeMsg = body.msg;
if (typeof maybeMsg === "string" && maybeMsg.trim()) {
return maybeMsg.trim();
}
return void 0;
}
function extractErrorCode(body) {
if (!body || typeof body !== "object") {
return void 0;
}
const error = body.error;
if (!error || typeof error !== "object") {
return void 0;
}
const code = error.code;
return typeof code === "string" && code.trim() ? code : void 0;
}
function defaultMessageForStatus(status) {
switch (status) {
case 400:
return "Bad request";
case 401:
return "Unauthorized";
case 402:
return "Insufficient credits";
case 404:
return "Not found";
case 409:
return "Conflict";
case 408:
return "Request timeout";
case 413:
return "Payload too large";
case 415:
return "Unsupported media type";
case 422:
return "Validation failed";
case 429:
return "Too many requests";
case 503:
return "Service unavailable";
default:
if (status >= 500) {
return "Server error";
}
return DEFAULT_ERROR_MESSAGE;
}
}
function errorFromResponse(response, bodyText, bodyJson) {
const status = response.status;
const requestId = response.headers.get("x-request-id") || void 0;
const messageFromBody = bodyJson === void 0 ? extractErrorMessage(bodyText) : extractErrorMessage(bodyJson);
const message = messageFromBody || defaultMessageForStatus(status);
const details = bodyJson ?? bodyText ?? void 0;
const code = extractErrorCode(bodyJson);
if (status === 401) {
return new AuthenticationError(message, { code, status, requestId, details });
}
if (status === 402) {
return new InsufficientCreditsError(message, { code, status, requestId, details });
}
if (status === 404) {
return new NotFoundError(message, { code, status, requestId, details });
}
if (status === 422 || status === 400) {
return new ValidationError(message, { code, status, requestId, details });
}
if (status === 409) {
return new ConflictError(message, { code, status, requestId, details });
}
if (status === 429) {
return new RateLimitError(message, {
status,
code,
requestId,
details,
retryAfterMs: parseRetryAfterMs(response)
});
}
if (status === 503) {
return new ServiceUnavailableError(message, { code, status, requestId, details });
}
return new RunApiError(message, { code, status, requestId, details });
}
export {
TIMEOUTS,
RETRY_CONFIG,
DEFAULT_BASE_URL,
SDK_USER_AGENT,
getRetryDelayMs,
isRetryableStatus,
isIdempotentMethod,
parseRetryAfterMs,
RunApiError,
AuthenticationError,
RateLimitError,
InsufficientCreditsError,
NotFoundError,
ValidationError,
ServiceUnavailableError,
NetworkError,
TimeoutError,
TaskTimeoutError,
TaskFailedError,
errorFromResponse
};
//# sourceMappingURL=chunk-V4WM5LRA.mjs.map
{"version":3,"sources":["../src/constants.ts","../src/retry.ts","../src/errors.ts"],"sourcesContent":["/**\n * Default timeout constants for SDK operations.\n * All values are in milliseconds.\n */\nexport const TIMEOUTS = {\n /**\n * Default HTTP request timeout (15 minutes).\n * AI generation APIs can take significant time to complete.\n */\n HTTP_REQUEST: 900000,\n\n /**\n * Default polling timeout (15 minutes).\n * Matches HTTP_REQUEST to allow long-running tasks to complete.\n */\n POLLING_MAX_WAIT: 900000,\n\n /**\n * Default polling interval (2 seconds).\n * How often to check task status during polling.\n */\n POLLING_INTERVAL: 2000,\n} as const;\n\n/**\n * Default retry configuration for HTTP requests.\n */\nexport const RETRY_CONFIG = {\n /**\n * Maximum number of retry attempts.\n */\n MAX_RETRIES: 2,\n\n /**\n * Base delay between retries (500ms).\n * Actual delay uses exponential backoff.\n */\n BASE_DELAY: 500,\n\n /**\n * Maximum delay between retries (5 seconds).\n * Caps the exponential backoff.\n */\n MAX_DELAY: 5000,\n} as const;\n\n/**\n * Default base URL for RunAPI services.\n */\nexport const DEFAULT_BASE_URL = 'https://runapi.ai';\n\n/**\n * SDK user agent string.\n */\nexport const SDK_USER_AGENT = 'runapi-sdk-js';\n","export interface RetryOptions {\n maxRetries: number;\n baseDelayMs: number;\n maxDelayMs: number;\n}\n\nexport function getRetryDelayMs(\n attempt: number,\n baseDelayMs: number,\n maxDelayMs: number\n): number {\n const exponential = baseDelayMs * Math.pow(2, attempt);\n const capped = Math.min(exponential, maxDelayMs);\n const jitter = Math.random() * capped * 0.5;\n return Math.min(maxDelayMs, capped + jitter);\n}\n\nexport function isRetryableStatus(status: number): boolean {\n return status === 429 || status >= 500;\n}\n\nexport function isIdempotentMethod(method: string): boolean {\n return ['GET', 'HEAD', 'PUT', 'DELETE', 'OPTIONS'].includes(method);\n}\n\nexport function parseRetryAfterMs(response: Response): number | undefined {\n const retryAfter = response.headers.get('retry-after');\n if (!retryAfter) {\n return undefined;\n }\n\n const numeric = Number(retryAfter);\n if (!Number.isNaN(numeric)) {\n return numeric * 1000;\n }\n\n const dateMs = Date.parse(retryAfter);\n if (!Number.isNaN(dateMs)) {\n return Math.max(0, dateMs - Date.now());\n }\n\n return undefined;\n}\n","import { parseRetryAfterMs } from './retry';\n\n/** Options for constructing RunApiError instances. */\nexport interface RunApiErrorOptions extends ErrorOptions {\n /** Explicit machine-readable reason. */\n code?: string;\n /** HTTP status code. */\n status?: number;\n /** Request ID from `X-Request-ID` header. */\n requestId?: string;\n /** Additional error details from response body. */\n details?: unknown;\n}\n\n/**\n * Base error class for all RunAPI SDK errors.\n * Includes HTTP status, request ID, and response details.\n */\nexport class RunApiError extends Error {\n /** Explicit machine-readable reason when one was provided. */\n code?: string;\n /** HTTP status code if available. */\n status?: number;\n /** Request ID from response headers. */\n requestId?: string;\n /** Parsed response body or error details. */\n details?: unknown;\n\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, options);\n this.name = 'RunApiError';\n this.code = options.code;\n this.status = options.status;\n this.requestId = options.requestId;\n this.details = options.details;\n }\n}\n\n/** Thrown when API key is missing or invalid (HTTP 401). */\nexport class AuthenticationError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'authentication', ...options });\n this.name = 'AuthenticationError';\n }\n}\n\n/** Thrown when rate limit is exceeded (HTTP 429). Includes retry-after delay. */\nexport class RateLimitError extends RunApiError {\n /** Suggested retry delay in milliseconds from `Retry-After` header. */\n retryAfterMs?: number;\n\n constructor(\n message: string,\n options: RunApiErrorOptions & { retryAfterMs?: number } = {}\n ) {\n super(message, { code: 'rate_limit', ...options });\n this.name = 'RateLimitError';\n this.retryAfterMs = options.retryAfterMs;\n }\n}\n\n/** Thrown when account has insufficient credits (HTTP 402). */\nexport class InsufficientCreditsError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'insufficient_credits', ...options });\n this.name = 'InsufficientCreditsError';\n }\n}\n\n/** Thrown when requested resource does not exist (HTTP 404). */\nexport class NotFoundError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'not_found', ...options });\n this.name = 'NotFoundError';\n }\n}\n\n/** Thrown when request validation fails (HTTP 400, 422). */\nexport class ValidationError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'validation', ...options });\n this.name = 'ValidationError';\n }\n}\n\n/** Thrown when a request conflicts with current resource state (HTTP 409). */\nexport class ConflictError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'conflict', ...options });\n this.name = 'ConflictError';\n }\n}\n\n/** Thrown when service is temporarily unavailable (HTTP 503). */\nexport class ServiceUnavailableError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'service_unavailable', ...options });\n this.name = 'ServiceUnavailableError';\n }\n}\n\n/** Thrown when network connection fails or request cannot be sent. */\nexport class NetworkError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'network', ...options });\n this.name = 'NetworkError';\n }\n}\n\n/** Thrown when HTTP request exceeds configured timeout. */\nexport class TimeoutError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'timeout', ...options });\n this.name = 'TimeoutError';\n }\n}\n\n/** Thrown when polling for task completion exceeds maximum wait time. */\nexport class TaskTimeoutError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'task_timeout', ...options });\n this.name = 'TaskTimeoutError';\n }\n}\n\n/** Thrown when async task fails during processing. */\nexport class TaskFailedError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'task_failed', ...options });\n this.name = 'TaskFailedError';\n }\n}\n\nconst DEFAULT_ERROR_MESSAGE = 'Request failed';\n\n// Detect HTML error pages from proxies/gateways to avoid leaking raw markup as message.\nconst HTML_MARKER = /<!doctype|<html/i;\n\nfunction extractMessageFromUnknown(value: unknown): string | undefined {\n if (typeof value === 'string' && value.trim()) {\n return value.trim();\n }\n\n if (value && typeof value === 'object') {\n const maybeMessage = (value as { message?: unknown }).message;\n if (typeof maybeMessage === 'string' && maybeMessage.trim()) {\n return maybeMessage.trim();\n }\n const maybeDetail = (value as { detail?: unknown }).detail;\n if (typeof maybeDetail === 'string' && maybeDetail.trim()) {\n return maybeDetail.trim();\n }\n }\n\n return undefined;\n}\n\nfunction extractErrorMessage(body: unknown): string | undefined {\n if (typeof body === 'string') {\n if (!body.trim()) {\n return undefined;\n }\n if (HTML_MARKER.test(body)) {\n return undefined;\n }\n return body.trim();\n }\n\n if (!body || typeof body !== 'object') {\n return undefined;\n }\n\n const maybeError = (body as { error?: unknown }).error;\n const errorMessage = extractMessageFromUnknown(maybeError);\n if (errorMessage) {\n return errorMessage;\n }\n\n const maybeMessage = (body as { message?: unknown }).message;\n if (typeof maybeMessage === 'string' && maybeMessage.trim()) {\n return maybeMessage.trim();\n }\n\n const maybeDetail = (body as { detail?: unknown }).detail;\n if (typeof maybeDetail === 'string' && maybeDetail.trim()) {\n return maybeDetail.trim();\n }\n\n const maybeErrorMessage = (body as { errorMessage?: unknown }).errorMessage;\n if (typeof maybeErrorMessage === 'string' && maybeErrorMessage.trim()) {\n return maybeErrorMessage.trim();\n }\n\n const maybeMsg = (body as { msg?: unknown }).msg;\n if (typeof maybeMsg === 'string' && maybeMsg.trim()) {\n return maybeMsg.trim();\n }\n\n return undefined;\n}\n\nfunction extractErrorCode(body: unknown): string | undefined {\n if (!body || typeof body !== 'object') {\n return undefined;\n }\n\n const error = (body as { error?: unknown }).error;\n if (!error || typeof error !== 'object') {\n return undefined;\n }\n\n const code = (error as { code?: unknown }).code;\n return typeof code === 'string' && code.trim() ? code : undefined;\n}\n\nfunction defaultMessageForStatus(status: number): string {\n switch (status) {\n case 400:\n return 'Bad request';\n case 401:\n return 'Unauthorized';\n case 402:\n return 'Insufficient credits';\n case 404:\n return 'Not found';\n case 409:\n return 'Conflict';\n case 408:\n return 'Request timeout';\n case 413:\n return 'Payload too large';\n case 415:\n return 'Unsupported media type';\n case 422:\n return 'Validation failed';\n case 429:\n return 'Too many requests';\n case 503:\n return 'Service unavailable';\n default:\n if (status >= 500) {\n return 'Server error';\n }\n return DEFAULT_ERROR_MESSAGE;\n }\n}\n\n/**\n * Constructs appropriate error class from HTTP response.\n * Maps status codes to specific error types and extracts error messages.\n *\n * @param response - HTTP Response object\n * @param bodyText - Response body as text\n * @param bodyJson - Parsed JSON body if available\n * @returns Specific error instance based on status code\n */\nexport function errorFromResponse(\n response: Response,\n bodyText: string | null,\n bodyJson?: unknown\n): RunApiError {\n const status = response.status;\n const requestId = response.headers.get('x-request-id') || undefined;\n const messageFromBody =\n bodyJson === undefined\n ? extractErrorMessage(bodyText)\n : extractErrorMessage(bodyJson);\n const message = messageFromBody || defaultMessageForStatus(status);\n const details = bodyJson ?? bodyText ?? undefined;\n const code = extractErrorCode(bodyJson);\n\n if (status === 401) {\n return new AuthenticationError(message, { code, status, requestId, details });\n }\n if (status === 402) {\n return new InsufficientCreditsError(message, { code, status, requestId, details });\n }\n if (status === 404) {\n return new NotFoundError(message, { code, status, requestId, details });\n }\n if (status === 422 || status === 400) {\n return new ValidationError(message, { code, status, requestId, details });\n }\n if (status === 409) {\n return new ConflictError(message, { code, status, requestId, details });\n }\n if (status === 429) {\n return new RateLimitError(message, {\n status,\n code,\n requestId,\n details,\n retryAfterMs: parseRetryAfterMs(response),\n });\n }\n if (status === 503) {\n return new ServiceUnavailableError(message, { code, status, requestId, details });\n }\n\n return new RunApiError(message, { code, status, requestId, details });\n}\n"],"mappings":"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","names":[]}
+1
-15

@@ -247,16 +247,2 @@ "use strict";

}
const maybeErrors = body.errors;
if (Array.isArray(maybeErrors) && maybeErrors.length > 0) {
const firstString = maybeErrors.find((item) => typeof item === "string");
if (typeof firstString === "string") {
return firstString;
}
const firstObject = maybeErrors.find(
(item) => item && typeof item === "object"
);
const objectMessage = extractMessageFromUnknown(firstObject);
if (objectMessage) {
return objectMessage;
}
}
const maybeMessage = body.message;

@@ -325,3 +311,3 @@ if (typeof maybeMessage === "string" && maybeMessage.trim()) {

const requestId = response.headers.get("x-request-id") || void 0;
const messageFromBody = extractErrorMessage(bodyJson) || extractErrorMessage(bodyText);
const messageFromBody = bodyJson === void 0 ? extractErrorMessage(bodyText) : extractErrorMessage(bodyJson);
const message = messageFromBody || defaultMessageForStatus(status);

@@ -328,0 +314,0 @@ const details = bodyJson ?? bodyText ?? void 0;

@@ -22,3 +22,3 @@ import {

parseRetryAfterMs
} from "./chunk-QT7BMRE5.mjs";
} from "./chunk-V4WM5LRA.mjs";

@@ -25,0 +25,0 @@ // src/auth.ts

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/polling.ts","../src/errors.ts","../src/constants.ts"],"sourcesContent":["import { TaskFailedError, TaskTimeoutError } from './errors';\nimport type { PollingOptions, TaskResponse, TaskStatus } from './types';\nimport { TIMEOUTS } from './constants';\n\nconst SUCCESS_STATUSES = new Set(['completed']);\nconst FAILED_STATUSES = new Set(['failed']);\nconst PENDING_STATUSES = new Set(['pending', 'processing']);\n\nfunction normalizeStatus(\n status: TaskStatus | string\n): 'completed' | 'failed' | 'processing' {\n const value = String(status).toLowerCase();\n if (SUCCESS_STATUSES.has(value)) {\n return 'completed';\n }\n if (FAILED_STATUSES.has(value)) {\n return 'failed';\n }\n if (PENDING_STATUSES.has(value)) {\n return 'processing';\n }\n return 'processing';\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport async function pollUntilComplete<T extends TaskResponse>(\n fetcher: () => Promise<T>,\n options: PollingOptions = {}\n): Promise<T> {\n const pollIntervalMs = options.pollIntervalMs ?? TIMEOUTS.POLLING_INTERVAL;\n const maxWaitMs = options.maxWaitMs ?? TIMEOUTS.POLLING_MAX_WAIT;\n const start = Date.now();\n\n while (true) {\n const response = await fetcher();\n const normalizedStatus = normalizeStatus(response.status);\n\n if (normalizedStatus === 'completed') {\n return response;\n }\n\n if (normalizedStatus === 'failed') {\n throw new TaskFailedError(response.error || 'Task failed', {\n details: response,\n });\n }\n\n if (Date.now() - start >= maxWaitMs) {\n throw new TaskTimeoutError('Task polling timed out', {\n details: response,\n });\n }\n\n await sleep(pollIntervalMs);\n }\n}\n","import { parseRetryAfterMs } from './retry';\n\n/** Options for constructing RunApiError instances. */\nexport interface RunApiErrorOptions extends ErrorOptions {\n /** Explicit machine-readable reason. */\n code?: string;\n /** HTTP status code. */\n status?: number;\n /** Request ID from `X-Request-ID` header. */\n requestId?: string;\n /** Additional error details from response body. */\n details?: unknown;\n}\n\n/**\n * Base error class for all RunAPI SDK errors.\n * Includes HTTP status, request ID, and response details.\n */\nexport class RunApiError extends Error {\n /** Explicit machine-readable reason when one was provided. */\n code?: string;\n /** HTTP status code if available. */\n status?: number;\n /** Request ID from response headers. */\n requestId?: string;\n /** Parsed response body or error details. */\n details?: unknown;\n\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, options);\n this.name = 'RunApiError';\n this.code = options.code;\n this.status = options.status;\n this.requestId = options.requestId;\n this.details = options.details;\n }\n}\n\n/** Thrown when API key is missing or invalid (HTTP 401). */\nexport class AuthenticationError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'authentication', ...options });\n this.name = 'AuthenticationError';\n }\n}\n\n/** Thrown when rate limit is exceeded (HTTP 429). Includes retry-after delay. */\nexport class RateLimitError extends RunApiError {\n /** Suggested retry delay in milliseconds from `Retry-After` header. */\n retryAfterMs?: number;\n\n constructor(\n message: string,\n options: RunApiErrorOptions & { retryAfterMs?: number } = {}\n ) {\n super(message, { code: 'rate_limit', ...options });\n this.name = 'RateLimitError';\n this.retryAfterMs = options.retryAfterMs;\n }\n}\n\n/** Thrown when account has insufficient credits (HTTP 402). */\nexport class InsufficientCreditsError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'insufficient_credits', ...options });\n this.name = 'InsufficientCreditsError';\n }\n}\n\n/** Thrown when requested resource does not exist (HTTP 404). */\nexport class NotFoundError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'not_found', ...options });\n this.name = 'NotFoundError';\n }\n}\n\n/** Thrown when request validation fails (HTTP 400, 422). */\nexport class ValidationError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'validation', ...options });\n this.name = 'ValidationError';\n }\n}\n\n/** Thrown when a request conflicts with current resource state (HTTP 409). */\nexport class ConflictError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'conflict', ...options });\n this.name = 'ConflictError';\n }\n}\n\n/** Thrown when service is temporarily unavailable (HTTP 503). */\nexport class ServiceUnavailableError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'service_unavailable', ...options });\n this.name = 'ServiceUnavailableError';\n }\n}\n\n/** Thrown when network connection fails or request cannot be sent. */\nexport class NetworkError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'network', ...options });\n this.name = 'NetworkError';\n }\n}\n\n/** Thrown when HTTP request exceeds configured timeout. */\nexport class TimeoutError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'timeout', ...options });\n this.name = 'TimeoutError';\n }\n}\n\n/** Thrown when polling for task completion exceeds maximum wait time. */\nexport class TaskTimeoutError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'task_timeout', ...options });\n this.name = 'TaskTimeoutError';\n }\n}\n\n/** Thrown when async task fails during processing. */\nexport class TaskFailedError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'task_failed', ...options });\n this.name = 'TaskFailedError';\n }\n}\n\nconst DEFAULT_ERROR_MESSAGE = 'Request failed';\n\n// Detect HTML error pages from proxies/gateways to avoid leaking raw markup as message.\nconst HTML_MARKER = /<!doctype|<html/i;\n\nfunction extractMessageFromUnknown(value: unknown): string | undefined {\n if (typeof value === 'string' && value.trim()) {\n return value.trim();\n }\n\n if (value && typeof value === 'object') {\n const maybeMessage = (value as { message?: unknown }).message;\n if (typeof maybeMessage === 'string' && maybeMessage.trim()) {\n return maybeMessage.trim();\n }\n const maybeDetail = (value as { detail?: unknown }).detail;\n if (typeof maybeDetail === 'string' && maybeDetail.trim()) {\n return maybeDetail.trim();\n }\n }\n\n return undefined;\n}\n\nfunction extractErrorMessage(body: unknown): string | undefined {\n if (typeof body === 'string') {\n if (!body.trim()) {\n return undefined;\n }\n if (HTML_MARKER.test(body)) {\n return undefined;\n }\n return body.trim();\n }\n\n if (!body || typeof body !== 'object') {\n return undefined;\n }\n\n const maybeError = (body as { error?: unknown }).error;\n const errorMessage = extractMessageFromUnknown(maybeError);\n if (errorMessage) {\n return errorMessage;\n }\n\n const maybeErrors = (body as { errors?: unknown }).errors;\n if (Array.isArray(maybeErrors) && maybeErrors.length > 0) {\n const firstString = maybeErrors.find((item) => typeof item === 'string');\n if (typeof firstString === 'string') {\n return firstString;\n }\n const firstObject = maybeErrors.find(\n (item) => item && typeof item === 'object'\n );\n const objectMessage = extractMessageFromUnknown(firstObject);\n if (objectMessage) {\n return objectMessage;\n }\n }\n\n const maybeMessage = (body as { message?: unknown }).message;\n if (typeof maybeMessage === 'string' && maybeMessage.trim()) {\n return maybeMessage.trim();\n }\n\n const maybeDetail = (body as { detail?: unknown }).detail;\n if (typeof maybeDetail === 'string' && maybeDetail.trim()) {\n return maybeDetail.trim();\n }\n\n const maybeErrorMessage = (body as { errorMessage?: unknown }).errorMessage;\n if (typeof maybeErrorMessage === 'string' && maybeErrorMessage.trim()) {\n return maybeErrorMessage.trim();\n }\n\n const maybeMsg = (body as { msg?: unknown }).msg;\n if (typeof maybeMsg === 'string' && maybeMsg.trim()) {\n return maybeMsg.trim();\n }\n\n return undefined;\n}\n\nfunction extractErrorCode(body: unknown): string | undefined {\n if (!body || typeof body !== 'object') {\n return undefined;\n }\n\n const error = (body as { error?: unknown }).error;\n if (!error || typeof error !== 'object') {\n return undefined;\n }\n\n const code = (error as { code?: unknown }).code;\n return typeof code === 'string' && code.trim() ? code : undefined;\n}\n\nfunction defaultMessageForStatus(status: number): string {\n switch (status) {\n case 400:\n return 'Bad request';\n case 401:\n return 'Unauthorized';\n case 402:\n return 'Insufficient credits';\n case 404:\n return 'Not found';\n case 409:\n return 'Conflict';\n case 408:\n return 'Request timeout';\n case 413:\n return 'Payload too large';\n case 415:\n return 'Unsupported media type';\n case 422:\n return 'Validation failed';\n case 429:\n return 'Too many requests';\n case 503:\n return 'Service unavailable';\n default:\n if (status >= 500) {\n return 'Server error';\n }\n return DEFAULT_ERROR_MESSAGE;\n }\n}\n\n/**\n * Constructs appropriate error class from HTTP response.\n * Maps status codes to specific error types and extracts error messages.\n *\n * @param response - HTTP Response object\n * @param bodyText - Response body as text\n * @param bodyJson - Parsed JSON body if available\n * @returns Specific error instance based on status code\n */\nexport function errorFromResponse(\n response: Response,\n bodyText: string | null,\n bodyJson?: unknown\n): RunApiError {\n const status = response.status;\n const requestId = response.headers.get('x-request-id') || undefined;\n const messageFromBody =\n extractErrorMessage(bodyJson) || extractErrorMessage(bodyText);\n const message = messageFromBody || defaultMessageForStatus(status);\n const details = bodyJson ?? bodyText ?? undefined;\n const code = extractErrorCode(bodyJson);\n\n if (status === 401) {\n return new AuthenticationError(message, { code, status, requestId, details });\n }\n if (status === 402) {\n return new InsufficientCreditsError(message, { code, status, requestId, details });\n }\n if (status === 404) {\n return new NotFoundError(message, { code, status, requestId, details });\n }\n if (status === 422 || status === 400) {\n return new ValidationError(message, { code, status, requestId, details });\n }\n if (status === 409) {\n return new ConflictError(message, { code, status, requestId, details });\n }\n if (status === 429) {\n return new RateLimitError(message, {\n status,\n code,\n requestId,\n details,\n retryAfterMs: parseRetryAfterMs(response),\n });\n }\n if (status === 503) {\n return new ServiceUnavailableError(message, { code, status, requestId, details });\n }\n\n return new RunApiError(message, { code, status, requestId, details });\n}\n","/**\n * Default timeout constants for SDK operations.\n * All values are in milliseconds.\n */\nexport const TIMEOUTS = {\n /**\n * Default HTTP request timeout (15 minutes).\n * AI generation APIs can take significant time to complete.\n */\n HTTP_REQUEST: 900000,\n\n /**\n * Default polling timeout (15 minutes).\n * Matches HTTP_REQUEST to allow long-running tasks to complete.\n */\n POLLING_MAX_WAIT: 900000,\n\n /**\n * Default polling interval (2 seconds).\n * How often to check task status during polling.\n */\n POLLING_INTERVAL: 2000,\n} as const;\n\n/**\n * Default retry configuration for HTTP requests.\n */\nexport const RETRY_CONFIG = {\n /**\n * Maximum number of retry attempts.\n */\n MAX_RETRIES: 2,\n\n /**\n * Base delay between retries (500ms).\n * Actual delay uses exponential backoff.\n */\n BASE_DELAY: 500,\n\n /**\n * Maximum delay between retries (5 seconds).\n * Caps the exponential backoff.\n */\n MAX_DELAY: 5000,\n} as const;\n\n/**\n * Default base URL for RunAPI services.\n */\nexport const DEFAULT_BASE_URL = 'https://runapi.ai';\n\n/**\n * SDK user agent string.\n */\nexport const SDK_USER_AGENT = 'runapi-sdk-js';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACkBO,IAAM,cAAN,cAA0B,MAAM;AAAA;AAAA,EAErC;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EAEA,YAAY,SAAiB,UAA8B,CAAC,GAAG;AAC7D,UAAM,SAAS,OAAO;AACtB,SAAK,OAAO;AACZ,SAAK,OAAO,QAAQ;AACpB,SAAK,SAAS,QAAQ;AACtB,SAAK,YAAY,QAAQ;AACzB,SAAK,UAAU,QAAQ;AAAA,EACzB;AACF;AAkFO,IAAM,mBAAN,cAA+B,YAAY;AAAA,EAChD,YAAY,SAAiB,UAA8B,CAAC,GAAG;AAC7D,UAAM,SAAS,EAAE,MAAM,gBAAgB,GAAG,QAAQ,CAAC;AACnD,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,kBAAN,cAA8B,YAAY;AAAA,EAC/C,YAAY,SAAiB,UAA8B,CAAC,GAAG;AAC7D,UAAM,SAAS,EAAE,MAAM,eAAe,GAAG,QAAQ,CAAC;AAClD,SAAK,OAAO;AAAA,EACd;AACF;;;AC/HO,IAAM,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA,EAKtB,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA,EAMd,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMlB,kBAAkB;AACpB;;;AFlBA,IAAM,mBAAmB,oBAAI,IAAI,CAAC,WAAW,CAAC;AAC9C,IAAM,kBAAkB,oBAAI,IAAI,CAAC,QAAQ,CAAC;AAC1C,IAAM,mBAAmB,oBAAI,IAAI,CAAC,WAAW,YAAY,CAAC;AAE1D,SAAS,gBACP,QACuC;AACvC,QAAM,QAAQ,OAAO,MAAM,EAAE,YAAY;AACzC,MAAI,iBAAiB,IAAI,KAAK,GAAG;AAC/B,WAAO;AAAA,EACT;AACA,MAAI,gBAAgB,IAAI,KAAK,GAAG;AAC9B,WAAO;AAAA,EACT;AACA,MAAI,iBAAiB,IAAI,KAAK,GAAG;AAC/B,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,MAAM,IAA2B;AACxC,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AACzD;AAEA,eAAsB,kBACpB,SACA,UAA0B,CAAC,GACf;AACZ,QAAM,iBAAiB,QAAQ,kBAAkB,SAAS;AAC1D,QAAM,YAAY,QAAQ,aAAa,SAAS;AAChD,QAAM,QAAQ,KAAK,IAAI;AAEvB,SAAO,MAAM;AACX,UAAM,WAAW,MAAM,QAAQ;AAC/B,UAAM,mBAAmB,gBAAgB,SAAS,MAAM;AAExD,QAAI,qBAAqB,aAAa;AACpC,aAAO;AAAA,IACT;AAEA,QAAI,qBAAqB,UAAU;AACjC,YAAM,IAAI,gBAAgB,SAAS,SAAS,eAAe;AAAA,QACzD,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAEA,QAAI,KAAK,IAAI,IAAI,SAAS,WAAW;AACnC,YAAM,IAAI,iBAAiB,0BAA0B;AAAA,QACnD,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAEA,UAAM,MAAM,cAAc;AAAA,EAC5B;AACF;","names":[]}
{"version":3,"sources":["../src/polling.ts","../src/errors.ts","../src/constants.ts"],"sourcesContent":["import { TaskFailedError, TaskTimeoutError } from './errors';\nimport type { PollingOptions, TaskResponse, TaskStatus } from './types';\nimport { TIMEOUTS } from './constants';\n\nconst SUCCESS_STATUSES = new Set(['completed']);\nconst FAILED_STATUSES = new Set(['failed']);\nconst PENDING_STATUSES = new Set(['pending', 'processing']);\n\nfunction normalizeStatus(\n status: TaskStatus | string\n): 'completed' | 'failed' | 'processing' {\n const value = String(status).toLowerCase();\n if (SUCCESS_STATUSES.has(value)) {\n return 'completed';\n }\n if (FAILED_STATUSES.has(value)) {\n return 'failed';\n }\n if (PENDING_STATUSES.has(value)) {\n return 'processing';\n }\n return 'processing';\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport async function pollUntilComplete<T extends TaskResponse>(\n fetcher: () => Promise<T>,\n options: PollingOptions = {}\n): Promise<T> {\n const pollIntervalMs = options.pollIntervalMs ?? TIMEOUTS.POLLING_INTERVAL;\n const maxWaitMs = options.maxWaitMs ?? TIMEOUTS.POLLING_MAX_WAIT;\n const start = Date.now();\n\n while (true) {\n const response = await fetcher();\n const normalizedStatus = normalizeStatus(response.status);\n\n if (normalizedStatus === 'completed') {\n return response;\n }\n\n if (normalizedStatus === 'failed') {\n throw new TaskFailedError(response.error || 'Task failed', {\n details: response,\n });\n }\n\n if (Date.now() - start >= maxWaitMs) {\n throw new TaskTimeoutError('Task polling timed out', {\n details: response,\n });\n }\n\n await sleep(pollIntervalMs);\n }\n}\n","import { parseRetryAfterMs } from './retry';\n\n/** Options for constructing RunApiError instances. */\nexport interface RunApiErrorOptions extends ErrorOptions {\n /** Explicit machine-readable reason. */\n code?: string;\n /** HTTP status code. */\n status?: number;\n /** Request ID from `X-Request-ID` header. */\n requestId?: string;\n /** Additional error details from response body. */\n details?: unknown;\n}\n\n/**\n * Base error class for all RunAPI SDK errors.\n * Includes HTTP status, request ID, and response details.\n */\nexport class RunApiError extends Error {\n /** Explicit machine-readable reason when one was provided. */\n code?: string;\n /** HTTP status code if available. */\n status?: number;\n /** Request ID from response headers. */\n requestId?: string;\n /** Parsed response body or error details. */\n details?: unknown;\n\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, options);\n this.name = 'RunApiError';\n this.code = options.code;\n this.status = options.status;\n this.requestId = options.requestId;\n this.details = options.details;\n }\n}\n\n/** Thrown when API key is missing or invalid (HTTP 401). */\nexport class AuthenticationError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'authentication', ...options });\n this.name = 'AuthenticationError';\n }\n}\n\n/** Thrown when rate limit is exceeded (HTTP 429). Includes retry-after delay. */\nexport class RateLimitError extends RunApiError {\n /** Suggested retry delay in milliseconds from `Retry-After` header. */\n retryAfterMs?: number;\n\n constructor(\n message: string,\n options: RunApiErrorOptions & { retryAfterMs?: number } = {}\n ) {\n super(message, { code: 'rate_limit', ...options });\n this.name = 'RateLimitError';\n this.retryAfterMs = options.retryAfterMs;\n }\n}\n\n/** Thrown when account has insufficient credits (HTTP 402). */\nexport class InsufficientCreditsError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'insufficient_credits', ...options });\n this.name = 'InsufficientCreditsError';\n }\n}\n\n/** Thrown when requested resource does not exist (HTTP 404). */\nexport class NotFoundError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'not_found', ...options });\n this.name = 'NotFoundError';\n }\n}\n\n/** Thrown when request validation fails (HTTP 400, 422). */\nexport class ValidationError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'validation', ...options });\n this.name = 'ValidationError';\n }\n}\n\n/** Thrown when a request conflicts with current resource state (HTTP 409). */\nexport class ConflictError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'conflict', ...options });\n this.name = 'ConflictError';\n }\n}\n\n/** Thrown when service is temporarily unavailable (HTTP 503). */\nexport class ServiceUnavailableError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'service_unavailable', ...options });\n this.name = 'ServiceUnavailableError';\n }\n}\n\n/** Thrown when network connection fails or request cannot be sent. */\nexport class NetworkError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'network', ...options });\n this.name = 'NetworkError';\n }\n}\n\n/** Thrown when HTTP request exceeds configured timeout. */\nexport class TimeoutError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'timeout', ...options });\n this.name = 'TimeoutError';\n }\n}\n\n/** Thrown when polling for task completion exceeds maximum wait time. */\nexport class TaskTimeoutError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'task_timeout', ...options });\n this.name = 'TaskTimeoutError';\n }\n}\n\n/** Thrown when async task fails during processing. */\nexport class TaskFailedError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'task_failed', ...options });\n this.name = 'TaskFailedError';\n }\n}\n\nconst DEFAULT_ERROR_MESSAGE = 'Request failed';\n\n// Detect HTML error pages from proxies/gateways to avoid leaking raw markup as message.\nconst HTML_MARKER = /<!doctype|<html/i;\n\nfunction extractMessageFromUnknown(value: unknown): string | undefined {\n if (typeof value === 'string' && value.trim()) {\n return value.trim();\n }\n\n if (value && typeof value === 'object') {\n const maybeMessage = (value as { message?: unknown }).message;\n if (typeof maybeMessage === 'string' && maybeMessage.trim()) {\n return maybeMessage.trim();\n }\n const maybeDetail = (value as { detail?: unknown }).detail;\n if (typeof maybeDetail === 'string' && maybeDetail.trim()) {\n return maybeDetail.trim();\n }\n }\n\n return undefined;\n}\n\nfunction extractErrorMessage(body: unknown): string | undefined {\n if (typeof body === 'string') {\n if (!body.trim()) {\n return undefined;\n }\n if (HTML_MARKER.test(body)) {\n return undefined;\n }\n return body.trim();\n }\n\n if (!body || typeof body !== 'object') {\n return undefined;\n }\n\n const maybeError = (body as { error?: unknown }).error;\n const errorMessage = extractMessageFromUnknown(maybeError);\n if (errorMessage) {\n return errorMessage;\n }\n\n const maybeMessage = (body as { message?: unknown }).message;\n if (typeof maybeMessage === 'string' && maybeMessage.trim()) {\n return maybeMessage.trim();\n }\n\n const maybeDetail = (body as { detail?: unknown }).detail;\n if (typeof maybeDetail === 'string' && maybeDetail.trim()) {\n return maybeDetail.trim();\n }\n\n const maybeErrorMessage = (body as { errorMessage?: unknown }).errorMessage;\n if (typeof maybeErrorMessage === 'string' && maybeErrorMessage.trim()) {\n return maybeErrorMessage.trim();\n }\n\n const maybeMsg = (body as { msg?: unknown }).msg;\n if (typeof maybeMsg === 'string' && maybeMsg.trim()) {\n return maybeMsg.trim();\n }\n\n return undefined;\n}\n\nfunction extractErrorCode(body: unknown): string | undefined {\n if (!body || typeof body !== 'object') {\n return undefined;\n }\n\n const error = (body as { error?: unknown }).error;\n if (!error || typeof error !== 'object') {\n return undefined;\n }\n\n const code = (error as { code?: unknown }).code;\n return typeof code === 'string' && code.trim() ? code : undefined;\n}\n\nfunction defaultMessageForStatus(status: number): string {\n switch (status) {\n case 400:\n return 'Bad request';\n case 401:\n return 'Unauthorized';\n case 402:\n return 'Insufficient credits';\n case 404:\n return 'Not found';\n case 409:\n return 'Conflict';\n case 408:\n return 'Request timeout';\n case 413:\n return 'Payload too large';\n case 415:\n return 'Unsupported media type';\n case 422:\n return 'Validation failed';\n case 429:\n return 'Too many requests';\n case 503:\n return 'Service unavailable';\n default:\n if (status >= 500) {\n return 'Server error';\n }\n return DEFAULT_ERROR_MESSAGE;\n }\n}\n\n/**\n * Constructs appropriate error class from HTTP response.\n * Maps status codes to specific error types and extracts error messages.\n *\n * @param response - HTTP Response object\n * @param bodyText - Response body as text\n * @param bodyJson - Parsed JSON body if available\n * @returns Specific error instance based on status code\n */\nexport function errorFromResponse(\n response: Response,\n bodyText: string | null,\n bodyJson?: unknown\n): RunApiError {\n const status = response.status;\n const requestId = response.headers.get('x-request-id') || undefined;\n const messageFromBody =\n bodyJson === undefined\n ? extractErrorMessage(bodyText)\n : extractErrorMessage(bodyJson);\n const message = messageFromBody || defaultMessageForStatus(status);\n const details = bodyJson ?? bodyText ?? undefined;\n const code = extractErrorCode(bodyJson);\n\n if (status === 401) {\n return new AuthenticationError(message, { code, status, requestId, details });\n }\n if (status === 402) {\n return new InsufficientCreditsError(message, { code, status, requestId, details });\n }\n if (status === 404) {\n return new NotFoundError(message, { code, status, requestId, details });\n }\n if (status === 422 || status === 400) {\n return new ValidationError(message, { code, status, requestId, details });\n }\n if (status === 409) {\n return new ConflictError(message, { code, status, requestId, details });\n }\n if (status === 429) {\n return new RateLimitError(message, {\n status,\n code,\n requestId,\n details,\n retryAfterMs: parseRetryAfterMs(response),\n });\n }\n if (status === 503) {\n return new ServiceUnavailableError(message, { code, status, requestId, details });\n }\n\n return new RunApiError(message, { code, status, requestId, details });\n}\n","/**\n * Default timeout constants for SDK operations.\n * All values are in milliseconds.\n */\nexport const TIMEOUTS = {\n /**\n * Default HTTP request timeout (15 minutes).\n * AI generation APIs can take significant time to complete.\n */\n HTTP_REQUEST: 900000,\n\n /**\n * Default polling timeout (15 minutes).\n * Matches HTTP_REQUEST to allow long-running tasks to complete.\n */\n POLLING_MAX_WAIT: 900000,\n\n /**\n * Default polling interval (2 seconds).\n * How often to check task status during polling.\n */\n POLLING_INTERVAL: 2000,\n} as const;\n\n/**\n * Default retry configuration for HTTP requests.\n */\nexport const RETRY_CONFIG = {\n /**\n * Maximum number of retry attempts.\n */\n MAX_RETRIES: 2,\n\n /**\n * Base delay between retries (500ms).\n * Actual delay uses exponential backoff.\n */\n BASE_DELAY: 500,\n\n /**\n * Maximum delay between retries (5 seconds).\n * Caps the exponential backoff.\n */\n MAX_DELAY: 5000,\n} as const;\n\n/**\n * Default base URL for RunAPI services.\n */\nexport const DEFAULT_BASE_URL = 'https://runapi.ai';\n\n/**\n * SDK user agent string.\n */\nexport const SDK_USER_AGENT = 'runapi-sdk-js';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACkBO,IAAM,cAAN,cAA0B,MAAM;AAAA;AAAA,EAErC;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EAEA,YAAY,SAAiB,UAA8B,CAAC,GAAG;AAC7D,UAAM,SAAS,OAAO;AACtB,SAAK,OAAO;AACZ,SAAK,OAAO,QAAQ;AACpB,SAAK,SAAS,QAAQ;AACtB,SAAK,YAAY,QAAQ;AACzB,SAAK,UAAU,QAAQ;AAAA,EACzB;AACF;AAkFO,IAAM,mBAAN,cAA+B,YAAY;AAAA,EAChD,YAAY,SAAiB,UAA8B,CAAC,GAAG;AAC7D,UAAM,SAAS,EAAE,MAAM,gBAAgB,GAAG,QAAQ,CAAC;AACnD,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,kBAAN,cAA8B,YAAY;AAAA,EAC/C,YAAY,SAAiB,UAA8B,CAAC,GAAG;AAC7D,UAAM,SAAS,EAAE,MAAM,eAAe,GAAG,QAAQ,CAAC;AAClD,SAAK,OAAO;AAAA,EACd;AACF;;;AC/HO,IAAM,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA,EAKtB,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA,EAMd,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMlB,kBAAkB;AACpB;;;AFlBA,IAAM,mBAAmB,oBAAI,IAAI,CAAC,WAAW,CAAC;AAC9C,IAAM,kBAAkB,oBAAI,IAAI,CAAC,QAAQ,CAAC;AAC1C,IAAM,mBAAmB,oBAAI,IAAI,CAAC,WAAW,YAAY,CAAC;AAE1D,SAAS,gBACP,QACuC;AACvC,QAAM,QAAQ,OAAO,MAAM,EAAE,YAAY;AACzC,MAAI,iBAAiB,IAAI,KAAK,GAAG;AAC/B,WAAO;AAAA,EACT;AACA,MAAI,gBAAgB,IAAI,KAAK,GAAG;AAC9B,WAAO;AAAA,EACT;AACA,MAAI,iBAAiB,IAAI,KAAK,GAAG;AAC/B,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,MAAM,IAA2B;AACxC,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AACzD;AAEA,eAAsB,kBACpB,SACA,UAA0B,CAAC,GACf;AACZ,QAAM,iBAAiB,QAAQ,kBAAkB,SAAS;AAC1D,QAAM,YAAY,QAAQ,aAAa,SAAS;AAChD,QAAM,QAAQ,KAAK,IAAI;AAEvB,SAAO,MAAM;AACX,UAAM,WAAW,MAAM,QAAQ;AAC/B,UAAM,mBAAmB,gBAAgB,SAAS,MAAM;AAExD,QAAI,qBAAqB,aAAa;AACpC,aAAO;AAAA,IACT;AAEA,QAAI,qBAAqB,UAAU;AACjC,YAAM,IAAI,gBAAgB,SAAS,SAAS,eAAe;AAAA,QACzD,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAEA,QAAI,KAAK,IAAI,IAAI,SAAS,WAAW;AACnC,YAAM,IAAI,iBAAiB,0BAA0B;AAAA,QACnD,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAEA,UAAM,MAAM,cAAc;AAAA,EAC5B;AACF;","names":[]}

@@ -5,3 +5,3 @@ import {

TaskTimeoutError
} from "./chunk-QT7BMRE5.mjs";
} from "./chunk-V4WM5LRA.mjs";

@@ -8,0 +8,0 @@ // src/polling.ts

@@ -6,3 +6,3 @@ {

},
"version": "0.3.4",
"version": "0.3.5",
"description": "RunAPI core SDK for JavaScript, Python, Ruby, Go, Java, and PHP",

@@ -9,0 +9,0 @@ "main": "./dist/index.js",

// src/constants.ts
var TIMEOUTS = {
/**
* Default HTTP request timeout (15 minutes).
* AI generation APIs can take significant time to complete.
*/
HTTP_REQUEST: 9e5,
/**
* Default polling timeout (15 minutes).
* Matches HTTP_REQUEST to allow long-running tasks to complete.
*/
POLLING_MAX_WAIT: 9e5,
/**
* Default polling interval (2 seconds).
* How often to check task status during polling.
*/
POLLING_INTERVAL: 2e3
};
var RETRY_CONFIG = {
/**
* Maximum number of retry attempts.
*/
MAX_RETRIES: 2,
/**
* Base delay between retries (500ms).
* Actual delay uses exponential backoff.
*/
BASE_DELAY: 500,
/**
* Maximum delay between retries (5 seconds).
* Caps the exponential backoff.
*/
MAX_DELAY: 5e3
};
var DEFAULT_BASE_URL = "https://runapi.ai";
var SDK_USER_AGENT = "runapi-sdk-js";
// src/retry.ts
function getRetryDelayMs(attempt, baseDelayMs, maxDelayMs) {
const exponential = baseDelayMs * Math.pow(2, attempt);
const capped = Math.min(exponential, maxDelayMs);
const jitter = Math.random() * capped * 0.5;
return Math.min(maxDelayMs, capped + jitter);
}
function isRetryableStatus(status) {
return status === 429 || status >= 500;
}
function isIdempotentMethod(method) {
return ["GET", "HEAD", "PUT", "DELETE", "OPTIONS"].includes(method);
}
function parseRetryAfterMs(response) {
const retryAfter = response.headers.get("retry-after");
if (!retryAfter) {
return void 0;
}
const numeric = Number(retryAfter);
if (!Number.isNaN(numeric)) {
return numeric * 1e3;
}
const dateMs = Date.parse(retryAfter);
if (!Number.isNaN(dateMs)) {
return Math.max(0, dateMs - Date.now());
}
return void 0;
}
// src/errors.ts
var RunApiError = class extends Error {
/** Explicit machine-readable reason when one was provided. */
code;
/** HTTP status code if available. */
status;
/** Request ID from response headers. */
requestId;
/** Parsed response body or error details. */
details;
constructor(message, options = {}) {
super(message, options);
this.name = "RunApiError";
this.code = options.code;
this.status = options.status;
this.requestId = options.requestId;
this.details = options.details;
}
};
var AuthenticationError = class extends RunApiError {
constructor(message, options = {}) {
super(message, { code: "authentication", ...options });
this.name = "AuthenticationError";
}
};
var RateLimitError = class extends RunApiError {
/** Suggested retry delay in milliseconds from `Retry-After` header. */
retryAfterMs;
constructor(message, options = {}) {
super(message, { code: "rate_limit", ...options });
this.name = "RateLimitError";
this.retryAfterMs = options.retryAfterMs;
}
};
var InsufficientCreditsError = class extends RunApiError {
constructor(message, options = {}) {
super(message, { code: "insufficient_credits", ...options });
this.name = "InsufficientCreditsError";
}
};
var NotFoundError = class extends RunApiError {
constructor(message, options = {}) {
super(message, { code: "not_found", ...options });
this.name = "NotFoundError";
}
};
var ValidationError = class extends RunApiError {
constructor(message, options = {}) {
super(message, { code: "validation", ...options });
this.name = "ValidationError";
}
};
var ConflictError = class extends RunApiError {
constructor(message, options = {}) {
super(message, { code: "conflict", ...options });
this.name = "ConflictError";
}
};
var ServiceUnavailableError = class extends RunApiError {
constructor(message, options = {}) {
super(message, { code: "service_unavailable", ...options });
this.name = "ServiceUnavailableError";
}
};
var NetworkError = class extends RunApiError {
constructor(message, options = {}) {
super(message, { code: "network", ...options });
this.name = "NetworkError";
}
};
var TimeoutError = class extends RunApiError {
constructor(message, options = {}) {
super(message, { code: "timeout", ...options });
this.name = "TimeoutError";
}
};
var TaskTimeoutError = class extends RunApiError {
constructor(message, options = {}) {
super(message, { code: "task_timeout", ...options });
this.name = "TaskTimeoutError";
}
};
var TaskFailedError = class extends RunApiError {
constructor(message, options = {}) {
super(message, { code: "task_failed", ...options });
this.name = "TaskFailedError";
}
};
var DEFAULT_ERROR_MESSAGE = "Request failed";
var HTML_MARKER = /<!doctype|<html/i;
function extractMessageFromUnknown(value) {
if (typeof value === "string" && value.trim()) {
return value.trim();
}
if (value && typeof value === "object") {
const maybeMessage = value.message;
if (typeof maybeMessage === "string" && maybeMessage.trim()) {
return maybeMessage.trim();
}
const maybeDetail = value.detail;
if (typeof maybeDetail === "string" && maybeDetail.trim()) {
return maybeDetail.trim();
}
}
return void 0;
}
function extractErrorMessage(body) {
if (typeof body === "string") {
if (!body.trim()) {
return void 0;
}
if (HTML_MARKER.test(body)) {
return void 0;
}
return body.trim();
}
if (!body || typeof body !== "object") {
return void 0;
}
const maybeError = body.error;
const errorMessage = extractMessageFromUnknown(maybeError);
if (errorMessage) {
return errorMessage;
}
const maybeErrors = body.errors;
if (Array.isArray(maybeErrors) && maybeErrors.length > 0) {
const firstString = maybeErrors.find((item) => typeof item === "string");
if (typeof firstString === "string") {
return firstString;
}
const firstObject = maybeErrors.find(
(item) => item && typeof item === "object"
);
const objectMessage = extractMessageFromUnknown(firstObject);
if (objectMessage) {
return objectMessage;
}
}
const maybeMessage = body.message;
if (typeof maybeMessage === "string" && maybeMessage.trim()) {
return maybeMessage.trim();
}
const maybeDetail = body.detail;
if (typeof maybeDetail === "string" && maybeDetail.trim()) {
return maybeDetail.trim();
}
const maybeErrorMessage = body.errorMessage;
if (typeof maybeErrorMessage === "string" && maybeErrorMessage.trim()) {
return maybeErrorMessage.trim();
}
const maybeMsg = body.msg;
if (typeof maybeMsg === "string" && maybeMsg.trim()) {
return maybeMsg.trim();
}
return void 0;
}
function extractErrorCode(body) {
if (!body || typeof body !== "object") {
return void 0;
}
const error = body.error;
if (!error || typeof error !== "object") {
return void 0;
}
const code = error.code;
return typeof code === "string" && code.trim() ? code : void 0;
}
function defaultMessageForStatus(status) {
switch (status) {
case 400:
return "Bad request";
case 401:
return "Unauthorized";
case 402:
return "Insufficient credits";
case 404:
return "Not found";
case 409:
return "Conflict";
case 408:
return "Request timeout";
case 413:
return "Payload too large";
case 415:
return "Unsupported media type";
case 422:
return "Validation failed";
case 429:
return "Too many requests";
case 503:
return "Service unavailable";
default:
if (status >= 500) {
return "Server error";
}
return DEFAULT_ERROR_MESSAGE;
}
}
function errorFromResponse(response, bodyText, bodyJson) {
const status = response.status;
const requestId = response.headers.get("x-request-id") || void 0;
const messageFromBody = extractErrorMessage(bodyJson) || extractErrorMessage(bodyText);
const message = messageFromBody || defaultMessageForStatus(status);
const details = bodyJson ?? bodyText ?? void 0;
const code = extractErrorCode(bodyJson);
if (status === 401) {
return new AuthenticationError(message, { code, status, requestId, details });
}
if (status === 402) {
return new InsufficientCreditsError(message, { code, status, requestId, details });
}
if (status === 404) {
return new NotFoundError(message, { code, status, requestId, details });
}
if (status === 422 || status === 400) {
return new ValidationError(message, { code, status, requestId, details });
}
if (status === 409) {
return new ConflictError(message, { code, status, requestId, details });
}
if (status === 429) {
return new RateLimitError(message, {
status,
code,
requestId,
details,
retryAfterMs: parseRetryAfterMs(response)
});
}
if (status === 503) {
return new ServiceUnavailableError(message, { code, status, requestId, details });
}
return new RunApiError(message, { code, status, requestId, details });
}
export {
TIMEOUTS,
RETRY_CONFIG,
DEFAULT_BASE_URL,
SDK_USER_AGENT,
getRetryDelayMs,
isRetryableStatus,
isIdempotentMethod,
parseRetryAfterMs,
RunApiError,
AuthenticationError,
RateLimitError,
InsufficientCreditsError,
NotFoundError,
ValidationError,
ServiceUnavailableError,
NetworkError,
TimeoutError,
TaskTimeoutError,
TaskFailedError,
errorFromResponse
};
//# sourceMappingURL=chunk-QT7BMRE5.mjs.map
{"version":3,"sources":["../src/constants.ts","../src/retry.ts","../src/errors.ts"],"sourcesContent":["/**\n * Default timeout constants for SDK operations.\n * All values are in milliseconds.\n */\nexport const TIMEOUTS = {\n /**\n * Default HTTP request timeout (15 minutes).\n * AI generation APIs can take significant time to complete.\n */\n HTTP_REQUEST: 900000,\n\n /**\n * Default polling timeout (15 minutes).\n * Matches HTTP_REQUEST to allow long-running tasks to complete.\n */\n POLLING_MAX_WAIT: 900000,\n\n /**\n * Default polling interval (2 seconds).\n * How often to check task status during polling.\n */\n POLLING_INTERVAL: 2000,\n} as const;\n\n/**\n * Default retry configuration for HTTP requests.\n */\nexport const RETRY_CONFIG = {\n /**\n * Maximum number of retry attempts.\n */\n MAX_RETRIES: 2,\n\n /**\n * Base delay between retries (500ms).\n * Actual delay uses exponential backoff.\n */\n BASE_DELAY: 500,\n\n /**\n * Maximum delay between retries (5 seconds).\n * Caps the exponential backoff.\n */\n MAX_DELAY: 5000,\n} as const;\n\n/**\n * Default base URL for RunAPI services.\n */\nexport const DEFAULT_BASE_URL = 'https://runapi.ai';\n\n/**\n * SDK user agent string.\n */\nexport const SDK_USER_AGENT = 'runapi-sdk-js';\n","export interface RetryOptions {\n maxRetries: number;\n baseDelayMs: number;\n maxDelayMs: number;\n}\n\nexport function getRetryDelayMs(\n attempt: number,\n baseDelayMs: number,\n maxDelayMs: number\n): number {\n const exponential = baseDelayMs * Math.pow(2, attempt);\n const capped = Math.min(exponential, maxDelayMs);\n const jitter = Math.random() * capped * 0.5;\n return Math.min(maxDelayMs, capped + jitter);\n}\n\nexport function isRetryableStatus(status: number): boolean {\n return status === 429 || status >= 500;\n}\n\nexport function isIdempotentMethod(method: string): boolean {\n return ['GET', 'HEAD', 'PUT', 'DELETE', 'OPTIONS'].includes(method);\n}\n\nexport function parseRetryAfterMs(response: Response): number | undefined {\n const retryAfter = response.headers.get('retry-after');\n if (!retryAfter) {\n return undefined;\n }\n\n const numeric = Number(retryAfter);\n if (!Number.isNaN(numeric)) {\n return numeric * 1000;\n }\n\n const dateMs = Date.parse(retryAfter);\n if (!Number.isNaN(dateMs)) {\n return Math.max(0, dateMs - Date.now());\n }\n\n return undefined;\n}\n","import { parseRetryAfterMs } from './retry';\n\n/** Options for constructing RunApiError instances. */\nexport interface RunApiErrorOptions extends ErrorOptions {\n /** Explicit machine-readable reason. */\n code?: string;\n /** HTTP status code. */\n status?: number;\n /** Request ID from `X-Request-ID` header. */\n requestId?: string;\n /** Additional error details from response body. */\n details?: unknown;\n}\n\n/**\n * Base error class for all RunAPI SDK errors.\n * Includes HTTP status, request ID, and response details.\n */\nexport class RunApiError extends Error {\n /** Explicit machine-readable reason when one was provided. */\n code?: string;\n /** HTTP status code if available. */\n status?: number;\n /** Request ID from response headers. */\n requestId?: string;\n /** Parsed response body or error details. */\n details?: unknown;\n\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, options);\n this.name = 'RunApiError';\n this.code = options.code;\n this.status = options.status;\n this.requestId = options.requestId;\n this.details = options.details;\n }\n}\n\n/** Thrown when API key is missing or invalid (HTTP 401). */\nexport class AuthenticationError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'authentication', ...options });\n this.name = 'AuthenticationError';\n }\n}\n\n/** Thrown when rate limit is exceeded (HTTP 429). Includes retry-after delay. */\nexport class RateLimitError extends RunApiError {\n /** Suggested retry delay in milliseconds from `Retry-After` header. */\n retryAfterMs?: number;\n\n constructor(\n message: string,\n options: RunApiErrorOptions & { retryAfterMs?: number } = {}\n ) {\n super(message, { code: 'rate_limit', ...options });\n this.name = 'RateLimitError';\n this.retryAfterMs = options.retryAfterMs;\n }\n}\n\n/** Thrown when account has insufficient credits (HTTP 402). */\nexport class InsufficientCreditsError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'insufficient_credits', ...options });\n this.name = 'InsufficientCreditsError';\n }\n}\n\n/** Thrown when requested resource does not exist (HTTP 404). */\nexport class NotFoundError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'not_found', ...options });\n this.name = 'NotFoundError';\n }\n}\n\n/** Thrown when request validation fails (HTTP 400, 422). */\nexport class ValidationError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'validation', ...options });\n this.name = 'ValidationError';\n }\n}\n\n/** Thrown when a request conflicts with current resource state (HTTP 409). */\nexport class ConflictError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'conflict', ...options });\n this.name = 'ConflictError';\n }\n}\n\n/** Thrown when service is temporarily unavailable (HTTP 503). */\nexport class ServiceUnavailableError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'service_unavailable', ...options });\n this.name = 'ServiceUnavailableError';\n }\n}\n\n/** Thrown when network connection fails or request cannot be sent. */\nexport class NetworkError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'network', ...options });\n this.name = 'NetworkError';\n }\n}\n\n/** Thrown when HTTP request exceeds configured timeout. */\nexport class TimeoutError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'timeout', ...options });\n this.name = 'TimeoutError';\n }\n}\n\n/** Thrown when polling for task completion exceeds maximum wait time. */\nexport class TaskTimeoutError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'task_timeout', ...options });\n this.name = 'TaskTimeoutError';\n }\n}\n\n/** Thrown when async task fails during processing. */\nexport class TaskFailedError extends RunApiError {\n constructor(message: string, options: RunApiErrorOptions = {}) {\n super(message, { code: 'task_failed', ...options });\n this.name = 'TaskFailedError';\n }\n}\n\nconst DEFAULT_ERROR_MESSAGE = 'Request failed';\n\n// Detect HTML error pages from proxies/gateways to avoid leaking raw markup as message.\nconst HTML_MARKER = /<!doctype|<html/i;\n\nfunction extractMessageFromUnknown(value: unknown): string | undefined {\n if (typeof value === 'string' && value.trim()) {\n return value.trim();\n }\n\n if (value && typeof value === 'object') {\n const maybeMessage = (value as { message?: unknown }).message;\n if (typeof maybeMessage === 'string' && maybeMessage.trim()) {\n return maybeMessage.trim();\n }\n const maybeDetail = (value as { detail?: unknown }).detail;\n if (typeof maybeDetail === 'string' && maybeDetail.trim()) {\n return maybeDetail.trim();\n }\n }\n\n return undefined;\n}\n\nfunction extractErrorMessage(body: unknown): string | undefined {\n if (typeof body === 'string') {\n if (!body.trim()) {\n return undefined;\n }\n if (HTML_MARKER.test(body)) {\n return undefined;\n }\n return body.trim();\n }\n\n if (!body || typeof body !== 'object') {\n return undefined;\n }\n\n const maybeError = (body as { error?: unknown }).error;\n const errorMessage = extractMessageFromUnknown(maybeError);\n if (errorMessage) {\n return errorMessage;\n }\n\n const maybeErrors = (body as { errors?: unknown }).errors;\n if (Array.isArray(maybeErrors) && maybeErrors.length > 0) {\n const firstString = maybeErrors.find((item) => typeof item === 'string');\n if (typeof firstString === 'string') {\n return firstString;\n }\n const firstObject = maybeErrors.find(\n (item) => item && typeof item === 'object'\n );\n const objectMessage = extractMessageFromUnknown(firstObject);\n if (objectMessage) {\n return objectMessage;\n }\n }\n\n const maybeMessage = (body as { message?: unknown }).message;\n if (typeof maybeMessage === 'string' && maybeMessage.trim()) {\n return maybeMessage.trim();\n }\n\n const maybeDetail = (body as { detail?: unknown }).detail;\n if (typeof maybeDetail === 'string' && maybeDetail.trim()) {\n return maybeDetail.trim();\n }\n\n const maybeErrorMessage = (body as { errorMessage?: unknown }).errorMessage;\n if (typeof maybeErrorMessage === 'string' && maybeErrorMessage.trim()) {\n return maybeErrorMessage.trim();\n }\n\n const maybeMsg = (body as { msg?: unknown }).msg;\n if (typeof maybeMsg === 'string' && maybeMsg.trim()) {\n return maybeMsg.trim();\n }\n\n return undefined;\n}\n\nfunction extractErrorCode(body: unknown): string | undefined {\n if (!body || typeof body !== 'object') {\n return undefined;\n }\n\n const error = (body as { error?: unknown }).error;\n if (!error || typeof error !== 'object') {\n return undefined;\n }\n\n const code = (error as { code?: unknown }).code;\n return typeof code === 'string' && code.trim() ? code : undefined;\n}\n\nfunction defaultMessageForStatus(status: number): string {\n switch (status) {\n case 400:\n return 'Bad request';\n case 401:\n return 'Unauthorized';\n case 402:\n return 'Insufficient credits';\n case 404:\n return 'Not found';\n case 409:\n return 'Conflict';\n case 408:\n return 'Request timeout';\n case 413:\n return 'Payload too large';\n case 415:\n return 'Unsupported media type';\n case 422:\n return 'Validation failed';\n case 429:\n return 'Too many requests';\n case 503:\n return 'Service unavailable';\n default:\n if (status >= 500) {\n return 'Server error';\n }\n return DEFAULT_ERROR_MESSAGE;\n }\n}\n\n/**\n * Constructs appropriate error class from HTTP response.\n * Maps status codes to specific error types and extracts error messages.\n *\n * @param response - HTTP Response object\n * @param bodyText - Response body as text\n * @param bodyJson - Parsed JSON body if available\n * @returns Specific error instance based on status code\n */\nexport function errorFromResponse(\n response: Response,\n bodyText: string | null,\n bodyJson?: unknown\n): RunApiError {\n const status = response.status;\n const requestId = response.headers.get('x-request-id') || undefined;\n const messageFromBody =\n extractErrorMessage(bodyJson) || extractErrorMessage(bodyText);\n const message = messageFromBody || defaultMessageForStatus(status);\n const details = bodyJson ?? bodyText ?? undefined;\n const code = extractErrorCode(bodyJson);\n\n if (status === 401) {\n return new AuthenticationError(message, { code, status, requestId, details });\n }\n if (status === 402) {\n return new InsufficientCreditsError(message, { code, status, requestId, details });\n }\n if (status === 404) {\n return new NotFoundError(message, { code, status, requestId, details });\n }\n if (status === 422 || status === 400) {\n return new ValidationError(message, { code, status, requestId, details });\n }\n if (status === 409) {\n return new ConflictError(message, { code, status, requestId, details });\n }\n if (status === 429) {\n return new RateLimitError(message, {\n status,\n code,\n requestId,\n details,\n retryAfterMs: parseRetryAfterMs(response),\n });\n }\n if (status === 503) {\n return new ServiceUnavailableError(message, { code, status, requestId, details });\n }\n\n return new RunApiError(message, { code, status, requestId, details });\n}\n"],"mappings":"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","names":[]}

Sorry, the diff of this file is too big to display