@cesto/sdk 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -78,7 +78,6 @@ async function main() {
78
78
  // Read the key from your environment — never hard-code a secret key.
79
79
  const cesto = new Cesto({
80
80
  apiKey: process.env.CESTO_API_KEY!,
81
- environment: 'PRODUCTION', // 'PRODUCTION' | 'BETA'
82
81
  timeout: 30_000,
83
82
  maxRetries: 2,
84
83
  });
@@ -132,23 +131,14 @@ main().catch((err) => {
132
131
  ```ts
133
132
  new Cesto({
134
133
  apiKey: 'cesto_sk_…', // required
135
- environment: 'PRODUCTION', // 'PRODUCTION' | 'BETA', default 'PRODUCTION'
136
134
  timeout: 60_000, // ms, default 60s
137
135
  maxRetries: 2, // default 2
138
136
  fetch: customFetch, // optional fetch override
139
137
  });
140
138
  ```
141
139
 
142
- The backend URL is **not a free-form option**. `NODE_ENV` decides local-vs-deployed,
143
- and `environment` selects which deployed backend:
144
-
145
- | NODE_ENV | environment | URL |
146
- |---|---|---|
147
- | `production` | `PRODUCTION` (default) | `https://backend.cesto.co` |
148
- | `production` | `BETA` | `https://dev.backend.cesto.co` |
149
-
150
- Keys are environment-specific (each backend has its own) — use the `PRODUCTION` key with
151
- `PRODUCTION`, the `BETA` key with `BETA`.
140
+ The SDK always targets the production backend at `https://backend.cesto.co`. The base URL
141
+ is **not a configurable option**.
152
142
 
153
143
  Per-request overrides (second/third argument on every method):
154
144
 
package/dist/index.cjs CHANGED
@@ -98,15 +98,11 @@ function makeAPIError(status, envelope, headers, retryAfter) {
98
98
 
99
99
  // src/core/options.ts
100
100
  var PROD_BASE_URL = "https://backend.cesto.co";
101
- var BETA_BASE_URL = "https://dev.backend.cesto.co";
102
101
  var DEFAULT_TIMEOUT_MS = 6e4;
103
102
  var DEFAULT_MAX_RETRIES = 2;
104
103
  function isBrowser() {
105
104
  return typeof window !== "undefined" && typeof window.document !== "undefined";
106
105
  }
107
- function resolveBaseURL(environment) {
108
- return environment === "BETA" ? BETA_BASE_URL : PROD_BASE_URL;
109
- }
110
106
  function resolveOptions(options) {
111
107
  if (isBrowser()) {
112
108
  throw new CestoError(
@@ -131,13 +127,9 @@ function resolveOptions(options) {
131
127
  if (!Number.isInteger(maxRetries) || maxRetries < 0) {
132
128
  throw new CestoError("`maxRetries` must be an integer >= 0.");
133
129
  }
134
- const environment = options.environment ?? "PRODUCTION";
135
- if (environment !== "PRODUCTION" && environment !== "BETA") {
136
- throw new CestoError(`Invalid environment: ${environment}. Use 'PRODUCTION' or 'BETA'.`);
137
- }
138
130
  return {
139
131
  apiKey,
140
- baseURL: resolveBaseURL(environment),
132
+ baseURL: PROD_BASE_URL,
141
133
  timeout,
142
134
  maxRetries,
143
135
  fetch: options.fetch ?? fetchImpl.bind(globalThis)
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/errors.ts","../src/core/options.ts","../src/core/version.ts","../src/core/request.ts","../src/resources/resource.ts","../src/resources/positions.ts","../src/resources/products.ts","../src/client.ts","../src/types/products.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Error hierarchy thrown by the SDK.\n *\n * Everything extends {@link CestoError}. Server (non-2xx) responses become an\n * {@link APIError} subclass built from the API's `{ code, message, details,\n * requestId }` envelope; transport problems become {@link APIConnectionError}\n * (or its timeout subclass); caller cancellation becomes {@link APIUserAbortError}.\n */\n\n/** Base class for every error the SDK throws. */\nexport class CestoError extends Error {\n constructor(message: string) {\n super(message);\n this.name = new.target.name;\n // Restore the prototype chain for `instanceof` across the transpile target.\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Parsed `{ code, message, details, requestId }` envelope from the API. */\nexport interface APIErrorEnvelope {\n code?: string;\n message?: string;\n details?: unknown;\n requestId?: string;\n}\n\n/** A non-2xx HTTP response. */\nexport class APIError extends CestoError {\n /** HTTP status code. */\n readonly status: number;\n /** Machine-readable error code from the API envelope (e.g. `RESOURCE_NOT_FOUND`). */\n readonly code?: string;\n /** Correlation id from the API envelope, useful when reporting issues. */\n readonly requestId?: string;\n /** Structured error details from the API envelope. */\n readonly details?: unknown;\n /** Response headers. */\n readonly headers?: Headers;\n\n constructor(\n status: number,\n message: string,\n opts: { code?: string; requestId?: string; details?: unknown; headers?: Headers } = {},\n ) {\n super(message);\n this.status = status;\n this.code = opts.code;\n this.requestId = opts.requestId;\n this.details = opts.details;\n this.headers = opts.headers;\n }\n}\n\nexport class BadRequestError extends APIError {}\nexport class AuthenticationError extends APIError {}\nexport class PermissionDeniedError extends APIError {}\nexport class NotFoundError extends APIError {}\nexport class ConflictError extends APIError {}\nexport class UnprocessableEntityError extends APIError {}\n\n/** HTTP 429. Carries `retryAfter` (ms) when the server sent a `Retry-After` header. */\nexport class RateLimitError extends APIError {\n /** Milliseconds to wait before retrying, derived from `Retry-After`. */\n readonly retryAfter?: number;\n\n constructor(\n status: number,\n message: string,\n opts: {\n code?: string;\n requestId?: string;\n details?: unknown;\n headers?: Headers;\n retryAfter?: number;\n } = {},\n ) {\n super(status, message, opts);\n this.retryAfter = opts.retryAfter;\n }\n}\n\nexport class InternalServerError extends APIError {}\n\n/** A network-level failure (DNS, connection reset, fetch threw). */\nexport class APIConnectionError extends CestoError {\n readonly cause?: unknown;\n constructor(message = 'Connection error', opts: { cause?: unknown } = {}) {\n super(message);\n this.cause = opts.cause;\n }\n}\n\n/** The request exceeded the configured timeout. */\nexport class APIConnectionTimeoutError extends APIConnectionError {\n constructor(message = 'Request timed out') {\n super(message);\n }\n}\n\n/** The caller's `AbortSignal` fired. */\nexport class APIUserAbortError extends CestoError {\n constructor(message = 'Request was aborted') {\n super(message);\n }\n}\n\n/** Build the right {@link APIError} subclass from a parsed error response. */\nexport function makeAPIError(\n status: number,\n envelope: APIErrorEnvelope,\n headers: Headers,\n retryAfter?: number,\n): APIError {\n const message = envelope.message || `HTTP ${status}`;\n const opts = {\n code: envelope.code,\n requestId: envelope.requestId,\n details: envelope.details,\n headers,\n };\n\n switch (status) {\n case 400:\n return new BadRequestError(status, message, opts);\n case 401:\n return new AuthenticationError(status, message, opts);\n case 403:\n return new PermissionDeniedError(status, message, opts);\n case 404:\n return new NotFoundError(status, message, opts);\n case 409:\n return new ConflictError(status, message, opts);\n case 422:\n return new UnprocessableEntityError(status, message, opts);\n case 429:\n return new RateLimitError(status, message, { ...opts, retryAfter });\n default:\n if (status >= 500) return new InternalServerError(status, message, opts);\n return new APIError(status, message, opts);\n }\n}\n","import { CestoError } from './errors.js';\n\nconst PROD_BASE_URL = 'https://backend.cesto.co';\nconst BETA_BASE_URL = 'https://dev.backend.cesto.co';\nconst DEFAULT_TIMEOUT_MS = 60_000;\nconst DEFAULT_MAX_RETRIES = 2;\n\n/** Which deployed Cesto backend to target. */\nexport type CestoEnvironment = 'PRODUCTION' | 'BETA';\n\n/** Options for constructing a {@link Cesto} client. */\nexport interface ClientOptions {\n /**\n * Secret API key (`cesto_sk_…`). Required — the constructor throws if omitted.\n * Read it from your environment yourself, e.g. `apiKey: process.env.CESTO_API_KEY`.\n */\n apiKey?: string;\n /**\n * Which backend to target in a deployed build (`NODE_ENV=production`):\n * `PRODUCTION` → backend.cesto.co, `BETA` → dev.backend.cesto.co. Default `PRODUCTION`.\n */\n environment?: CestoEnvironment;\n /** Per-request timeout in milliseconds. Default `60000`. */\n timeout?: number;\n /** Max automatic retries on transient failures. Default `2`. */\n maxRetries?: number;\n /** Custom fetch implementation (e.g. undici, a test mock). Default `globalThis.fetch`. */\n fetch?: typeof fetch;\n}\n\n/** Per-request overrides accepted by every resource method. */\nexport interface RequestOptions {\n /** Override the client timeout (ms) for this request. */\n timeout?: number;\n /** Override the client retry count for this request (e.g. `0` to disable). */\n maxRetries?: number;\n /** Caller cancellation; composed with the internal timeout signal. */\n signal?: AbortSignal;\n}\n\n/** Fully-resolved, validated client configuration. */\nexport interface ResolvedOptions {\n apiKey: string;\n /** Normalized base URL, no trailing slash. */\n baseURL: string;\n timeout: number;\n maxRetries: number;\n fetch: typeof fetch;\n}\n\nfunction isBrowser(): boolean {\n return typeof window !== 'undefined' && typeof window.document !== 'undefined';\n}\n\n/** Resolve the backend URL as per `environment`. */\nfunction resolveBaseURL(environment: CestoEnvironment): string {\n return environment === 'BETA' ? BETA_BASE_URL : PROD_BASE_URL;\n}\n\n/** Validate and normalize {@link ClientOptions} into {@link ResolvedOptions}. */\nexport function resolveOptions(options: ClientOptions): ResolvedOptions {\n if (isBrowser()) {\n throw new CestoError(\n 'The Cesto SDK is server-side only. It must not run in a browser — a secret key ' +\n '(cesto_sk_…) would be exposed to end users.',\n );\n }\n\n const apiKey = options.apiKey\n if (!apiKey) {\n throw new CestoError('Missing API key. Pass { apiKey } when constructing the client.');\n }\n\n const fetchImpl = options.fetch ?? globalThis.fetch;\n if (typeof fetchImpl !== 'function') {\n throw new CestoError(\n 'No fetch implementation found. Use Node 18+ or pass a custom { fetch } in ClientOptions.',\n );\n }\n\n const timeout = options.timeout ?? DEFAULT_TIMEOUT_MS;\n if (!Number.isFinite(timeout) || timeout < 0) {\n throw new CestoError('`timeout` must be a finite number >= 0.');\n }\n\n const maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES;\n if (!Number.isInteger(maxRetries) || maxRetries < 0) {\n throw new CestoError('`maxRetries` must be an integer >= 0.');\n }\n\n const environment = options.environment ?? 'PRODUCTION';\n if (environment !== 'PRODUCTION' && environment !== 'BETA') {\n throw new CestoError(`Invalid environment: ${environment}. Use 'PRODUCTION' or 'BETA'.`);\n }\n\n return {\n apiKey,\n baseURL: resolveBaseURL(environment),\n timeout,\n maxRetries,\n fetch: options.fetch ?? fetchImpl.bind(globalThis),\n };\n}\n","/** SDK version. Keep in sync with package.json `version`. */\nexport const VERSION = '0.0.1';\n","import {\n APIConnectionError,\n APIConnectionTimeoutError,\n type APIError,\n type APIErrorEnvelope,\n APIUserAbortError,\n CestoError,\n makeAPIError,\n} from './errors.js';\nimport type { RequestOptions, ResolvedOptions } from './options.js';\nimport { VERSION } from './version.js';\n\n/** Query parameters; `undefined`/`null` values are skipped. */\nexport type QueryParams = Record<string, string | number | boolean | undefined | null>;\n\ninterface GetOptions extends RequestOptions {\n query?: QueryParams;\n}\n\nconst RETRY_BASE_MS = 500;\nconst RETRY_CAP_MS = 8_000;\n\n/** Internal transport: builds requests, applies auth, retries, and parses JSON. */\nexport class APIClientCore {\n constructor(private readonly opts: ResolvedOptions) {}\n\n get<T>(path: string, options: GetOptions = {}): Promise<T> {\n return this.request<T>('GET', path, options);\n }\n\n private async request<T>(method: string, path: string, options: GetOptions): Promise<T> {\n const url = this.buildURL(path, options.query);\n const timeout = options.timeout ?? this.opts.timeout;\n const maxRetries = options.maxRetries ?? this.opts.maxRetries;\n\n let attempt = 0;\n // Loop: returns on success/non-retryable error, retries transient failures.\n for (;;) {\n const timer = withTimeout(options.signal, timeout);\n let response: Response;\n\n try {\n response = await this.opts.fetch(url, {\n method,\n headers: buildHeaders(this.opts.apiKey, attempt),\n signal: timer.signal,\n });\n } catch (err) {\n timer.cleanup();\n const mapped = mapFetchError(err, timer, options.signal);\n // Never retry a user abort.\n if (mapped instanceof APIUserAbortError) throw mapped;\n if (attempt < maxRetries) {\n attempt += 1;\n await sleep(backoff(attempt));\n continue;\n }\n throw mapped;\n }\n\n timer.cleanup();\n\n if (response.ok) {\n return parseJSON<T>(response);\n }\n\n if (shouldRetryStatus(response.status) && attempt < maxRetries) {\n attempt += 1;\n await sleep(parseRetryAfter(response.headers) ?? backoff(attempt));\n continue;\n }\n\n throw await errorFromResponse(response);\n }\n }\n\n private buildURL(path: string, query?: QueryParams): string {\n const url = new URL(`${this.opts.baseURL}${path}`);\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined && value !== null) url.searchParams.set(key, String(value));\n }\n }\n return url.toString();\n }\n}\n\nfunction buildHeaders(apiKey: string, attempt: number): Record<string, string> {\n const headers: Record<string, string> = {\n 'X-API-Key': apiKey,\n Accept: 'application/json',\n };\n const ua = userAgent();\n if (ua) headers['User-Agent'] = ua;\n if (attempt > 0) headers['x-cesto-retry-count'] = String(attempt);\n return headers;\n}\n\nfunction userAgent(): string {\n if (typeof process !== 'undefined' && process.versions?.node) {\n return `cesto-sdk/${VERSION} (node/${process.versions.node})`;\n }\n return `cesto-sdk/${VERSION}`;\n}\n\n/** AbortController that fires on either the caller's signal or the timeout. */\nfunction withTimeout(userSignal: AbortSignal | undefined, timeoutMs: number) {\n const controller = new AbortController();\n let timedOut = false;\n\n const timer = setTimeout(() => {\n timedOut = true;\n controller.abort(new Error('timeout'));\n }, timeoutMs);\n\n const onUserAbort = () => controller.abort(userSignal?.reason);\n if (userSignal) {\n if (userSignal.aborted) controller.abort(userSignal.reason);\n else userSignal.addEventListener('abort', onUserAbort, { once: true });\n }\n\n return {\n signal: controller.signal,\n didTimeout: () => timedOut,\n cleanup: () => {\n clearTimeout(timer);\n userSignal?.removeEventListener('abort', onUserAbort);\n },\n };\n}\n\nfunction mapFetchError(\n err: unknown,\n timer: { didTimeout: () => boolean },\n userSignal: AbortSignal | undefined,\n): CestoError {\n if (userSignal?.aborted) return new APIUserAbortError();\n if (timer.didTimeout()) return new APIConnectionTimeoutError();\n return new APIConnectionError('Connection error', { cause: err });\n}\n\nfunction shouldRetryStatus(status: number): boolean {\n return status === 408 || status === 409 || status === 429 || status >= 500;\n}\n\nasync function parseJSON<T>(response: Response): Promise<T> {\n const text = await response.text();\n if (!text) return undefined as T;\n try {\n return JSON.parse(text) as T;\n } catch {\n throw new CestoError('Failed to parse response body as JSON.');\n }\n}\n\nasync function errorFromResponse(response: Response): Promise<APIError> {\n let envelope: APIErrorEnvelope = {};\n try {\n const text = await response.text();\n if (text) {\n const parsed = JSON.parse(text) as unknown;\n if (parsed && typeof parsed === 'object') envelope = parsed as APIErrorEnvelope;\n }\n } catch {\n // Non-JSON error body — fall back to status-only error.\n }\n return makeAPIError(\n response.status,\n envelope,\n response.headers,\n parseRetryAfter(response.headers),\n );\n}\n\n/** Parse a `Retry-After` header (delta-seconds or HTTP-date) into milliseconds. */\nfunction parseRetryAfter(headers: Headers): number | undefined {\n const value = headers.get('retry-after');\n if (!value) return undefined;\n const seconds = Number(value);\n if (!Number.isNaN(seconds)) return Math.max(0, seconds * 1000);\n const dateMs = Date.parse(value);\n if (!Number.isNaN(dateMs)) return Math.max(0, dateMs - Date.now());\n return undefined;\n}\n\n/** Exponential backoff with full jitter, capped. */\nfunction backoff(attempt: number): number {\n const ceiling = Math.min(RETRY_CAP_MS, RETRY_BASE_MS * 2 ** (attempt - 1));\n return Math.random() * ceiling;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import type { APIClientCore } from '../core/request.js';\n\n/** Base class for resource groups; holds a reference to the transport. */\nexport abstract class APIResource {\n constructor(protected readonly client: APIClientCore) {}\n}\n","import { CestoError } from '../core/errors.js';\nimport type { RequestOptions } from '../core/options.js';\nimport type { PositionsResult } from '../types/positions.js';\nimport { APIResource } from './resource.js';\n\nexport interface PositionsListParams {\n /** External Solana wallet address (Phantom/Solflare). Required. */\n wallet: string;\n}\n\nexport class Positions extends APIResource {\n /**\n * List a user's open/closing positions, resolved from their external Solana\n * wallet. A wallet with no Cesto account returns an empty result (not an error).\n */\n list(params: PositionsListParams, options?: RequestOptions): Promise<PositionsResult> {\n if (!params?.wallet) throw new CestoError('wallet is required');\n return this.client.get<PositionsResult>('/positions/by-wallet', {\n query: { wallet: params.wallet },\n ...options,\n });\n }\n}\n","import type { RequestOptions } from '../core/options.js';\nimport type {\n ProductBacktest,\n ProductBacktestChart,\n ProductListItem,\n ProductVersionResponse,\n ProductWithBacktest,\n ProductWithBacktestChart,\n} from '../types/products.js';\nimport type { ChartTimeRange } from '../types/shared.js';\nimport { APIResource } from './resource.js';\n\nexport interface ProductListParams {\n /** Filter by category. */\n category?: string;\n /**\n * Also fetch backtested performance (`GET /products/analytics`) and merge it\n * onto each product as `backtest`. Fails gracefully → `backtest: null`.\n */\n includeBacktest?: boolean;\n}\n\nexport interface ProductGetParams {\n /**\n * Also fetch the product's backtested value chart and attach it as `backtestChart`.\n * Fails gracefully → `backtestChart: null`.\n */\n includeBacktestChart?: boolean;\n /** Chart window when `includeBacktestChart` is true. Default `'1y'`. */\n chartTimeRange?: ChartTimeRange;\n}\n\nconst DEFAULT_CHART_TIME_RANGE: ChartTimeRange = '1y';\n\nexport class Products extends APIResource {\n /** List products. */\n list(): Promise<ProductListItem[]>;\n list(\n params: ProductListParams & { includeBacktest?: false },\n options?: RequestOptions,\n ): Promise<ProductListItem[]>;\n list(\n params: ProductListParams & { includeBacktest: true },\n options?: RequestOptions,\n ): Promise<ProductWithBacktest[]>;\n async list(\n params: ProductListParams = {},\n options?: RequestOptions,\n ): Promise<ProductListItem[] | ProductWithBacktest[]> {\n const query = params.category ? { category: params.category } : undefined;\n\n if (!params.includeBacktest) {\n return this.client.get<ProductListItem[]>('/products', { query, ...options });\n }\n\n const [items, backtests] = await Promise.all([\n this.client.get<ProductListItem[]>('/products', { query, ...options }),\n this.client\n .get<Record<string, ProductBacktest>>('/products/analytics', { query, ...options })\n // Graceful: a failed/slow analytics fetch never breaks the list.\n .catch(() => ({}) as Record<string, ProductBacktest>),\n ]);\n\n return items.map((item) => ({ ...item, backtest: backtests[item.id] ?? null }));\n }\n\n /** Get a product by slug. */\n get(slug: string): Promise<ProductVersionResponse>;\n get(\n slug: string,\n params: ProductGetParams & { includeBacktestChart?: false },\n options?: RequestOptions,\n ): Promise<ProductVersionResponse>;\n get(\n slug: string,\n params: ProductGetParams & { includeBacktestChart: true },\n options?: RequestOptions,\n ): Promise<ProductWithBacktestChart>;\n async get(\n slug: string,\n params: ProductGetParams = {},\n options?: RequestOptions,\n ): Promise<ProductVersionResponse | ProductWithBacktestChart> {\n const product = await this.client.get<ProductVersionResponse>(\n `/products/${encodeURIComponent(slug)}`,\n options,\n );\n\n if (!params.includeBacktestChart) return product;\n\n // Sequential: the chart is keyed by productId, which we only have after the\n // detail fetch resolves the slug. Graceful: a chart failure → null.\n const backtestChart = await this.client\n .get<ProductBacktestChart>(`/products/${encodeURIComponent(product.id)}/graph`, {\n query: { timeRange: params.chartTimeRange ?? DEFAULT_CHART_TIME_RANGE },\n ...options,\n })\n .catch(() => null);\n\n return { ...product, backtestChart };\n }\n}\n","import {\n APIConnectionError,\n APIConnectionTimeoutError,\n APIError,\n APIUserAbortError,\n AuthenticationError,\n BadRequestError,\n CestoError,\n ConflictError,\n InternalServerError,\n NotFoundError,\n PermissionDeniedError,\n RateLimitError,\n UnprocessableEntityError,\n} from './core/errors.js';\nimport { type ClientOptions, resolveOptions } from './core/options.js';\nimport { APIClientCore } from './core/request.js';\nimport { Positions } from './resources/positions.js';\nimport { Products } from './resources/products.js';\n\n/**\n * The Cesto SDK client.\n *\n * @example\n * ```ts\n * const cesto = new Cesto({ apiKey: process.env.CESTO_API_KEY! });\n * const products = await cesto.products.list({ includeBacktest: true });\n * ```\n */\nexport class Cesto {\n readonly products: Products;\n readonly positions: Positions;\n private readonly core: APIClientCore;\n\n constructor(options: ClientOptions = {}) {\n this.core = new APIClientCore(resolveOptions(options));\n this.products = new Products(this.core);\n this.positions = new Positions(this.core);\n }\n\n // Error classes re-exposed for ergonomic `instanceof` checks:\n // catch (e) { if (e instanceof Cesto.NotFoundError) … }\n static readonly CestoError = CestoError;\n static readonly APIError = APIError;\n static readonly BadRequestError = BadRequestError;\n static readonly AuthenticationError = AuthenticationError;\n static readonly PermissionDeniedError = PermissionDeniedError;\n static readonly NotFoundError = NotFoundError;\n static readonly ConflictError = ConflictError;\n static readonly UnprocessableEntityError = UnprocessableEntityError;\n static readonly RateLimitError = RateLimitError;\n static readonly InternalServerError = InternalServerError;\n static readonly APIConnectionError = APIConnectionError;\n static readonly APIConnectionTimeoutError = APIConnectionTimeoutError;\n static readonly APIUserAbortError = APIUserAbortError;\n}\n","import type {\n ChartTimeRange,\n GeoStatus,\n IncentiveOverlayCampaign,\n PredictionMarketState,\n TokenPerformance,\n} from './shared.js';\n\n/** An item in `products.list()` — `GET /products`. */\nexport interface ProductListItem {\n id: string;\n slug: string;\n name: string;\n description: string | null;\n logoUrl: string | null;\n category: string | null;\n tags: string[];\n isActive: boolean;\n isPublished: boolean;\n pointMultiplier: number;\n metadata: Record<string, unknown> | null;\n geoStatus: GeoStatus;\n /** Active incentive campaigns; `[]` when none. */\n incentives: IncentiveOverlayCampaign[];\n}\n\n/** Backtested performance for a product — `GET /products/analytics` (per product). */\nexport interface ProductBacktest {\n protocolsInvolved: string[];\n tokensInvolved: string[];\n tokenPerformance: TokenPerformance | null;\n tokenPerformance7d: TokenPerformance | null;\n tokenPerformance30d: TokenPerformance | null;\n priceChange24h: number | null;\n tokenPriceChanges: Record<\n string,\n { priceChange24h: number | null; priceChange24hPercent: number | null }\n >;\n}\n\n/** `products.list({ includeBacktest: true })` — list item with backtest merged in. */\nexport type ProductWithBacktest = ProductListItem & {\n backtest: ProductBacktest | null;\n};\n\nexport interface ProductCreator {\n id: string;\n username: string | null;\n email: string | null;\n solanaWalletAddress: string | null;\n embeddedWalletAddress: string | null;\n}\n\nexport interface OndoTradingStatus {\n allTradable: boolean;\n currentSession: string;\n hasOndoTokens: boolean;\n tokens: unknown[];\n untradableTokens: unknown[];\n nextFullyTradableAt: string | null;\n nextFullyTradableSession: string | null;\n}\n\n/** Full product detail — `GET /products/:slug`. */\nexport interface ProductVersionResponse {\n id: string;\n versionId: string;\n version: number;\n changelog: string | null;\n minimumInvestment: string;\n inputTokenMint: string;\n inputTokenDecimals: number;\n about: string | null;\n riskNotes: string | null;\n resources: string | null;\n name: string;\n slug: string;\n description: string | null;\n logoUrl: string | null;\n category: string | null;\n tags: string[];\n isActive: boolean;\n isPublished: boolean;\n metadata: Record<string, unknown> | null;\n pointMultiplier: number;\n createdBy: string;\n creator: ProductCreator | null;\n tokensInvolved: string[];\n protocolsInvolved: string[];\n tokenPerformance: TokenPerformance | null;\n tokenPerformance7d: TokenPerformance | null;\n tokenPerformance30d: TokenPerformance | null;\n predictionMarkets?: PredictionMarketState[];\n canInvest: boolean;\n /** Raw workflow definition. */\n definition: unknown;\n geoStatus: GeoStatus;\n ondoTradingStatus: OndoTradingStatus;\n incentives?: IncentiveOverlayCampaign[];\n}\n\nexport interface BacktestChartTimeSeriesPoint {\n timestamp: string;\n portfolioValue: number;\n sp500Value?: number;\n mag7Value?: number;\n btcValue?: number;\n solValue?: number;\n usdcValue?: number;\n isLiquidated?: boolean;\n liquidationThreshold?: number;\n}\n\nexport interface BacktestChartMetrics {\n totalReturn: number;\n cagr: number;\n volatility: number;\n maxDrawdown: number;\n sharpe: number;\n}\n\nexport interface PredictionMarketEvent {\n ticker: string;\n marketTicker: string;\n seriesTicker: string;\n title: string;\n closeTime: number;\n currentProbability?: number;\n currentPrice: number;\n daysToClose: number;\n timeSeries: Array<{\n market_ticker: string;\n event_ticker: string;\n raw_numerical_forecast: number;\n numerical_forecast: number;\n formatted_forecast: string;\n end_period_ts: number;\n period_interval: number;\n }>;\n}\n\n/** Token-portfolio backtest chart — `GET /products/:id/graph` (non-prediction). */\nexport interface BacktestChart {\n workflowId: string;\n name: string;\n timeRange?: ChartTimeRange;\n timeSeries: BacktestChartTimeSeriesPoint[];\n /** Computed only when `timeRange === '1y'`; null otherwise. */\n metrics: BacktestChartMetrics | null;\n assetPerformance: Array<{ token: string; mint: string; returnPct: number }>;\n contributions: Array<{ token: string; mint: string; contribution: number }>;\n assetSparklines: Array<{\n token: string;\n mint: string;\n points: Array<{ timestamp: string; value: number; price: number }>;\n }>;\n checkpoints?: Array<{\n timestamp: string;\n version: number;\n fromVersion: number | null;\n changelog: string | null;\n added: Array<{ token: string; mint: string; allocation: number }>;\n removed: Array<{ token: string; mint: string; allocation: number }>;\n reweighted: Array<{ token: string; mint: string; fromPct: number; toPct: number }>;\n }>;\n liquidationInfo?: {\n hasLiquidations: boolean;\n liquidationEvents: Array<{\n timestamp: string;\n asset: string;\n liquidationPrice: number;\n actualPrice: number;\n }>;\n liquidationThresholds: Array<{\n asset: string;\n mint: string;\n liquidationPrice: number;\n entryPrice: number;\n leverage: number;\n direction: 'LONG' | 'SHORT';\n }>;\n };\n hasPredictionMarkets?: boolean;\n predictionMarketEvents?: PredictionMarketEvent[];\n incentives?: IncentiveOverlayCampaign[];\n}\n\n/** Prediction-market backtest chart — `GET /products/:id/graph` (prediction). */\nexport interface PredictionMarketChart {\n workflowId: string;\n name: string;\n predictionMarket: boolean;\n markets: PredictionMarketEvent[];\n incentives?: IncentiveOverlayCampaign[];\n}\n\n/** Union returned by the graph endpoint. Discriminate with {@link isPredictionMarketChart}. */\nexport type ProductBacktestChart = BacktestChart | PredictionMarketChart;\n\n/** `products.get(slug, { includeBacktestChart: true })` — detail with chart merged in. */\nexport type ProductWithBacktestChart = ProductVersionResponse & {\n backtestChart: ProductBacktestChart | null;\n};\n\n/** Type guard: is this chart the prediction-market variant? */\nexport function isPredictionMarketChart(\n chart: ProductBacktestChart,\n): chart is PredictionMarketChart {\n return (chart as PredictionMarketChart).predictionMarket === true;\n}\n"]}
1
+ {"version":3,"sources":["../src/core/errors.ts","../src/core/options.ts","../src/core/version.ts","../src/core/request.ts","../src/resources/resource.ts","../src/resources/positions.ts","../src/resources/products.ts","../src/client.ts","../src/types/products.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Error hierarchy thrown by the SDK.\n *\n * Everything extends {@link CestoError}. Server (non-2xx) responses become an\n * {@link APIError} subclass built from the API's `{ code, message, details,\n * requestId }` envelope; transport problems become {@link APIConnectionError}\n * (or its timeout subclass); caller cancellation becomes {@link APIUserAbortError}.\n */\n\n/** Base class for every error the SDK throws. */\nexport class CestoError extends Error {\n constructor(message: string) {\n super(message);\n this.name = new.target.name;\n // Restore the prototype chain for `instanceof` across the transpile target.\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Parsed `{ code, message, details, requestId }` envelope from the API. */\nexport interface APIErrorEnvelope {\n code?: string;\n message?: string;\n details?: unknown;\n requestId?: string;\n}\n\n/** A non-2xx HTTP response. */\nexport class APIError extends CestoError {\n /** HTTP status code. */\n readonly status: number;\n /** Machine-readable error code from the API envelope (e.g. `RESOURCE_NOT_FOUND`). */\n readonly code?: string;\n /** Correlation id from the API envelope, useful when reporting issues. */\n readonly requestId?: string;\n /** Structured error details from the API envelope. */\n readonly details?: unknown;\n /** Response headers. */\n readonly headers?: Headers;\n\n constructor(\n status: number,\n message: string,\n opts: { code?: string; requestId?: string; details?: unknown; headers?: Headers } = {},\n ) {\n super(message);\n this.status = status;\n this.code = opts.code;\n this.requestId = opts.requestId;\n this.details = opts.details;\n this.headers = opts.headers;\n }\n}\n\nexport class BadRequestError extends APIError {}\nexport class AuthenticationError extends APIError {}\nexport class PermissionDeniedError extends APIError {}\nexport class NotFoundError extends APIError {}\nexport class ConflictError extends APIError {}\nexport class UnprocessableEntityError extends APIError {}\n\n/** HTTP 429. Carries `retryAfter` (ms) when the server sent a `Retry-After` header. */\nexport class RateLimitError extends APIError {\n /** Milliseconds to wait before retrying, derived from `Retry-After`. */\n readonly retryAfter?: number;\n\n constructor(\n status: number,\n message: string,\n opts: {\n code?: string;\n requestId?: string;\n details?: unknown;\n headers?: Headers;\n retryAfter?: number;\n } = {},\n ) {\n super(status, message, opts);\n this.retryAfter = opts.retryAfter;\n }\n}\n\nexport class InternalServerError extends APIError {}\n\n/** A network-level failure (DNS, connection reset, fetch threw). */\nexport class APIConnectionError extends CestoError {\n readonly cause?: unknown;\n constructor(message = 'Connection error', opts: { cause?: unknown } = {}) {\n super(message);\n this.cause = opts.cause;\n }\n}\n\n/** The request exceeded the configured timeout. */\nexport class APIConnectionTimeoutError extends APIConnectionError {\n constructor(message = 'Request timed out') {\n super(message);\n }\n}\n\n/** The caller's `AbortSignal` fired. */\nexport class APIUserAbortError extends CestoError {\n constructor(message = 'Request was aborted') {\n super(message);\n }\n}\n\n/** Build the right {@link APIError} subclass from a parsed error response. */\nexport function makeAPIError(\n status: number,\n envelope: APIErrorEnvelope,\n headers: Headers,\n retryAfter?: number,\n): APIError {\n const message = envelope.message || `HTTP ${status}`;\n const opts = {\n code: envelope.code,\n requestId: envelope.requestId,\n details: envelope.details,\n headers,\n };\n\n switch (status) {\n case 400:\n return new BadRequestError(status, message, opts);\n case 401:\n return new AuthenticationError(status, message, opts);\n case 403:\n return new PermissionDeniedError(status, message, opts);\n case 404:\n return new NotFoundError(status, message, opts);\n case 409:\n return new ConflictError(status, message, opts);\n case 422:\n return new UnprocessableEntityError(status, message, opts);\n case 429:\n return new RateLimitError(status, message, { ...opts, retryAfter });\n default:\n if (status >= 500) return new InternalServerError(status, message, opts);\n return new APIError(status, message, opts);\n }\n}\n","import { CestoError } from './errors.js';\n\nconst PROD_BASE_URL = 'https://backend.cesto.co';\nconst DEFAULT_TIMEOUT_MS = 60_000;\nconst DEFAULT_MAX_RETRIES = 2;\n\n/** Options for constructing a {@link Cesto} client. */\nexport interface ClientOptions {\n /**\n * Secret API key (`cesto_sk_…`). Required — the constructor throws if omitted.\n * Read it from your environment yourself, e.g. `apiKey: process.env.CESTO_API_KEY`.\n */\n apiKey?: string;\n /** Per-request timeout in milliseconds. Default `60000`. */\n timeout?: number;\n /** Max automatic retries on transient failures. Default `2`. */\n maxRetries?: number;\n /** Custom fetch implementation (e.g. undici, a test mock). Default `globalThis.fetch`. */\n fetch?: typeof fetch;\n}\n\n/** Per-request overrides accepted by every resource method. */\nexport interface RequestOptions {\n /** Override the client timeout (ms) for this request. */\n timeout?: number;\n /** Override the client retry count for this request (e.g. `0` to disable). */\n maxRetries?: number;\n /** Caller cancellation; composed with the internal timeout signal. */\n signal?: AbortSignal;\n}\n\n/** Fully-resolved, validated client configuration. */\nexport interface ResolvedOptions {\n apiKey: string;\n /** Normalized base URL, no trailing slash. */\n baseURL: string;\n timeout: number;\n maxRetries: number;\n fetch: typeof fetch;\n}\n\nfunction isBrowser(): boolean {\n return typeof window !== 'undefined' && typeof window.document !== 'undefined';\n}\n\n/** Validate and normalize {@link ClientOptions} into {@link ResolvedOptions}. */\nexport function resolveOptions(options: ClientOptions): ResolvedOptions {\n if (isBrowser()) {\n throw new CestoError(\n 'The Cesto SDK is server-side only. It must not run in a browser — a secret key ' +\n '(cesto_sk_…) would be exposed to end users.',\n );\n }\n\n const apiKey = options.apiKey;\n if (!apiKey) {\n throw new CestoError('Missing API key. Pass { apiKey } when constructing the client.');\n }\n\n const fetchImpl = options.fetch ?? globalThis.fetch;\n if (typeof fetchImpl !== 'function') {\n throw new CestoError(\n 'No fetch implementation found. Use Node 18+ or pass a custom { fetch } in ClientOptions.',\n );\n }\n\n const timeout = options.timeout ?? DEFAULT_TIMEOUT_MS;\n if (!Number.isFinite(timeout) || timeout < 0) {\n throw new CestoError('`timeout` must be a finite number >= 0.');\n }\n\n const maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES;\n if (!Number.isInteger(maxRetries) || maxRetries < 0) {\n throw new CestoError('`maxRetries` must be an integer >= 0.');\n }\n\n return {\n apiKey,\n baseURL: PROD_BASE_URL,\n timeout,\n maxRetries,\n fetch: options.fetch ?? fetchImpl.bind(globalThis),\n };\n}\n","/** SDK version. Keep in sync with package.json `version`. */\nexport const VERSION = '0.0.1';\n","import {\n APIConnectionError,\n APIConnectionTimeoutError,\n type APIError,\n type APIErrorEnvelope,\n APIUserAbortError,\n CestoError,\n makeAPIError,\n} from './errors.js';\nimport type { RequestOptions, ResolvedOptions } from './options.js';\nimport { VERSION } from './version.js';\n\n/** Query parameters; `undefined`/`null` values are skipped. */\nexport type QueryParams = Record<string, string | number | boolean | undefined | null>;\n\ninterface GetOptions extends RequestOptions {\n query?: QueryParams;\n}\n\nconst RETRY_BASE_MS = 500;\nconst RETRY_CAP_MS = 8_000;\n\n/** Internal transport: builds requests, applies auth, retries, and parses JSON. */\nexport class APIClientCore {\n constructor(private readonly opts: ResolvedOptions) {}\n\n get<T>(path: string, options: GetOptions = {}): Promise<T> {\n return this.request<T>('GET', path, options);\n }\n\n private async request<T>(method: string, path: string, options: GetOptions): Promise<T> {\n const url = this.buildURL(path, options.query);\n const timeout = options.timeout ?? this.opts.timeout;\n const maxRetries = options.maxRetries ?? this.opts.maxRetries;\n\n let attempt = 0;\n // Loop: returns on success/non-retryable error, retries transient failures.\n for (;;) {\n const timer = withTimeout(options.signal, timeout);\n let response: Response;\n\n try {\n response = await this.opts.fetch(url, {\n method,\n headers: buildHeaders(this.opts.apiKey, attempt),\n signal: timer.signal,\n });\n } catch (err) {\n timer.cleanup();\n const mapped = mapFetchError(err, timer, options.signal);\n // Never retry a user abort.\n if (mapped instanceof APIUserAbortError) throw mapped;\n if (attempt < maxRetries) {\n attempt += 1;\n await sleep(backoff(attempt));\n continue;\n }\n throw mapped;\n }\n\n timer.cleanup();\n\n if (response.ok) {\n return parseJSON<T>(response);\n }\n\n if (shouldRetryStatus(response.status) && attempt < maxRetries) {\n attempt += 1;\n await sleep(parseRetryAfter(response.headers) ?? backoff(attempt));\n continue;\n }\n\n throw await errorFromResponse(response);\n }\n }\n\n private buildURL(path: string, query?: QueryParams): string {\n const url = new URL(`${this.opts.baseURL}${path}`);\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined && value !== null) url.searchParams.set(key, String(value));\n }\n }\n return url.toString();\n }\n}\n\nfunction buildHeaders(apiKey: string, attempt: number): Record<string, string> {\n const headers: Record<string, string> = {\n 'X-API-Key': apiKey,\n Accept: 'application/json',\n };\n const ua = userAgent();\n if (ua) headers['User-Agent'] = ua;\n if (attempt > 0) headers['x-cesto-retry-count'] = String(attempt);\n return headers;\n}\n\nfunction userAgent(): string {\n if (typeof process !== 'undefined' && process.versions?.node) {\n return `cesto-sdk/${VERSION} (node/${process.versions.node})`;\n }\n return `cesto-sdk/${VERSION}`;\n}\n\n/** AbortController that fires on either the caller's signal or the timeout. */\nfunction withTimeout(userSignal: AbortSignal | undefined, timeoutMs: number) {\n const controller = new AbortController();\n let timedOut = false;\n\n const timer = setTimeout(() => {\n timedOut = true;\n controller.abort(new Error('timeout'));\n }, timeoutMs);\n\n const onUserAbort = () => controller.abort(userSignal?.reason);\n if (userSignal) {\n if (userSignal.aborted) controller.abort(userSignal.reason);\n else userSignal.addEventListener('abort', onUserAbort, { once: true });\n }\n\n return {\n signal: controller.signal,\n didTimeout: () => timedOut,\n cleanup: () => {\n clearTimeout(timer);\n userSignal?.removeEventListener('abort', onUserAbort);\n },\n };\n}\n\nfunction mapFetchError(\n err: unknown,\n timer: { didTimeout: () => boolean },\n userSignal: AbortSignal | undefined,\n): CestoError {\n if (userSignal?.aborted) return new APIUserAbortError();\n if (timer.didTimeout()) return new APIConnectionTimeoutError();\n return new APIConnectionError('Connection error', { cause: err });\n}\n\nfunction shouldRetryStatus(status: number): boolean {\n return status === 408 || status === 409 || status === 429 || status >= 500;\n}\n\nasync function parseJSON<T>(response: Response): Promise<T> {\n const text = await response.text();\n if (!text) return undefined as T;\n try {\n return JSON.parse(text) as T;\n } catch {\n throw new CestoError('Failed to parse response body as JSON.');\n }\n}\n\nasync function errorFromResponse(response: Response): Promise<APIError> {\n let envelope: APIErrorEnvelope = {};\n try {\n const text = await response.text();\n if (text) {\n const parsed = JSON.parse(text) as unknown;\n if (parsed && typeof parsed === 'object') envelope = parsed as APIErrorEnvelope;\n }\n } catch {\n // Non-JSON error body — fall back to status-only error.\n }\n return makeAPIError(\n response.status,\n envelope,\n response.headers,\n parseRetryAfter(response.headers),\n );\n}\n\n/** Parse a `Retry-After` header (delta-seconds or HTTP-date) into milliseconds. */\nfunction parseRetryAfter(headers: Headers): number | undefined {\n const value = headers.get('retry-after');\n if (!value) return undefined;\n const seconds = Number(value);\n if (!Number.isNaN(seconds)) return Math.max(0, seconds * 1000);\n const dateMs = Date.parse(value);\n if (!Number.isNaN(dateMs)) return Math.max(0, dateMs - Date.now());\n return undefined;\n}\n\n/** Exponential backoff with full jitter, capped. */\nfunction backoff(attempt: number): number {\n const ceiling = Math.min(RETRY_CAP_MS, RETRY_BASE_MS * 2 ** (attempt - 1));\n return Math.random() * ceiling;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import type { APIClientCore } from '../core/request.js';\n\n/** Base class for resource groups; holds a reference to the transport. */\nexport abstract class APIResource {\n constructor(protected readonly client: APIClientCore) {}\n}\n","import { CestoError } from '../core/errors.js';\nimport type { RequestOptions } from '../core/options.js';\nimport type { PositionsResult } from '../types/positions.js';\nimport { APIResource } from './resource.js';\n\nexport interface PositionsListParams {\n /** External Solana wallet address (Phantom/Solflare). Required. */\n wallet: string;\n}\n\nexport class Positions extends APIResource {\n /**\n * List a user's open/closing positions, resolved from their external Solana\n * wallet. A wallet with no Cesto account returns an empty result (not an error).\n */\n list(params: PositionsListParams, options?: RequestOptions): Promise<PositionsResult> {\n if (!params?.wallet) throw new CestoError('wallet is required');\n return this.client.get<PositionsResult>('/positions/by-wallet', {\n query: { wallet: params.wallet },\n ...options,\n });\n }\n}\n","import type { RequestOptions } from '../core/options.js';\nimport type {\n ProductBacktest,\n ProductBacktestChart,\n ProductListItem,\n ProductVersionResponse,\n ProductWithBacktest,\n ProductWithBacktestChart,\n} from '../types/products.js';\nimport type { ChartTimeRange } from '../types/shared.js';\nimport { APIResource } from './resource.js';\n\nexport interface ProductListParams {\n /** Filter by category. */\n category?: string;\n /**\n * Also fetch backtested performance (`GET /products/analytics`) and merge it\n * onto each product as `backtest`. Fails gracefully → `backtest: null`.\n */\n includeBacktest?: boolean;\n}\n\nexport interface ProductGetParams {\n /**\n * Also fetch the product's backtested value chart and attach it as `backtestChart`.\n * Fails gracefully → `backtestChart: null`.\n */\n includeBacktestChart?: boolean;\n /** Chart window when `includeBacktestChart` is true. Default `'1y'`. */\n chartTimeRange?: ChartTimeRange;\n}\n\nconst DEFAULT_CHART_TIME_RANGE: ChartTimeRange = '1y';\n\nexport class Products extends APIResource {\n /** List products. */\n list(): Promise<ProductListItem[]>;\n list(\n params: ProductListParams & { includeBacktest?: false },\n options?: RequestOptions,\n ): Promise<ProductListItem[]>;\n list(\n params: ProductListParams & { includeBacktest: true },\n options?: RequestOptions,\n ): Promise<ProductWithBacktest[]>;\n async list(\n params: ProductListParams = {},\n options?: RequestOptions,\n ): Promise<ProductListItem[] | ProductWithBacktest[]> {\n const query = params.category ? { category: params.category } : undefined;\n\n if (!params.includeBacktest) {\n return this.client.get<ProductListItem[]>('/products', { query, ...options });\n }\n\n const [items, backtests] = await Promise.all([\n this.client.get<ProductListItem[]>('/products', { query, ...options }),\n this.client\n .get<Record<string, ProductBacktest>>('/products/analytics', { query, ...options })\n // Graceful: a failed/slow analytics fetch never breaks the list.\n .catch(() => ({}) as Record<string, ProductBacktest>),\n ]);\n\n return items.map((item) => ({ ...item, backtest: backtests[item.id] ?? null }));\n }\n\n /** Get a product by slug. */\n get(slug: string): Promise<ProductVersionResponse>;\n get(\n slug: string,\n params: ProductGetParams & { includeBacktestChart?: false },\n options?: RequestOptions,\n ): Promise<ProductVersionResponse>;\n get(\n slug: string,\n params: ProductGetParams & { includeBacktestChart: true },\n options?: RequestOptions,\n ): Promise<ProductWithBacktestChart>;\n async get(\n slug: string,\n params: ProductGetParams = {},\n options?: RequestOptions,\n ): Promise<ProductVersionResponse | ProductWithBacktestChart> {\n const product = await this.client.get<ProductVersionResponse>(\n `/products/${encodeURIComponent(slug)}`,\n options,\n );\n\n if (!params.includeBacktestChart) return product;\n\n // Sequential: the chart is keyed by productId, which we only have after the\n // detail fetch resolves the slug. Graceful: a chart failure → null.\n const backtestChart = await this.client\n .get<ProductBacktestChart>(`/products/${encodeURIComponent(product.id)}/graph`, {\n query: { timeRange: params.chartTimeRange ?? DEFAULT_CHART_TIME_RANGE },\n ...options,\n })\n .catch(() => null);\n\n return { ...product, backtestChart };\n }\n}\n","import {\n APIConnectionError,\n APIConnectionTimeoutError,\n APIError,\n APIUserAbortError,\n AuthenticationError,\n BadRequestError,\n CestoError,\n ConflictError,\n InternalServerError,\n NotFoundError,\n PermissionDeniedError,\n RateLimitError,\n UnprocessableEntityError,\n} from './core/errors.js';\nimport { type ClientOptions, resolveOptions } from './core/options.js';\nimport { APIClientCore } from './core/request.js';\nimport { Positions } from './resources/positions.js';\nimport { Products } from './resources/products.js';\n\n/**\n * The Cesto SDK client.\n *\n * @example\n * ```ts\n * const cesto = new Cesto({ apiKey: process.env.CESTO_API_KEY! });\n * const products = await cesto.products.list({ includeBacktest: true });\n * ```\n */\nexport class Cesto {\n readonly products: Products;\n readonly positions: Positions;\n private readonly core: APIClientCore;\n\n constructor(options: ClientOptions = {}) {\n this.core = new APIClientCore(resolveOptions(options));\n this.products = new Products(this.core);\n this.positions = new Positions(this.core);\n }\n\n // Error classes re-exposed for ergonomic `instanceof` checks:\n // catch (e) { if (e instanceof Cesto.NotFoundError) … }\n static readonly CestoError = CestoError;\n static readonly APIError = APIError;\n static readonly BadRequestError = BadRequestError;\n static readonly AuthenticationError = AuthenticationError;\n static readonly PermissionDeniedError = PermissionDeniedError;\n static readonly NotFoundError = NotFoundError;\n static readonly ConflictError = ConflictError;\n static readonly UnprocessableEntityError = UnprocessableEntityError;\n static readonly RateLimitError = RateLimitError;\n static readonly InternalServerError = InternalServerError;\n static readonly APIConnectionError = APIConnectionError;\n static readonly APIConnectionTimeoutError = APIConnectionTimeoutError;\n static readonly APIUserAbortError = APIUserAbortError;\n}\n","import type {\n ChartTimeRange,\n GeoStatus,\n IncentiveOverlayCampaign,\n PredictionMarketState,\n TokenPerformance,\n} from './shared.js';\n\n/** An item in `products.list()` — `GET /products`. */\nexport interface ProductListItem {\n id: string;\n slug: string;\n name: string;\n description: string | null;\n logoUrl: string | null;\n category: string | null;\n tags: string[];\n isActive: boolean;\n isPublished: boolean;\n pointMultiplier: number;\n metadata: Record<string, unknown> | null;\n geoStatus: GeoStatus;\n /** Active incentive campaigns; `[]` when none. */\n incentives: IncentiveOverlayCampaign[];\n}\n\n/** Backtested performance for a product — `GET /products/analytics` (per product). */\nexport interface ProductBacktest {\n protocolsInvolved: string[];\n tokensInvolved: string[];\n tokenPerformance: TokenPerformance | null;\n tokenPerformance7d: TokenPerformance | null;\n tokenPerformance30d: TokenPerformance | null;\n priceChange24h: number | null;\n tokenPriceChanges: Record<\n string,\n { priceChange24h: number | null; priceChange24hPercent: number | null }\n >;\n}\n\n/** `products.list({ includeBacktest: true })` — list item with backtest merged in. */\nexport type ProductWithBacktest = ProductListItem & {\n backtest: ProductBacktest | null;\n};\n\nexport interface ProductCreator {\n id: string;\n username: string | null;\n email: string | null;\n solanaWalletAddress: string | null;\n embeddedWalletAddress: string | null;\n}\n\nexport interface OndoTradingStatus {\n allTradable: boolean;\n currentSession: string;\n hasOndoTokens: boolean;\n tokens: unknown[];\n untradableTokens: unknown[];\n nextFullyTradableAt: string | null;\n nextFullyTradableSession: string | null;\n}\n\n/** Full product detail — `GET /products/:slug`. */\nexport interface ProductVersionResponse {\n id: string;\n versionId: string;\n version: number;\n changelog: string | null;\n minimumInvestment: string;\n inputTokenMint: string;\n inputTokenDecimals: number;\n about: string | null;\n riskNotes: string | null;\n resources: string | null;\n name: string;\n slug: string;\n description: string | null;\n logoUrl: string | null;\n category: string | null;\n tags: string[];\n isActive: boolean;\n isPublished: boolean;\n metadata: Record<string, unknown> | null;\n pointMultiplier: number;\n createdBy: string;\n creator: ProductCreator | null;\n tokensInvolved: string[];\n protocolsInvolved: string[];\n tokenPerformance: TokenPerformance | null;\n tokenPerformance7d: TokenPerformance | null;\n tokenPerformance30d: TokenPerformance | null;\n predictionMarkets?: PredictionMarketState[];\n canInvest: boolean;\n /** Raw workflow definition. */\n definition: unknown;\n geoStatus: GeoStatus;\n ondoTradingStatus: OndoTradingStatus;\n incentives?: IncentiveOverlayCampaign[];\n /**\n * The product's current (canonical) slug. When the request used an old slug\n * that has since been renamed, this differs from the requested slug and\n * `slugRedirect` is true — clients should redirect to the canonical slug.\n */\n canonicalSlug?: string;\n /** True when the requested slug was an old alias that redirects to `canonicalSlug`. */\n slugRedirect?: boolean;\n}\n\nexport interface BacktestChartTimeSeriesPoint {\n timestamp: string;\n portfolioValue: number;\n sp500Value?: number;\n btcValue?: number;\n solValue?: number;\n usdcValue?: number;\n isLiquidated?: boolean;\n liquidationThreshold?: number;\n}\n\nexport interface BacktestChartMetrics {\n totalReturn: number;\n cagr: number;\n volatility: number;\n maxDrawdown: number;\n sharpe: number;\n}\n\nexport interface PredictionMarketEvent {\n ticker: string;\n marketTicker: string;\n seriesTicker: string;\n title: string;\n closeTime: number;\n currentProbability?: number;\n currentPrice: number;\n daysToClose: number;\n timeSeries: Array<{\n market_ticker: string;\n event_ticker: string;\n raw_numerical_forecast: number;\n numerical_forecast: number;\n formatted_forecast: string;\n end_period_ts: number;\n period_interval: number;\n }>;\n}\n\n/** Token-portfolio backtest chart — `GET /products/:id/graph` (non-prediction). */\nexport interface BacktestChart {\n workflowId: string;\n name: string;\n timeRange?: ChartTimeRange;\n timeSeries: BacktestChartTimeSeriesPoint[];\n /** Computed only when `timeRange === '1y'`; null otherwise. */\n metrics: BacktestChartMetrics | null;\n assetPerformance: Array<{ token: string; mint: string; returnPct: number }>;\n contributions: Array<{ token: string; mint: string; contribution: number }>;\n assetSparklines: Array<{\n token: string;\n mint: string;\n points: Array<{ timestamp: string; value: number; price: number }>;\n }>;\n checkpoints?: Array<{\n timestamp: string;\n version: number;\n fromVersion: number | null;\n changelog: string | null;\n added: Array<{ token: string; mint: string; allocation: number }>;\n removed: Array<{ token: string; mint: string; allocation: number }>;\n reweighted: Array<{ token: string; mint: string; fromPct: number; toPct: number }>;\n }>;\n liquidationInfo?: {\n hasLiquidations: boolean;\n liquidationEvents: Array<{\n timestamp: string;\n asset: string;\n liquidationPrice: number;\n actualPrice: number;\n }>;\n liquidationThresholds: Array<{\n asset: string;\n mint: string;\n liquidationPrice: number;\n entryPrice: number;\n leverage: number;\n direction: 'LONG' | 'SHORT';\n }>;\n };\n hasPredictionMarkets?: boolean;\n predictionMarketEvents?: PredictionMarketEvent[];\n incentives?: IncentiveOverlayCampaign[];\n}\n\n/** Prediction-market backtest chart — `GET /products/:id/graph` (prediction). */\nexport interface PredictionMarketChart {\n workflowId: string;\n name: string;\n predictionMarket: boolean;\n markets: PredictionMarketEvent[];\n incentives?: IncentiveOverlayCampaign[];\n}\n\n/** Union returned by the graph endpoint. Discriminate with {@link isPredictionMarketChart}. */\nexport type ProductBacktestChart = BacktestChart | PredictionMarketChart;\n\n/** `products.get(slug, { includeBacktestChart: true })` — detail with chart merged in. */\nexport type ProductWithBacktestChart = ProductVersionResponse & {\n backtestChart: ProductBacktestChart | null;\n};\n\n/** Type guard: is this chart the prediction-market variant? */\nexport function isPredictionMarketChart(\n chart: ProductBacktestChart,\n): chart is PredictionMarketChart {\n return (chart as PredictionMarketChart).predictionMarket === true;\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -78,8 +78,6 @@ declare class APIUserAbortError extends CestoError {
78
78
  constructor(message?: string);
79
79
  }
80
80
 
81
- /** Which deployed Cesto backend to target. */
82
- type CestoEnvironment = 'PRODUCTION' | 'BETA';
83
81
  /** Options for constructing a {@link Cesto} client. */
84
82
  interface ClientOptions {
85
83
  /**
@@ -87,11 +85,6 @@ interface ClientOptions {
87
85
  * Read it from your environment yourself, e.g. `apiKey: process.env.CESTO_API_KEY`.
88
86
  */
89
87
  apiKey?: string;
90
- /**
91
- * Which backend to target in a deployed build (`NODE_ENV=production`):
92
- * `PRODUCTION` → backend.cesto.co, `BETA` → dev.backend.cesto.co. Default `PRODUCTION`.
93
- */
94
- environment?: CestoEnvironment;
95
88
  /** Per-request timeout in milliseconds. Default `60000`. */
96
89
  timeout?: number;
97
90
  /** Max automatic retries on transient failures. Default `2`. */
@@ -120,7 +113,7 @@ interface ResolvedOptions {
120
113
 
121
114
  /** Backtest chart window. Only `1y` carries full portfolio metrics. */
122
115
  type ChartTimeRange = '7d' | '1m' | '3m' | '6m' | '1y' | 'all';
123
- type PredictionProtocol = 'kalshi' | 'polymarket';
116
+ type PredictionProtocol = 'polymarket';
124
117
  type PredictionSide = 'YES' | 'NO';
125
118
  type MarketStatus = 'initialized' | 'active' | 'inactive' | 'closed' | 'determined' | 'finalized';
126
119
  /** Whether the requester's region may view / invest in a product. */
@@ -376,12 +369,19 @@ interface ProductVersionResponse {
376
369
  geoStatus: GeoStatus;
377
370
  ondoTradingStatus: OndoTradingStatus;
378
371
  incentives?: IncentiveOverlayCampaign[];
372
+ /**
373
+ * The product's current (canonical) slug. When the request used an old slug
374
+ * that has since been renamed, this differs from the requested slug and
375
+ * `slugRedirect` is true — clients should redirect to the canonical slug.
376
+ */
377
+ canonicalSlug?: string;
378
+ /** True when the requested slug was an old alias that redirects to `canonicalSlug`. */
379
+ slugRedirect?: boolean;
379
380
  }
380
381
  interface BacktestChartTimeSeriesPoint {
381
382
  timestamp: string;
382
383
  portfolioValue: number;
383
384
  sp500Value?: number;
384
- mag7Value?: number;
385
385
  btcValue?: number;
386
386
  solValue?: number;
387
387
  usdcValue?: number;
@@ -570,4 +570,4 @@ declare class Cesto {
570
570
  /** SDK version. Keep in sync with package.json `version`. */
571
571
  declare const VERSION = "0.0.1";
572
572
 
573
- export { APIConnectionError, APIConnectionTimeoutError, APIError, type APIErrorEnvelope, APIUserAbortError, AuthenticationError, type BacktestChart, type BacktestChartMetrics, type BacktestChartTimeSeriesPoint, BadRequestError, Cesto, type CestoEnvironment, CestoError, type ChartTimeRange, type ClientOptions, ConflictError, type GeoStatus, type IncentiveOverlayCampaign, InternalServerError, type MarketStatus, NotFoundError, type OndoTradingStatus, PermissionDeniedError, type Position, type PositionInvestment, type PositionProduct, type PositionValuation, type PositionVersion, type PositionsListParams, type PositionsResult, type PredictionMarketChart, type PredictionMarketEvent, type PredictionMarketState, type PredictionPerformance, type PredictionProtocol, type PredictionSide, type ProductBacktest, type ProductBacktestChart, type ProductCreator, type ProductGetParams, type ProductListItem, type ProductListParams, type ProductVersionResponse, type ProductWithBacktest, type ProductWithBacktestChart, RateLimitError, type RequestOptions, type TokenPerformance, UnprocessableEntityError, VERSION, isPredictionMarketChart };
573
+ export { APIConnectionError, APIConnectionTimeoutError, APIError, type APIErrorEnvelope, APIUserAbortError, AuthenticationError, type BacktestChart, type BacktestChartMetrics, type BacktestChartTimeSeriesPoint, BadRequestError, Cesto, CestoError, type ChartTimeRange, type ClientOptions, ConflictError, type GeoStatus, type IncentiveOverlayCampaign, InternalServerError, type MarketStatus, NotFoundError, type OndoTradingStatus, PermissionDeniedError, type Position, type PositionInvestment, type PositionProduct, type PositionValuation, type PositionVersion, type PositionsListParams, type PositionsResult, type PredictionMarketChart, type PredictionMarketEvent, type PredictionMarketState, type PredictionPerformance, type PredictionProtocol, type PredictionSide, type ProductBacktest, type ProductBacktestChart, type ProductCreator, type ProductGetParams, type ProductListItem, type ProductListParams, type ProductVersionResponse, type ProductWithBacktest, type ProductWithBacktestChart, RateLimitError, type RequestOptions, type TokenPerformance, UnprocessableEntityError, VERSION, isPredictionMarketChart };
package/dist/index.d.ts CHANGED
@@ -78,8 +78,6 @@ declare class APIUserAbortError extends CestoError {
78
78
  constructor(message?: string);
79
79
  }
80
80
 
81
- /** Which deployed Cesto backend to target. */
82
- type CestoEnvironment = 'PRODUCTION' | 'BETA';
83
81
  /** Options for constructing a {@link Cesto} client. */
84
82
  interface ClientOptions {
85
83
  /**
@@ -87,11 +85,6 @@ interface ClientOptions {
87
85
  * Read it from your environment yourself, e.g. `apiKey: process.env.CESTO_API_KEY`.
88
86
  */
89
87
  apiKey?: string;
90
- /**
91
- * Which backend to target in a deployed build (`NODE_ENV=production`):
92
- * `PRODUCTION` → backend.cesto.co, `BETA` → dev.backend.cesto.co. Default `PRODUCTION`.
93
- */
94
- environment?: CestoEnvironment;
95
88
  /** Per-request timeout in milliseconds. Default `60000`. */
96
89
  timeout?: number;
97
90
  /** Max automatic retries on transient failures. Default `2`. */
@@ -120,7 +113,7 @@ interface ResolvedOptions {
120
113
 
121
114
  /** Backtest chart window. Only `1y` carries full portfolio metrics. */
122
115
  type ChartTimeRange = '7d' | '1m' | '3m' | '6m' | '1y' | 'all';
123
- type PredictionProtocol = 'kalshi' | 'polymarket';
116
+ type PredictionProtocol = 'polymarket';
124
117
  type PredictionSide = 'YES' | 'NO';
125
118
  type MarketStatus = 'initialized' | 'active' | 'inactive' | 'closed' | 'determined' | 'finalized';
126
119
  /** Whether the requester's region may view / invest in a product. */
@@ -376,12 +369,19 @@ interface ProductVersionResponse {
376
369
  geoStatus: GeoStatus;
377
370
  ondoTradingStatus: OndoTradingStatus;
378
371
  incentives?: IncentiveOverlayCampaign[];
372
+ /**
373
+ * The product's current (canonical) slug. When the request used an old slug
374
+ * that has since been renamed, this differs from the requested slug and
375
+ * `slugRedirect` is true — clients should redirect to the canonical slug.
376
+ */
377
+ canonicalSlug?: string;
378
+ /** True when the requested slug was an old alias that redirects to `canonicalSlug`. */
379
+ slugRedirect?: boolean;
379
380
  }
380
381
  interface BacktestChartTimeSeriesPoint {
381
382
  timestamp: string;
382
383
  portfolioValue: number;
383
384
  sp500Value?: number;
384
- mag7Value?: number;
385
385
  btcValue?: number;
386
386
  solValue?: number;
387
387
  usdcValue?: number;
@@ -570,4 +570,4 @@ declare class Cesto {
570
570
  /** SDK version. Keep in sync with package.json `version`. */
571
571
  declare const VERSION = "0.0.1";
572
572
 
573
- export { APIConnectionError, APIConnectionTimeoutError, APIError, type APIErrorEnvelope, APIUserAbortError, AuthenticationError, type BacktestChart, type BacktestChartMetrics, type BacktestChartTimeSeriesPoint, BadRequestError, Cesto, type CestoEnvironment, CestoError, type ChartTimeRange, type ClientOptions, ConflictError, type GeoStatus, type IncentiveOverlayCampaign, InternalServerError, type MarketStatus, NotFoundError, type OndoTradingStatus, PermissionDeniedError, type Position, type PositionInvestment, type PositionProduct, type PositionValuation, type PositionVersion, type PositionsListParams, type PositionsResult, type PredictionMarketChart, type PredictionMarketEvent, type PredictionMarketState, type PredictionPerformance, type PredictionProtocol, type PredictionSide, type ProductBacktest, type ProductBacktestChart, type ProductCreator, type ProductGetParams, type ProductListItem, type ProductListParams, type ProductVersionResponse, type ProductWithBacktest, type ProductWithBacktestChart, RateLimitError, type RequestOptions, type TokenPerformance, UnprocessableEntityError, VERSION, isPredictionMarketChart };
573
+ export { APIConnectionError, APIConnectionTimeoutError, APIError, type APIErrorEnvelope, APIUserAbortError, AuthenticationError, type BacktestChart, type BacktestChartMetrics, type BacktestChartTimeSeriesPoint, BadRequestError, Cesto, CestoError, type ChartTimeRange, type ClientOptions, ConflictError, type GeoStatus, type IncentiveOverlayCampaign, InternalServerError, type MarketStatus, NotFoundError, type OndoTradingStatus, PermissionDeniedError, type Position, type PositionInvestment, type PositionProduct, type PositionValuation, type PositionVersion, type PositionsListParams, type PositionsResult, type PredictionMarketChart, type PredictionMarketEvent, type PredictionMarketState, type PredictionPerformance, type PredictionProtocol, type PredictionSide, type ProductBacktest, type ProductBacktestChart, type ProductCreator, type ProductGetParams, type ProductListItem, type ProductListParams, type ProductVersionResponse, type ProductWithBacktest, type ProductWithBacktestChart, RateLimitError, type RequestOptions, type TokenPerformance, UnprocessableEntityError, VERSION, isPredictionMarketChart };
package/dist/index.js CHANGED
@@ -96,15 +96,11 @@ function makeAPIError(status, envelope, headers, retryAfter) {
96
96
 
97
97
  // src/core/options.ts
98
98
  var PROD_BASE_URL = "https://backend.cesto.co";
99
- var BETA_BASE_URL = "https://dev.backend.cesto.co";
100
99
  var DEFAULT_TIMEOUT_MS = 6e4;
101
100
  var DEFAULT_MAX_RETRIES = 2;
102
101
  function isBrowser() {
103
102
  return typeof window !== "undefined" && typeof window.document !== "undefined";
104
103
  }
105
- function resolveBaseURL(environment) {
106
- return environment === "BETA" ? BETA_BASE_URL : PROD_BASE_URL;
107
- }
108
104
  function resolveOptions(options) {
109
105
  if (isBrowser()) {
110
106
  throw new CestoError(
@@ -129,13 +125,9 @@ function resolveOptions(options) {
129
125
  if (!Number.isInteger(maxRetries) || maxRetries < 0) {
130
126
  throw new CestoError("`maxRetries` must be an integer >= 0.");
131
127
  }
132
- const environment = options.environment ?? "PRODUCTION";
133
- if (environment !== "PRODUCTION" && environment !== "BETA") {
134
- throw new CestoError(`Invalid environment: ${environment}. Use 'PRODUCTION' or 'BETA'.`);
135
- }
136
128
  return {
137
129
  apiKey,
138
- baseURL: resolveBaseURL(environment),
130
+ baseURL: PROD_BASE_URL,
139
131
  timeout,
140
132
  maxRetries,
141
133
  fetch: options.fetch ?? fetchImpl.bind(globalThis)
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/errors.ts","../src/core/options.ts","../src/core/version.ts","../src/core/request.ts","../src/resources/resource.ts","../src/resources/positions.ts","../src/resources/products.ts","../src/client.ts","../src/types/products.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Error hierarchy thrown by the SDK.\n *\n * Everything extends {@link CestoError}. Server (non-2xx) responses become an\n * {@link APIError} subclass built from the API's `{ code, message, details,\n * requestId }` envelope; transport problems become {@link APIConnectionError}\n * (or its timeout subclass); caller cancellation becomes {@link APIUserAbortError}.\n */\n\n/** Base class for every error the SDK throws. */\nexport class CestoError extends Error {\n constructor(message: string) {\n super(message);\n this.name = new.target.name;\n // Restore the prototype chain for `instanceof` across the transpile target.\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Parsed `{ code, message, details, requestId }` envelope from the API. */\nexport interface APIErrorEnvelope {\n code?: string;\n message?: string;\n details?: unknown;\n requestId?: string;\n}\n\n/** A non-2xx HTTP response. */\nexport class APIError extends CestoError {\n /** HTTP status code. */\n readonly status: number;\n /** Machine-readable error code from the API envelope (e.g. `RESOURCE_NOT_FOUND`). */\n readonly code?: string;\n /** Correlation id from the API envelope, useful when reporting issues. */\n readonly requestId?: string;\n /** Structured error details from the API envelope. */\n readonly details?: unknown;\n /** Response headers. */\n readonly headers?: Headers;\n\n constructor(\n status: number,\n message: string,\n opts: { code?: string; requestId?: string; details?: unknown; headers?: Headers } = {},\n ) {\n super(message);\n this.status = status;\n this.code = opts.code;\n this.requestId = opts.requestId;\n this.details = opts.details;\n this.headers = opts.headers;\n }\n}\n\nexport class BadRequestError extends APIError {}\nexport class AuthenticationError extends APIError {}\nexport class PermissionDeniedError extends APIError {}\nexport class NotFoundError extends APIError {}\nexport class ConflictError extends APIError {}\nexport class UnprocessableEntityError extends APIError {}\n\n/** HTTP 429. Carries `retryAfter` (ms) when the server sent a `Retry-After` header. */\nexport class RateLimitError extends APIError {\n /** Milliseconds to wait before retrying, derived from `Retry-After`. */\n readonly retryAfter?: number;\n\n constructor(\n status: number,\n message: string,\n opts: {\n code?: string;\n requestId?: string;\n details?: unknown;\n headers?: Headers;\n retryAfter?: number;\n } = {},\n ) {\n super(status, message, opts);\n this.retryAfter = opts.retryAfter;\n }\n}\n\nexport class InternalServerError extends APIError {}\n\n/** A network-level failure (DNS, connection reset, fetch threw). */\nexport class APIConnectionError extends CestoError {\n readonly cause?: unknown;\n constructor(message = 'Connection error', opts: { cause?: unknown } = {}) {\n super(message);\n this.cause = opts.cause;\n }\n}\n\n/** The request exceeded the configured timeout. */\nexport class APIConnectionTimeoutError extends APIConnectionError {\n constructor(message = 'Request timed out') {\n super(message);\n }\n}\n\n/** The caller's `AbortSignal` fired. */\nexport class APIUserAbortError extends CestoError {\n constructor(message = 'Request was aborted') {\n super(message);\n }\n}\n\n/** Build the right {@link APIError} subclass from a parsed error response. */\nexport function makeAPIError(\n status: number,\n envelope: APIErrorEnvelope,\n headers: Headers,\n retryAfter?: number,\n): APIError {\n const message = envelope.message || `HTTP ${status}`;\n const opts = {\n code: envelope.code,\n requestId: envelope.requestId,\n details: envelope.details,\n headers,\n };\n\n switch (status) {\n case 400:\n return new BadRequestError(status, message, opts);\n case 401:\n return new AuthenticationError(status, message, opts);\n case 403:\n return new PermissionDeniedError(status, message, opts);\n case 404:\n return new NotFoundError(status, message, opts);\n case 409:\n return new ConflictError(status, message, opts);\n case 422:\n return new UnprocessableEntityError(status, message, opts);\n case 429:\n return new RateLimitError(status, message, { ...opts, retryAfter });\n default:\n if (status >= 500) return new InternalServerError(status, message, opts);\n return new APIError(status, message, opts);\n }\n}\n","import { CestoError } from './errors.js';\n\nconst PROD_BASE_URL = 'https://backend.cesto.co';\nconst BETA_BASE_URL = 'https://dev.backend.cesto.co';\nconst DEFAULT_TIMEOUT_MS = 60_000;\nconst DEFAULT_MAX_RETRIES = 2;\n\n/** Which deployed Cesto backend to target. */\nexport type CestoEnvironment = 'PRODUCTION' | 'BETA';\n\n/** Options for constructing a {@link Cesto} client. */\nexport interface ClientOptions {\n /**\n * Secret API key (`cesto_sk_…`). Required — the constructor throws if omitted.\n * Read it from your environment yourself, e.g. `apiKey: process.env.CESTO_API_KEY`.\n */\n apiKey?: string;\n /**\n * Which backend to target in a deployed build (`NODE_ENV=production`):\n * `PRODUCTION` → backend.cesto.co, `BETA` → dev.backend.cesto.co. Default `PRODUCTION`.\n */\n environment?: CestoEnvironment;\n /** Per-request timeout in milliseconds. Default `60000`. */\n timeout?: number;\n /** Max automatic retries on transient failures. Default `2`. */\n maxRetries?: number;\n /** Custom fetch implementation (e.g. undici, a test mock). Default `globalThis.fetch`. */\n fetch?: typeof fetch;\n}\n\n/** Per-request overrides accepted by every resource method. */\nexport interface RequestOptions {\n /** Override the client timeout (ms) for this request. */\n timeout?: number;\n /** Override the client retry count for this request (e.g. `0` to disable). */\n maxRetries?: number;\n /** Caller cancellation; composed with the internal timeout signal. */\n signal?: AbortSignal;\n}\n\n/** Fully-resolved, validated client configuration. */\nexport interface ResolvedOptions {\n apiKey: string;\n /** Normalized base URL, no trailing slash. */\n baseURL: string;\n timeout: number;\n maxRetries: number;\n fetch: typeof fetch;\n}\n\nfunction isBrowser(): boolean {\n return typeof window !== 'undefined' && typeof window.document !== 'undefined';\n}\n\n/** Resolve the backend URL as per `environment`. */\nfunction resolveBaseURL(environment: CestoEnvironment): string {\n return environment === 'BETA' ? BETA_BASE_URL : PROD_BASE_URL;\n}\n\n/** Validate and normalize {@link ClientOptions} into {@link ResolvedOptions}. */\nexport function resolveOptions(options: ClientOptions): ResolvedOptions {\n if (isBrowser()) {\n throw new CestoError(\n 'The Cesto SDK is server-side only. It must not run in a browser — a secret key ' +\n '(cesto_sk_…) would be exposed to end users.',\n );\n }\n\n const apiKey = options.apiKey\n if (!apiKey) {\n throw new CestoError('Missing API key. Pass { apiKey } when constructing the client.');\n }\n\n const fetchImpl = options.fetch ?? globalThis.fetch;\n if (typeof fetchImpl !== 'function') {\n throw new CestoError(\n 'No fetch implementation found. Use Node 18+ or pass a custom { fetch } in ClientOptions.',\n );\n }\n\n const timeout = options.timeout ?? DEFAULT_TIMEOUT_MS;\n if (!Number.isFinite(timeout) || timeout < 0) {\n throw new CestoError('`timeout` must be a finite number >= 0.');\n }\n\n const maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES;\n if (!Number.isInteger(maxRetries) || maxRetries < 0) {\n throw new CestoError('`maxRetries` must be an integer >= 0.');\n }\n\n const environment = options.environment ?? 'PRODUCTION';\n if (environment !== 'PRODUCTION' && environment !== 'BETA') {\n throw new CestoError(`Invalid environment: ${environment}. Use 'PRODUCTION' or 'BETA'.`);\n }\n\n return {\n apiKey,\n baseURL: resolveBaseURL(environment),\n timeout,\n maxRetries,\n fetch: options.fetch ?? fetchImpl.bind(globalThis),\n };\n}\n","/** SDK version. Keep in sync with package.json `version`. */\nexport const VERSION = '0.0.1';\n","import {\n APIConnectionError,\n APIConnectionTimeoutError,\n type APIError,\n type APIErrorEnvelope,\n APIUserAbortError,\n CestoError,\n makeAPIError,\n} from './errors.js';\nimport type { RequestOptions, ResolvedOptions } from './options.js';\nimport { VERSION } from './version.js';\n\n/** Query parameters; `undefined`/`null` values are skipped. */\nexport type QueryParams = Record<string, string | number | boolean | undefined | null>;\n\ninterface GetOptions extends RequestOptions {\n query?: QueryParams;\n}\n\nconst RETRY_BASE_MS = 500;\nconst RETRY_CAP_MS = 8_000;\n\n/** Internal transport: builds requests, applies auth, retries, and parses JSON. */\nexport class APIClientCore {\n constructor(private readonly opts: ResolvedOptions) {}\n\n get<T>(path: string, options: GetOptions = {}): Promise<T> {\n return this.request<T>('GET', path, options);\n }\n\n private async request<T>(method: string, path: string, options: GetOptions): Promise<T> {\n const url = this.buildURL(path, options.query);\n const timeout = options.timeout ?? this.opts.timeout;\n const maxRetries = options.maxRetries ?? this.opts.maxRetries;\n\n let attempt = 0;\n // Loop: returns on success/non-retryable error, retries transient failures.\n for (;;) {\n const timer = withTimeout(options.signal, timeout);\n let response: Response;\n\n try {\n response = await this.opts.fetch(url, {\n method,\n headers: buildHeaders(this.opts.apiKey, attempt),\n signal: timer.signal,\n });\n } catch (err) {\n timer.cleanup();\n const mapped = mapFetchError(err, timer, options.signal);\n // Never retry a user abort.\n if (mapped instanceof APIUserAbortError) throw mapped;\n if (attempt < maxRetries) {\n attempt += 1;\n await sleep(backoff(attempt));\n continue;\n }\n throw mapped;\n }\n\n timer.cleanup();\n\n if (response.ok) {\n return parseJSON<T>(response);\n }\n\n if (shouldRetryStatus(response.status) && attempt < maxRetries) {\n attempt += 1;\n await sleep(parseRetryAfter(response.headers) ?? backoff(attempt));\n continue;\n }\n\n throw await errorFromResponse(response);\n }\n }\n\n private buildURL(path: string, query?: QueryParams): string {\n const url = new URL(`${this.opts.baseURL}${path}`);\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined && value !== null) url.searchParams.set(key, String(value));\n }\n }\n return url.toString();\n }\n}\n\nfunction buildHeaders(apiKey: string, attempt: number): Record<string, string> {\n const headers: Record<string, string> = {\n 'X-API-Key': apiKey,\n Accept: 'application/json',\n };\n const ua = userAgent();\n if (ua) headers['User-Agent'] = ua;\n if (attempt > 0) headers['x-cesto-retry-count'] = String(attempt);\n return headers;\n}\n\nfunction userAgent(): string {\n if (typeof process !== 'undefined' && process.versions?.node) {\n return `cesto-sdk/${VERSION} (node/${process.versions.node})`;\n }\n return `cesto-sdk/${VERSION}`;\n}\n\n/** AbortController that fires on either the caller's signal or the timeout. */\nfunction withTimeout(userSignal: AbortSignal | undefined, timeoutMs: number) {\n const controller = new AbortController();\n let timedOut = false;\n\n const timer = setTimeout(() => {\n timedOut = true;\n controller.abort(new Error('timeout'));\n }, timeoutMs);\n\n const onUserAbort = () => controller.abort(userSignal?.reason);\n if (userSignal) {\n if (userSignal.aborted) controller.abort(userSignal.reason);\n else userSignal.addEventListener('abort', onUserAbort, { once: true });\n }\n\n return {\n signal: controller.signal,\n didTimeout: () => timedOut,\n cleanup: () => {\n clearTimeout(timer);\n userSignal?.removeEventListener('abort', onUserAbort);\n },\n };\n}\n\nfunction mapFetchError(\n err: unknown,\n timer: { didTimeout: () => boolean },\n userSignal: AbortSignal | undefined,\n): CestoError {\n if (userSignal?.aborted) return new APIUserAbortError();\n if (timer.didTimeout()) return new APIConnectionTimeoutError();\n return new APIConnectionError('Connection error', { cause: err });\n}\n\nfunction shouldRetryStatus(status: number): boolean {\n return status === 408 || status === 409 || status === 429 || status >= 500;\n}\n\nasync function parseJSON<T>(response: Response): Promise<T> {\n const text = await response.text();\n if (!text) return undefined as T;\n try {\n return JSON.parse(text) as T;\n } catch {\n throw new CestoError('Failed to parse response body as JSON.');\n }\n}\n\nasync function errorFromResponse(response: Response): Promise<APIError> {\n let envelope: APIErrorEnvelope = {};\n try {\n const text = await response.text();\n if (text) {\n const parsed = JSON.parse(text) as unknown;\n if (parsed && typeof parsed === 'object') envelope = parsed as APIErrorEnvelope;\n }\n } catch {\n // Non-JSON error body — fall back to status-only error.\n }\n return makeAPIError(\n response.status,\n envelope,\n response.headers,\n parseRetryAfter(response.headers),\n );\n}\n\n/** Parse a `Retry-After` header (delta-seconds or HTTP-date) into milliseconds. */\nfunction parseRetryAfter(headers: Headers): number | undefined {\n const value = headers.get('retry-after');\n if (!value) return undefined;\n const seconds = Number(value);\n if (!Number.isNaN(seconds)) return Math.max(0, seconds * 1000);\n const dateMs = Date.parse(value);\n if (!Number.isNaN(dateMs)) return Math.max(0, dateMs - Date.now());\n return undefined;\n}\n\n/** Exponential backoff with full jitter, capped. */\nfunction backoff(attempt: number): number {\n const ceiling = Math.min(RETRY_CAP_MS, RETRY_BASE_MS * 2 ** (attempt - 1));\n return Math.random() * ceiling;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import type { APIClientCore } from '../core/request.js';\n\n/** Base class for resource groups; holds a reference to the transport. */\nexport abstract class APIResource {\n constructor(protected readonly client: APIClientCore) {}\n}\n","import { CestoError } from '../core/errors.js';\nimport type { RequestOptions } from '../core/options.js';\nimport type { PositionsResult } from '../types/positions.js';\nimport { APIResource } from './resource.js';\n\nexport interface PositionsListParams {\n /** External Solana wallet address (Phantom/Solflare). Required. */\n wallet: string;\n}\n\nexport class Positions extends APIResource {\n /**\n * List a user's open/closing positions, resolved from their external Solana\n * wallet. A wallet with no Cesto account returns an empty result (not an error).\n */\n list(params: PositionsListParams, options?: RequestOptions): Promise<PositionsResult> {\n if (!params?.wallet) throw new CestoError('wallet is required');\n return this.client.get<PositionsResult>('/positions/by-wallet', {\n query: { wallet: params.wallet },\n ...options,\n });\n }\n}\n","import type { RequestOptions } from '../core/options.js';\nimport type {\n ProductBacktest,\n ProductBacktestChart,\n ProductListItem,\n ProductVersionResponse,\n ProductWithBacktest,\n ProductWithBacktestChart,\n} from '../types/products.js';\nimport type { ChartTimeRange } from '../types/shared.js';\nimport { APIResource } from './resource.js';\n\nexport interface ProductListParams {\n /** Filter by category. */\n category?: string;\n /**\n * Also fetch backtested performance (`GET /products/analytics`) and merge it\n * onto each product as `backtest`. Fails gracefully → `backtest: null`.\n */\n includeBacktest?: boolean;\n}\n\nexport interface ProductGetParams {\n /**\n * Also fetch the product's backtested value chart and attach it as `backtestChart`.\n * Fails gracefully → `backtestChart: null`.\n */\n includeBacktestChart?: boolean;\n /** Chart window when `includeBacktestChart` is true. Default `'1y'`. */\n chartTimeRange?: ChartTimeRange;\n}\n\nconst DEFAULT_CHART_TIME_RANGE: ChartTimeRange = '1y';\n\nexport class Products extends APIResource {\n /** List products. */\n list(): Promise<ProductListItem[]>;\n list(\n params: ProductListParams & { includeBacktest?: false },\n options?: RequestOptions,\n ): Promise<ProductListItem[]>;\n list(\n params: ProductListParams & { includeBacktest: true },\n options?: RequestOptions,\n ): Promise<ProductWithBacktest[]>;\n async list(\n params: ProductListParams = {},\n options?: RequestOptions,\n ): Promise<ProductListItem[] | ProductWithBacktest[]> {\n const query = params.category ? { category: params.category } : undefined;\n\n if (!params.includeBacktest) {\n return this.client.get<ProductListItem[]>('/products', { query, ...options });\n }\n\n const [items, backtests] = await Promise.all([\n this.client.get<ProductListItem[]>('/products', { query, ...options }),\n this.client\n .get<Record<string, ProductBacktest>>('/products/analytics', { query, ...options })\n // Graceful: a failed/slow analytics fetch never breaks the list.\n .catch(() => ({}) as Record<string, ProductBacktest>),\n ]);\n\n return items.map((item) => ({ ...item, backtest: backtests[item.id] ?? null }));\n }\n\n /** Get a product by slug. */\n get(slug: string): Promise<ProductVersionResponse>;\n get(\n slug: string,\n params: ProductGetParams & { includeBacktestChart?: false },\n options?: RequestOptions,\n ): Promise<ProductVersionResponse>;\n get(\n slug: string,\n params: ProductGetParams & { includeBacktestChart: true },\n options?: RequestOptions,\n ): Promise<ProductWithBacktestChart>;\n async get(\n slug: string,\n params: ProductGetParams = {},\n options?: RequestOptions,\n ): Promise<ProductVersionResponse | ProductWithBacktestChart> {\n const product = await this.client.get<ProductVersionResponse>(\n `/products/${encodeURIComponent(slug)}`,\n options,\n );\n\n if (!params.includeBacktestChart) return product;\n\n // Sequential: the chart is keyed by productId, which we only have after the\n // detail fetch resolves the slug. Graceful: a chart failure → null.\n const backtestChart = await this.client\n .get<ProductBacktestChart>(`/products/${encodeURIComponent(product.id)}/graph`, {\n query: { timeRange: params.chartTimeRange ?? DEFAULT_CHART_TIME_RANGE },\n ...options,\n })\n .catch(() => null);\n\n return { ...product, backtestChart };\n }\n}\n","import {\n APIConnectionError,\n APIConnectionTimeoutError,\n APIError,\n APIUserAbortError,\n AuthenticationError,\n BadRequestError,\n CestoError,\n ConflictError,\n InternalServerError,\n NotFoundError,\n PermissionDeniedError,\n RateLimitError,\n UnprocessableEntityError,\n} from './core/errors.js';\nimport { type ClientOptions, resolveOptions } from './core/options.js';\nimport { APIClientCore } from './core/request.js';\nimport { Positions } from './resources/positions.js';\nimport { Products } from './resources/products.js';\n\n/**\n * The Cesto SDK client.\n *\n * @example\n * ```ts\n * const cesto = new Cesto({ apiKey: process.env.CESTO_API_KEY! });\n * const products = await cesto.products.list({ includeBacktest: true });\n * ```\n */\nexport class Cesto {\n readonly products: Products;\n readonly positions: Positions;\n private readonly core: APIClientCore;\n\n constructor(options: ClientOptions = {}) {\n this.core = new APIClientCore(resolveOptions(options));\n this.products = new Products(this.core);\n this.positions = new Positions(this.core);\n }\n\n // Error classes re-exposed for ergonomic `instanceof` checks:\n // catch (e) { if (e instanceof Cesto.NotFoundError) … }\n static readonly CestoError = CestoError;\n static readonly APIError = APIError;\n static readonly BadRequestError = BadRequestError;\n static readonly AuthenticationError = AuthenticationError;\n static readonly PermissionDeniedError = PermissionDeniedError;\n static readonly NotFoundError = NotFoundError;\n static readonly ConflictError = ConflictError;\n static readonly UnprocessableEntityError = UnprocessableEntityError;\n static readonly RateLimitError = RateLimitError;\n static readonly InternalServerError = InternalServerError;\n static readonly APIConnectionError = APIConnectionError;\n static readonly APIConnectionTimeoutError = APIConnectionTimeoutError;\n static readonly APIUserAbortError = APIUserAbortError;\n}\n","import type {\n ChartTimeRange,\n GeoStatus,\n IncentiveOverlayCampaign,\n PredictionMarketState,\n TokenPerformance,\n} from './shared.js';\n\n/** An item in `products.list()` — `GET /products`. */\nexport interface ProductListItem {\n id: string;\n slug: string;\n name: string;\n description: string | null;\n logoUrl: string | null;\n category: string | null;\n tags: string[];\n isActive: boolean;\n isPublished: boolean;\n pointMultiplier: number;\n metadata: Record<string, unknown> | null;\n geoStatus: GeoStatus;\n /** Active incentive campaigns; `[]` when none. */\n incentives: IncentiveOverlayCampaign[];\n}\n\n/** Backtested performance for a product — `GET /products/analytics` (per product). */\nexport interface ProductBacktest {\n protocolsInvolved: string[];\n tokensInvolved: string[];\n tokenPerformance: TokenPerformance | null;\n tokenPerformance7d: TokenPerformance | null;\n tokenPerformance30d: TokenPerformance | null;\n priceChange24h: number | null;\n tokenPriceChanges: Record<\n string,\n { priceChange24h: number | null; priceChange24hPercent: number | null }\n >;\n}\n\n/** `products.list({ includeBacktest: true })` — list item with backtest merged in. */\nexport type ProductWithBacktest = ProductListItem & {\n backtest: ProductBacktest | null;\n};\n\nexport interface ProductCreator {\n id: string;\n username: string | null;\n email: string | null;\n solanaWalletAddress: string | null;\n embeddedWalletAddress: string | null;\n}\n\nexport interface OndoTradingStatus {\n allTradable: boolean;\n currentSession: string;\n hasOndoTokens: boolean;\n tokens: unknown[];\n untradableTokens: unknown[];\n nextFullyTradableAt: string | null;\n nextFullyTradableSession: string | null;\n}\n\n/** Full product detail — `GET /products/:slug`. */\nexport interface ProductVersionResponse {\n id: string;\n versionId: string;\n version: number;\n changelog: string | null;\n minimumInvestment: string;\n inputTokenMint: string;\n inputTokenDecimals: number;\n about: string | null;\n riskNotes: string | null;\n resources: string | null;\n name: string;\n slug: string;\n description: string | null;\n logoUrl: string | null;\n category: string | null;\n tags: string[];\n isActive: boolean;\n isPublished: boolean;\n metadata: Record<string, unknown> | null;\n pointMultiplier: number;\n createdBy: string;\n creator: ProductCreator | null;\n tokensInvolved: string[];\n protocolsInvolved: string[];\n tokenPerformance: TokenPerformance | null;\n tokenPerformance7d: TokenPerformance | null;\n tokenPerformance30d: TokenPerformance | null;\n predictionMarkets?: PredictionMarketState[];\n canInvest: boolean;\n /** Raw workflow definition. */\n definition: unknown;\n geoStatus: GeoStatus;\n ondoTradingStatus: OndoTradingStatus;\n incentives?: IncentiveOverlayCampaign[];\n}\n\nexport interface BacktestChartTimeSeriesPoint {\n timestamp: string;\n portfolioValue: number;\n sp500Value?: number;\n mag7Value?: number;\n btcValue?: number;\n solValue?: number;\n usdcValue?: number;\n isLiquidated?: boolean;\n liquidationThreshold?: number;\n}\n\nexport interface BacktestChartMetrics {\n totalReturn: number;\n cagr: number;\n volatility: number;\n maxDrawdown: number;\n sharpe: number;\n}\n\nexport interface PredictionMarketEvent {\n ticker: string;\n marketTicker: string;\n seriesTicker: string;\n title: string;\n closeTime: number;\n currentProbability?: number;\n currentPrice: number;\n daysToClose: number;\n timeSeries: Array<{\n market_ticker: string;\n event_ticker: string;\n raw_numerical_forecast: number;\n numerical_forecast: number;\n formatted_forecast: string;\n end_period_ts: number;\n period_interval: number;\n }>;\n}\n\n/** Token-portfolio backtest chart — `GET /products/:id/graph` (non-prediction). */\nexport interface BacktestChart {\n workflowId: string;\n name: string;\n timeRange?: ChartTimeRange;\n timeSeries: BacktestChartTimeSeriesPoint[];\n /** Computed only when `timeRange === '1y'`; null otherwise. */\n metrics: BacktestChartMetrics | null;\n assetPerformance: Array<{ token: string; mint: string; returnPct: number }>;\n contributions: Array<{ token: string; mint: string; contribution: number }>;\n assetSparklines: Array<{\n token: string;\n mint: string;\n points: Array<{ timestamp: string; value: number; price: number }>;\n }>;\n checkpoints?: Array<{\n timestamp: string;\n version: number;\n fromVersion: number | null;\n changelog: string | null;\n added: Array<{ token: string; mint: string; allocation: number }>;\n removed: Array<{ token: string; mint: string; allocation: number }>;\n reweighted: Array<{ token: string; mint: string; fromPct: number; toPct: number }>;\n }>;\n liquidationInfo?: {\n hasLiquidations: boolean;\n liquidationEvents: Array<{\n timestamp: string;\n asset: string;\n liquidationPrice: number;\n actualPrice: number;\n }>;\n liquidationThresholds: Array<{\n asset: string;\n mint: string;\n liquidationPrice: number;\n entryPrice: number;\n leverage: number;\n direction: 'LONG' | 'SHORT';\n }>;\n };\n hasPredictionMarkets?: boolean;\n predictionMarketEvents?: PredictionMarketEvent[];\n incentives?: IncentiveOverlayCampaign[];\n}\n\n/** Prediction-market backtest chart — `GET /products/:id/graph` (prediction). */\nexport interface PredictionMarketChart {\n workflowId: string;\n name: string;\n predictionMarket: boolean;\n markets: PredictionMarketEvent[];\n incentives?: IncentiveOverlayCampaign[];\n}\n\n/** Union returned by the graph endpoint. Discriminate with {@link isPredictionMarketChart}. */\nexport type ProductBacktestChart = BacktestChart | PredictionMarketChart;\n\n/** `products.get(slug, { includeBacktestChart: true })` — detail with chart merged in. */\nexport type ProductWithBacktestChart = ProductVersionResponse & {\n backtestChart: ProductBacktestChart | null;\n};\n\n/** Type guard: is this chart the prediction-market variant? */\nexport function isPredictionMarketChart(\n chart: ProductBacktestChart,\n): chart is PredictionMarketChart {\n return (chart as PredictionMarketChart).predictionMarket === true;\n}\n"]}
1
+ {"version":3,"sources":["../src/core/errors.ts","../src/core/options.ts","../src/core/version.ts","../src/core/request.ts","../src/resources/resource.ts","../src/resources/positions.ts","../src/resources/products.ts","../src/client.ts","../src/types/products.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Error hierarchy thrown by the SDK.\n *\n * Everything extends {@link CestoError}. Server (non-2xx) responses become an\n * {@link APIError} subclass built from the API's `{ code, message, details,\n * requestId }` envelope; transport problems become {@link APIConnectionError}\n * (or its timeout subclass); caller cancellation becomes {@link APIUserAbortError}.\n */\n\n/** Base class for every error the SDK throws. */\nexport class CestoError extends Error {\n constructor(message: string) {\n super(message);\n this.name = new.target.name;\n // Restore the prototype chain for `instanceof` across the transpile target.\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Parsed `{ code, message, details, requestId }` envelope from the API. */\nexport interface APIErrorEnvelope {\n code?: string;\n message?: string;\n details?: unknown;\n requestId?: string;\n}\n\n/** A non-2xx HTTP response. */\nexport class APIError extends CestoError {\n /** HTTP status code. */\n readonly status: number;\n /** Machine-readable error code from the API envelope (e.g. `RESOURCE_NOT_FOUND`). */\n readonly code?: string;\n /** Correlation id from the API envelope, useful when reporting issues. */\n readonly requestId?: string;\n /** Structured error details from the API envelope. */\n readonly details?: unknown;\n /** Response headers. */\n readonly headers?: Headers;\n\n constructor(\n status: number,\n message: string,\n opts: { code?: string; requestId?: string; details?: unknown; headers?: Headers } = {},\n ) {\n super(message);\n this.status = status;\n this.code = opts.code;\n this.requestId = opts.requestId;\n this.details = opts.details;\n this.headers = opts.headers;\n }\n}\n\nexport class BadRequestError extends APIError {}\nexport class AuthenticationError extends APIError {}\nexport class PermissionDeniedError extends APIError {}\nexport class NotFoundError extends APIError {}\nexport class ConflictError extends APIError {}\nexport class UnprocessableEntityError extends APIError {}\n\n/** HTTP 429. Carries `retryAfter` (ms) when the server sent a `Retry-After` header. */\nexport class RateLimitError extends APIError {\n /** Milliseconds to wait before retrying, derived from `Retry-After`. */\n readonly retryAfter?: number;\n\n constructor(\n status: number,\n message: string,\n opts: {\n code?: string;\n requestId?: string;\n details?: unknown;\n headers?: Headers;\n retryAfter?: number;\n } = {},\n ) {\n super(status, message, opts);\n this.retryAfter = opts.retryAfter;\n }\n}\n\nexport class InternalServerError extends APIError {}\n\n/** A network-level failure (DNS, connection reset, fetch threw). */\nexport class APIConnectionError extends CestoError {\n readonly cause?: unknown;\n constructor(message = 'Connection error', opts: { cause?: unknown } = {}) {\n super(message);\n this.cause = opts.cause;\n }\n}\n\n/** The request exceeded the configured timeout. */\nexport class APIConnectionTimeoutError extends APIConnectionError {\n constructor(message = 'Request timed out') {\n super(message);\n }\n}\n\n/** The caller's `AbortSignal` fired. */\nexport class APIUserAbortError extends CestoError {\n constructor(message = 'Request was aborted') {\n super(message);\n }\n}\n\n/** Build the right {@link APIError} subclass from a parsed error response. */\nexport function makeAPIError(\n status: number,\n envelope: APIErrorEnvelope,\n headers: Headers,\n retryAfter?: number,\n): APIError {\n const message = envelope.message || `HTTP ${status}`;\n const opts = {\n code: envelope.code,\n requestId: envelope.requestId,\n details: envelope.details,\n headers,\n };\n\n switch (status) {\n case 400:\n return new BadRequestError(status, message, opts);\n case 401:\n return new AuthenticationError(status, message, opts);\n case 403:\n return new PermissionDeniedError(status, message, opts);\n case 404:\n return new NotFoundError(status, message, opts);\n case 409:\n return new ConflictError(status, message, opts);\n case 422:\n return new UnprocessableEntityError(status, message, opts);\n case 429:\n return new RateLimitError(status, message, { ...opts, retryAfter });\n default:\n if (status >= 500) return new InternalServerError(status, message, opts);\n return new APIError(status, message, opts);\n }\n}\n","import { CestoError } from './errors.js';\n\nconst PROD_BASE_URL = 'https://backend.cesto.co';\nconst DEFAULT_TIMEOUT_MS = 60_000;\nconst DEFAULT_MAX_RETRIES = 2;\n\n/** Options for constructing a {@link Cesto} client. */\nexport interface ClientOptions {\n /**\n * Secret API key (`cesto_sk_…`). Required — the constructor throws if omitted.\n * Read it from your environment yourself, e.g. `apiKey: process.env.CESTO_API_KEY`.\n */\n apiKey?: string;\n /** Per-request timeout in milliseconds. Default `60000`. */\n timeout?: number;\n /** Max automatic retries on transient failures. Default `2`. */\n maxRetries?: number;\n /** Custom fetch implementation (e.g. undici, a test mock). Default `globalThis.fetch`. */\n fetch?: typeof fetch;\n}\n\n/** Per-request overrides accepted by every resource method. */\nexport interface RequestOptions {\n /** Override the client timeout (ms) for this request. */\n timeout?: number;\n /** Override the client retry count for this request (e.g. `0` to disable). */\n maxRetries?: number;\n /** Caller cancellation; composed with the internal timeout signal. */\n signal?: AbortSignal;\n}\n\n/** Fully-resolved, validated client configuration. */\nexport interface ResolvedOptions {\n apiKey: string;\n /** Normalized base URL, no trailing slash. */\n baseURL: string;\n timeout: number;\n maxRetries: number;\n fetch: typeof fetch;\n}\n\nfunction isBrowser(): boolean {\n return typeof window !== 'undefined' && typeof window.document !== 'undefined';\n}\n\n/** Validate and normalize {@link ClientOptions} into {@link ResolvedOptions}. */\nexport function resolveOptions(options: ClientOptions): ResolvedOptions {\n if (isBrowser()) {\n throw new CestoError(\n 'The Cesto SDK is server-side only. It must not run in a browser — a secret key ' +\n '(cesto_sk_…) would be exposed to end users.',\n );\n }\n\n const apiKey = options.apiKey;\n if (!apiKey) {\n throw new CestoError('Missing API key. Pass { apiKey } when constructing the client.');\n }\n\n const fetchImpl = options.fetch ?? globalThis.fetch;\n if (typeof fetchImpl !== 'function') {\n throw new CestoError(\n 'No fetch implementation found. Use Node 18+ or pass a custom { fetch } in ClientOptions.',\n );\n }\n\n const timeout = options.timeout ?? DEFAULT_TIMEOUT_MS;\n if (!Number.isFinite(timeout) || timeout < 0) {\n throw new CestoError('`timeout` must be a finite number >= 0.');\n }\n\n const maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES;\n if (!Number.isInteger(maxRetries) || maxRetries < 0) {\n throw new CestoError('`maxRetries` must be an integer >= 0.');\n }\n\n return {\n apiKey,\n baseURL: PROD_BASE_URL,\n timeout,\n maxRetries,\n fetch: options.fetch ?? fetchImpl.bind(globalThis),\n };\n}\n","/** SDK version. Keep in sync with package.json `version`. */\nexport const VERSION = '0.0.1';\n","import {\n APIConnectionError,\n APIConnectionTimeoutError,\n type APIError,\n type APIErrorEnvelope,\n APIUserAbortError,\n CestoError,\n makeAPIError,\n} from './errors.js';\nimport type { RequestOptions, ResolvedOptions } from './options.js';\nimport { VERSION } from './version.js';\n\n/** Query parameters; `undefined`/`null` values are skipped. */\nexport type QueryParams = Record<string, string | number | boolean | undefined | null>;\n\ninterface GetOptions extends RequestOptions {\n query?: QueryParams;\n}\n\nconst RETRY_BASE_MS = 500;\nconst RETRY_CAP_MS = 8_000;\n\n/** Internal transport: builds requests, applies auth, retries, and parses JSON. */\nexport class APIClientCore {\n constructor(private readonly opts: ResolvedOptions) {}\n\n get<T>(path: string, options: GetOptions = {}): Promise<T> {\n return this.request<T>('GET', path, options);\n }\n\n private async request<T>(method: string, path: string, options: GetOptions): Promise<T> {\n const url = this.buildURL(path, options.query);\n const timeout = options.timeout ?? this.opts.timeout;\n const maxRetries = options.maxRetries ?? this.opts.maxRetries;\n\n let attempt = 0;\n // Loop: returns on success/non-retryable error, retries transient failures.\n for (;;) {\n const timer = withTimeout(options.signal, timeout);\n let response: Response;\n\n try {\n response = await this.opts.fetch(url, {\n method,\n headers: buildHeaders(this.opts.apiKey, attempt),\n signal: timer.signal,\n });\n } catch (err) {\n timer.cleanup();\n const mapped = mapFetchError(err, timer, options.signal);\n // Never retry a user abort.\n if (mapped instanceof APIUserAbortError) throw mapped;\n if (attempt < maxRetries) {\n attempt += 1;\n await sleep(backoff(attempt));\n continue;\n }\n throw mapped;\n }\n\n timer.cleanup();\n\n if (response.ok) {\n return parseJSON<T>(response);\n }\n\n if (shouldRetryStatus(response.status) && attempt < maxRetries) {\n attempt += 1;\n await sleep(parseRetryAfter(response.headers) ?? backoff(attempt));\n continue;\n }\n\n throw await errorFromResponse(response);\n }\n }\n\n private buildURL(path: string, query?: QueryParams): string {\n const url = new URL(`${this.opts.baseURL}${path}`);\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined && value !== null) url.searchParams.set(key, String(value));\n }\n }\n return url.toString();\n }\n}\n\nfunction buildHeaders(apiKey: string, attempt: number): Record<string, string> {\n const headers: Record<string, string> = {\n 'X-API-Key': apiKey,\n Accept: 'application/json',\n };\n const ua = userAgent();\n if (ua) headers['User-Agent'] = ua;\n if (attempt > 0) headers['x-cesto-retry-count'] = String(attempt);\n return headers;\n}\n\nfunction userAgent(): string {\n if (typeof process !== 'undefined' && process.versions?.node) {\n return `cesto-sdk/${VERSION} (node/${process.versions.node})`;\n }\n return `cesto-sdk/${VERSION}`;\n}\n\n/** AbortController that fires on either the caller's signal or the timeout. */\nfunction withTimeout(userSignal: AbortSignal | undefined, timeoutMs: number) {\n const controller = new AbortController();\n let timedOut = false;\n\n const timer = setTimeout(() => {\n timedOut = true;\n controller.abort(new Error('timeout'));\n }, timeoutMs);\n\n const onUserAbort = () => controller.abort(userSignal?.reason);\n if (userSignal) {\n if (userSignal.aborted) controller.abort(userSignal.reason);\n else userSignal.addEventListener('abort', onUserAbort, { once: true });\n }\n\n return {\n signal: controller.signal,\n didTimeout: () => timedOut,\n cleanup: () => {\n clearTimeout(timer);\n userSignal?.removeEventListener('abort', onUserAbort);\n },\n };\n}\n\nfunction mapFetchError(\n err: unknown,\n timer: { didTimeout: () => boolean },\n userSignal: AbortSignal | undefined,\n): CestoError {\n if (userSignal?.aborted) return new APIUserAbortError();\n if (timer.didTimeout()) return new APIConnectionTimeoutError();\n return new APIConnectionError('Connection error', { cause: err });\n}\n\nfunction shouldRetryStatus(status: number): boolean {\n return status === 408 || status === 409 || status === 429 || status >= 500;\n}\n\nasync function parseJSON<T>(response: Response): Promise<T> {\n const text = await response.text();\n if (!text) return undefined as T;\n try {\n return JSON.parse(text) as T;\n } catch {\n throw new CestoError('Failed to parse response body as JSON.');\n }\n}\n\nasync function errorFromResponse(response: Response): Promise<APIError> {\n let envelope: APIErrorEnvelope = {};\n try {\n const text = await response.text();\n if (text) {\n const parsed = JSON.parse(text) as unknown;\n if (parsed && typeof parsed === 'object') envelope = parsed as APIErrorEnvelope;\n }\n } catch {\n // Non-JSON error body — fall back to status-only error.\n }\n return makeAPIError(\n response.status,\n envelope,\n response.headers,\n parseRetryAfter(response.headers),\n );\n}\n\n/** Parse a `Retry-After` header (delta-seconds or HTTP-date) into milliseconds. */\nfunction parseRetryAfter(headers: Headers): number | undefined {\n const value = headers.get('retry-after');\n if (!value) return undefined;\n const seconds = Number(value);\n if (!Number.isNaN(seconds)) return Math.max(0, seconds * 1000);\n const dateMs = Date.parse(value);\n if (!Number.isNaN(dateMs)) return Math.max(0, dateMs - Date.now());\n return undefined;\n}\n\n/** Exponential backoff with full jitter, capped. */\nfunction backoff(attempt: number): number {\n const ceiling = Math.min(RETRY_CAP_MS, RETRY_BASE_MS * 2 ** (attempt - 1));\n return Math.random() * ceiling;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import type { APIClientCore } from '../core/request.js';\n\n/** Base class for resource groups; holds a reference to the transport. */\nexport abstract class APIResource {\n constructor(protected readonly client: APIClientCore) {}\n}\n","import { CestoError } from '../core/errors.js';\nimport type { RequestOptions } from '../core/options.js';\nimport type { PositionsResult } from '../types/positions.js';\nimport { APIResource } from './resource.js';\n\nexport interface PositionsListParams {\n /** External Solana wallet address (Phantom/Solflare). Required. */\n wallet: string;\n}\n\nexport class Positions extends APIResource {\n /**\n * List a user's open/closing positions, resolved from their external Solana\n * wallet. A wallet with no Cesto account returns an empty result (not an error).\n */\n list(params: PositionsListParams, options?: RequestOptions): Promise<PositionsResult> {\n if (!params?.wallet) throw new CestoError('wallet is required');\n return this.client.get<PositionsResult>('/positions/by-wallet', {\n query: { wallet: params.wallet },\n ...options,\n });\n }\n}\n","import type { RequestOptions } from '../core/options.js';\nimport type {\n ProductBacktest,\n ProductBacktestChart,\n ProductListItem,\n ProductVersionResponse,\n ProductWithBacktest,\n ProductWithBacktestChart,\n} from '../types/products.js';\nimport type { ChartTimeRange } from '../types/shared.js';\nimport { APIResource } from './resource.js';\n\nexport interface ProductListParams {\n /** Filter by category. */\n category?: string;\n /**\n * Also fetch backtested performance (`GET /products/analytics`) and merge it\n * onto each product as `backtest`. Fails gracefully → `backtest: null`.\n */\n includeBacktest?: boolean;\n}\n\nexport interface ProductGetParams {\n /**\n * Also fetch the product's backtested value chart and attach it as `backtestChart`.\n * Fails gracefully → `backtestChart: null`.\n */\n includeBacktestChart?: boolean;\n /** Chart window when `includeBacktestChart` is true. Default `'1y'`. */\n chartTimeRange?: ChartTimeRange;\n}\n\nconst DEFAULT_CHART_TIME_RANGE: ChartTimeRange = '1y';\n\nexport class Products extends APIResource {\n /** List products. */\n list(): Promise<ProductListItem[]>;\n list(\n params: ProductListParams & { includeBacktest?: false },\n options?: RequestOptions,\n ): Promise<ProductListItem[]>;\n list(\n params: ProductListParams & { includeBacktest: true },\n options?: RequestOptions,\n ): Promise<ProductWithBacktest[]>;\n async list(\n params: ProductListParams = {},\n options?: RequestOptions,\n ): Promise<ProductListItem[] | ProductWithBacktest[]> {\n const query = params.category ? { category: params.category } : undefined;\n\n if (!params.includeBacktest) {\n return this.client.get<ProductListItem[]>('/products', { query, ...options });\n }\n\n const [items, backtests] = await Promise.all([\n this.client.get<ProductListItem[]>('/products', { query, ...options }),\n this.client\n .get<Record<string, ProductBacktest>>('/products/analytics', { query, ...options })\n // Graceful: a failed/slow analytics fetch never breaks the list.\n .catch(() => ({}) as Record<string, ProductBacktest>),\n ]);\n\n return items.map((item) => ({ ...item, backtest: backtests[item.id] ?? null }));\n }\n\n /** Get a product by slug. */\n get(slug: string): Promise<ProductVersionResponse>;\n get(\n slug: string,\n params: ProductGetParams & { includeBacktestChart?: false },\n options?: RequestOptions,\n ): Promise<ProductVersionResponse>;\n get(\n slug: string,\n params: ProductGetParams & { includeBacktestChart: true },\n options?: RequestOptions,\n ): Promise<ProductWithBacktestChart>;\n async get(\n slug: string,\n params: ProductGetParams = {},\n options?: RequestOptions,\n ): Promise<ProductVersionResponse | ProductWithBacktestChart> {\n const product = await this.client.get<ProductVersionResponse>(\n `/products/${encodeURIComponent(slug)}`,\n options,\n );\n\n if (!params.includeBacktestChart) return product;\n\n // Sequential: the chart is keyed by productId, which we only have after the\n // detail fetch resolves the slug. Graceful: a chart failure → null.\n const backtestChart = await this.client\n .get<ProductBacktestChart>(`/products/${encodeURIComponent(product.id)}/graph`, {\n query: { timeRange: params.chartTimeRange ?? DEFAULT_CHART_TIME_RANGE },\n ...options,\n })\n .catch(() => null);\n\n return { ...product, backtestChart };\n }\n}\n","import {\n APIConnectionError,\n APIConnectionTimeoutError,\n APIError,\n APIUserAbortError,\n AuthenticationError,\n BadRequestError,\n CestoError,\n ConflictError,\n InternalServerError,\n NotFoundError,\n PermissionDeniedError,\n RateLimitError,\n UnprocessableEntityError,\n} from './core/errors.js';\nimport { type ClientOptions, resolveOptions } from './core/options.js';\nimport { APIClientCore } from './core/request.js';\nimport { Positions } from './resources/positions.js';\nimport { Products } from './resources/products.js';\n\n/**\n * The Cesto SDK client.\n *\n * @example\n * ```ts\n * const cesto = new Cesto({ apiKey: process.env.CESTO_API_KEY! });\n * const products = await cesto.products.list({ includeBacktest: true });\n * ```\n */\nexport class Cesto {\n readonly products: Products;\n readonly positions: Positions;\n private readonly core: APIClientCore;\n\n constructor(options: ClientOptions = {}) {\n this.core = new APIClientCore(resolveOptions(options));\n this.products = new Products(this.core);\n this.positions = new Positions(this.core);\n }\n\n // Error classes re-exposed for ergonomic `instanceof` checks:\n // catch (e) { if (e instanceof Cesto.NotFoundError) … }\n static readonly CestoError = CestoError;\n static readonly APIError = APIError;\n static readonly BadRequestError = BadRequestError;\n static readonly AuthenticationError = AuthenticationError;\n static readonly PermissionDeniedError = PermissionDeniedError;\n static readonly NotFoundError = NotFoundError;\n static readonly ConflictError = ConflictError;\n static readonly UnprocessableEntityError = UnprocessableEntityError;\n static readonly RateLimitError = RateLimitError;\n static readonly InternalServerError = InternalServerError;\n static readonly APIConnectionError = APIConnectionError;\n static readonly APIConnectionTimeoutError = APIConnectionTimeoutError;\n static readonly APIUserAbortError = APIUserAbortError;\n}\n","import type {\n ChartTimeRange,\n GeoStatus,\n IncentiveOverlayCampaign,\n PredictionMarketState,\n TokenPerformance,\n} from './shared.js';\n\n/** An item in `products.list()` — `GET /products`. */\nexport interface ProductListItem {\n id: string;\n slug: string;\n name: string;\n description: string | null;\n logoUrl: string | null;\n category: string | null;\n tags: string[];\n isActive: boolean;\n isPublished: boolean;\n pointMultiplier: number;\n metadata: Record<string, unknown> | null;\n geoStatus: GeoStatus;\n /** Active incentive campaigns; `[]` when none. */\n incentives: IncentiveOverlayCampaign[];\n}\n\n/** Backtested performance for a product — `GET /products/analytics` (per product). */\nexport interface ProductBacktest {\n protocolsInvolved: string[];\n tokensInvolved: string[];\n tokenPerformance: TokenPerformance | null;\n tokenPerformance7d: TokenPerformance | null;\n tokenPerformance30d: TokenPerformance | null;\n priceChange24h: number | null;\n tokenPriceChanges: Record<\n string,\n { priceChange24h: number | null; priceChange24hPercent: number | null }\n >;\n}\n\n/** `products.list({ includeBacktest: true })` — list item with backtest merged in. */\nexport type ProductWithBacktest = ProductListItem & {\n backtest: ProductBacktest | null;\n};\n\nexport interface ProductCreator {\n id: string;\n username: string | null;\n email: string | null;\n solanaWalletAddress: string | null;\n embeddedWalletAddress: string | null;\n}\n\nexport interface OndoTradingStatus {\n allTradable: boolean;\n currentSession: string;\n hasOndoTokens: boolean;\n tokens: unknown[];\n untradableTokens: unknown[];\n nextFullyTradableAt: string | null;\n nextFullyTradableSession: string | null;\n}\n\n/** Full product detail — `GET /products/:slug`. */\nexport interface ProductVersionResponse {\n id: string;\n versionId: string;\n version: number;\n changelog: string | null;\n minimumInvestment: string;\n inputTokenMint: string;\n inputTokenDecimals: number;\n about: string | null;\n riskNotes: string | null;\n resources: string | null;\n name: string;\n slug: string;\n description: string | null;\n logoUrl: string | null;\n category: string | null;\n tags: string[];\n isActive: boolean;\n isPublished: boolean;\n metadata: Record<string, unknown> | null;\n pointMultiplier: number;\n createdBy: string;\n creator: ProductCreator | null;\n tokensInvolved: string[];\n protocolsInvolved: string[];\n tokenPerformance: TokenPerformance | null;\n tokenPerformance7d: TokenPerformance | null;\n tokenPerformance30d: TokenPerformance | null;\n predictionMarkets?: PredictionMarketState[];\n canInvest: boolean;\n /** Raw workflow definition. */\n definition: unknown;\n geoStatus: GeoStatus;\n ondoTradingStatus: OndoTradingStatus;\n incentives?: IncentiveOverlayCampaign[];\n /**\n * The product's current (canonical) slug. When the request used an old slug\n * that has since been renamed, this differs from the requested slug and\n * `slugRedirect` is true — clients should redirect to the canonical slug.\n */\n canonicalSlug?: string;\n /** True when the requested slug was an old alias that redirects to `canonicalSlug`. */\n slugRedirect?: boolean;\n}\n\nexport interface BacktestChartTimeSeriesPoint {\n timestamp: string;\n portfolioValue: number;\n sp500Value?: number;\n btcValue?: number;\n solValue?: number;\n usdcValue?: number;\n isLiquidated?: boolean;\n liquidationThreshold?: number;\n}\n\nexport interface BacktestChartMetrics {\n totalReturn: number;\n cagr: number;\n volatility: number;\n maxDrawdown: number;\n sharpe: number;\n}\n\nexport interface PredictionMarketEvent {\n ticker: string;\n marketTicker: string;\n seriesTicker: string;\n title: string;\n closeTime: number;\n currentProbability?: number;\n currentPrice: number;\n daysToClose: number;\n timeSeries: Array<{\n market_ticker: string;\n event_ticker: string;\n raw_numerical_forecast: number;\n numerical_forecast: number;\n formatted_forecast: string;\n end_period_ts: number;\n period_interval: number;\n }>;\n}\n\n/** Token-portfolio backtest chart — `GET /products/:id/graph` (non-prediction). */\nexport interface BacktestChart {\n workflowId: string;\n name: string;\n timeRange?: ChartTimeRange;\n timeSeries: BacktestChartTimeSeriesPoint[];\n /** Computed only when `timeRange === '1y'`; null otherwise. */\n metrics: BacktestChartMetrics | null;\n assetPerformance: Array<{ token: string; mint: string; returnPct: number }>;\n contributions: Array<{ token: string; mint: string; contribution: number }>;\n assetSparklines: Array<{\n token: string;\n mint: string;\n points: Array<{ timestamp: string; value: number; price: number }>;\n }>;\n checkpoints?: Array<{\n timestamp: string;\n version: number;\n fromVersion: number | null;\n changelog: string | null;\n added: Array<{ token: string; mint: string; allocation: number }>;\n removed: Array<{ token: string; mint: string; allocation: number }>;\n reweighted: Array<{ token: string; mint: string; fromPct: number; toPct: number }>;\n }>;\n liquidationInfo?: {\n hasLiquidations: boolean;\n liquidationEvents: Array<{\n timestamp: string;\n asset: string;\n liquidationPrice: number;\n actualPrice: number;\n }>;\n liquidationThresholds: Array<{\n asset: string;\n mint: string;\n liquidationPrice: number;\n entryPrice: number;\n leverage: number;\n direction: 'LONG' | 'SHORT';\n }>;\n };\n hasPredictionMarkets?: boolean;\n predictionMarketEvents?: PredictionMarketEvent[];\n incentives?: IncentiveOverlayCampaign[];\n}\n\n/** Prediction-market backtest chart — `GET /products/:id/graph` (prediction). */\nexport interface PredictionMarketChart {\n workflowId: string;\n name: string;\n predictionMarket: boolean;\n markets: PredictionMarketEvent[];\n incentives?: IncentiveOverlayCampaign[];\n}\n\n/** Union returned by the graph endpoint. Discriminate with {@link isPredictionMarketChart}. */\nexport type ProductBacktestChart = BacktestChart | PredictionMarketChart;\n\n/** `products.get(slug, { includeBacktestChart: true })` — detail with chart merged in. */\nexport type ProductWithBacktestChart = ProductVersionResponse & {\n backtestChart: ProductBacktestChart | null;\n};\n\n/** Type guard: is this chart the prediction-market variant? */\nexport function isPredictionMarketChart(\n chart: ProductBacktestChart,\n): chart is PredictionMarketChart {\n return (chart as PredictionMarketChart).predictionMarket === true;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cesto/sdk",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "Typed, server-side TypeScript SDK for the Cesto read-only API.",
5
5
  "type": "module",
6
6
  "license": "MIT",