@onlist/sdk 0.1.0 → 0.2.0

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
@@ -5,13 +5,13 @@ The official JavaScript/TypeScript SDK for [Onlist](https://onlist.io), the AI A
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
- npm install onlist
8
+ npm install @onlist/sdk
9
9
  ```
10
10
 
11
11
  ## Quick Start
12
12
 
13
13
  ```typescript
14
- import { Onlist } from "onlist";
14
+ import { Onlist } from "@onlist/sdk";
15
15
 
16
16
  const client = new Onlist({ apiKey: "sk-..." });
17
17
 
@@ -35,9 +35,13 @@ The SDK looks for API keys in this order:
35
35
  // Explicit key
36
36
  const client = new Onlist({ apiKey: "sk-..." });
37
37
 
38
- // From environment variable
38
+ // From ONLIST_API_KEY
39
39
  // export ONLIST_API_KEY=sk-...
40
40
  const client = new Onlist();
41
+
42
+ // Falls back to OPENAI_API_KEY if ONLIST_API_KEY is not set
43
+ // export OPENAI_API_KEY=sk-...
44
+ const client = new Onlist();
41
45
  ```
42
46
 
43
47
  ## Provider Routing
@@ -49,7 +53,6 @@ Route requests to specific providers on the Onlist marketplace:
49
53
  const response = await client.chat.completions.create({
50
54
  model: "anthropic/claude-sonnet-4",
51
55
  messages: [{ role: "user", content: "Hello!" }],
52
- // @ts-expect-error -- extra body fields
53
56
  provider: { only: ["alice-shop"] },
54
57
  });
55
58
 
@@ -57,7 +60,6 @@ const response = await client.chat.completions.create({
57
60
  const response = await client.chat.completions.create({
58
61
  model: "openai/gpt-4o",
59
62
  messages: [{ role: "user", content: "Hello!" }],
60
- // @ts-expect-error
61
63
  provider: { sort: "price" },
62
64
  });
63
65
 
@@ -65,7 +67,6 @@ const response = await client.chat.completions.create({
65
67
  const response = await client.chat.completions.create({
66
68
  model: "openai/gpt-4o",
67
69
  messages: [{ role: "user", content: "Hello!" }],
68
- // @ts-expect-error
69
70
  provider: {
70
71
  order: ["alice-shop", "bob-ai"],
71
72
  allow_fallbacks: true,
@@ -119,13 +120,44 @@ for (const provider of providers.items) {
119
120
  const profile = await client.marketplace.providers.get("alice-shop");
120
121
  ```
121
122
 
123
+ ## Rankings API
124
+
125
+ Access model and app usage rankings:
126
+
127
+ ```typescript
128
+ // Model usage leaderboard
129
+ const rankings = await client.marketplace.rankings.models({
130
+ sort: "popular",
131
+ window: "week",
132
+ });
133
+ for (const entry of rankings.leaderboard) {
134
+ console.log(`#${entry.rank} ${entry.model_name} (${entry.total_requests} requests)`);
135
+ }
136
+
137
+ // Trending models
138
+ const trending = await client.marketplace.rankings.models({
139
+ sort: "trending",
140
+ window: "month",
141
+ });
142
+
143
+ // App rankings
144
+ const apps = await client.marketplace.rankings.apps({
145
+ sort: "popular",
146
+ window: "month",
147
+ limit: 10,
148
+ });
149
+ for (const app of apps.apps) {
150
+ console.log(`#${app.rank} ${app.title} (${app.domain})`);
151
+ }
152
+ ```
153
+
122
154
  ## Error Handling
123
155
 
124
156
  OpenAI-compatible calls (`chat.completions`, `embeddings`, etc.) throw standard `openai` errors. Marketplace calls throw `onlist` errors:
125
157
 
126
158
  ```typescript
127
159
  import OpenAI from "openai";
128
- import { AuthenticationError } from "onlist";
160
+ import { AuthenticationError, NotFoundError } from "@onlist/sdk";
129
161
 
130
162
  // OpenAI-compatible endpoints throw openai errors
131
163
  try {
@@ -138,21 +170,35 @@ try {
138
170
 
139
171
  // Marketplace endpoints throw onlist errors
140
172
  try {
141
- await client.marketplace.models.list();
173
+ await client.marketplace.models.get("nonexistent/model");
142
174
  } catch (e) {
175
+ if (e instanceof NotFoundError) {
176
+ console.log("Model not found");
177
+ }
143
178
  if (e instanceof AuthenticationError) {
144
179
  console.log("Invalid API key for marketplace");
145
180
  }
146
181
  }
147
182
  ```
148
183
 
184
+ ## Retry Configuration
185
+
186
+ Marketplace API calls automatically retry on transient failures (408, 429, 5xx) with exponential backoff:
187
+
188
+ ```typescript
189
+ const client = new Onlist({
190
+ apiKey: "sk-...",
191
+ maxRetries: 3, // default: 2
192
+ });
193
+ ```
194
+
149
195
  ## Migration from OpenAI
150
196
 
151
197
  Replace the `openai` import with `onlist`:
152
198
 
153
199
  ```diff
154
200
  - import OpenAI from "openai";
155
- + import { Onlist } from "onlist";
201
+ + import { Onlist } from "@onlist/sdk";
156
202
 
157
203
  - const client = new OpenAI({ apiKey: "sk-..." });
158
204
  + const client = new Onlist({ apiKey: "sk-..." });
@@ -168,7 +214,7 @@ const response = await client.chat.completions.create({
168
214
 
169
215
  ```diff
170
216
  - import OpenAI from "openai";
171
- + import { Onlist } from "onlist";
217
+ + import { Onlist } from "@onlist/sdk";
172
218
 
173
219
  - const client = new OpenAI({
174
220
  - baseURL: "https://openrouter.ai/api/v1",
@@ -188,7 +234,13 @@ const response = await client.chat.completions.create({
188
234
  The SDK is written in TypeScript and ships with full type definitions. All marketplace response types are exported:
189
235
 
190
236
  ```typescript
191
- import type { Model, Provider, ProviderRouting } from "onlist";
237
+ import type {
238
+ Model,
239
+ Provider,
240
+ ProviderRouting,
241
+ ModelRankingsResponse,
242
+ AppRankingsResponse,
243
+ } from "@onlist/sdk";
192
244
  ```
193
245
 
194
246
  ## Links
@@ -198,7 +250,7 @@ import type { Model, Provider, ProviderRouting } from "onlist";
198
250
  - [Model Catalog](https://onlist.io/models)
199
251
  - [Provider Directory](https://onlist.io/providers)
200
252
  - [API Reference](https://onlist.io/docs/api)
201
- - [GitHub](https://github.com/OnlistTeam/onlist-js)
253
+ - [GitHub](https://github.com/OnlistTeam/typescript-sdk)
202
254
  - [Python SDK](https://pypi.org/project/onlist/)
203
255
 
204
256
  ## License
package/dist/index.cjs CHANGED
@@ -36,6 +36,8 @@ __export(index_exports, {
36
36
  Marketplace: () => Marketplace,
37
37
  MarketplaceModels: () => MarketplaceModels,
38
38
  MarketplaceProviders: () => MarketplaceProviders,
39
+ MarketplaceRankings: () => MarketplaceRankings,
40
+ NotFoundError: () => NotFoundError,
39
41
  Onlist: () => Onlist,
40
42
  OnlistError: () => OnlistError,
41
43
  ProviderError: () => ProviderError,
@@ -94,6 +96,12 @@ var ProviderError = class extends APIError {
94
96
  this.name = "ProviderError";
95
97
  }
96
98
  };
99
+ var NotFoundError = class extends APIError {
100
+ constructor(message = "Not found", opts) {
101
+ super(message, { status: 404, ...opts });
102
+ this.name = "NotFoundError";
103
+ }
104
+ };
97
105
  function raiseForStatus(status, body) {
98
106
  let error = {};
99
107
  if (body && typeof body === "object" && "error" in body) {
@@ -109,16 +117,22 @@ function raiseForStatus(status, body) {
109
117
  const opts = { status, type, code, param, body };
110
118
  if (status === 401) throw new AuthenticationError(message, opts);
111
119
  if (status === 402) throw new InsufficientBalanceError(message, opts);
120
+ if (status === 404) throw new NotFoundError(message, opts);
112
121
  if (status === 429) throw new RateLimitError(message, opts);
113
122
  if (code && code.startsWith("no_provider")) throw new ProviderError(message, opts);
114
123
  throw new APIError(message, opts);
115
124
  }
116
125
 
117
126
  // src/version.ts
118
- var VERSION = "0.1.0";
127
+ var VERSION = "0.2.0";
119
128
 
120
129
  // src/marketplace.ts
121
130
  var DEFAULT_TIMEOUT = 3e4;
131
+ var DEFAULT_MAX_RETRIES = 2;
132
+ var INITIAL_RETRY_DELAY = 500;
133
+ var MAX_RETRY_DELAY = 8e3;
134
+ var JITTER_FACTOR = 0.25;
135
+ var RETRYABLE_STATUSES = /* @__PURE__ */ new Set([408, 429, 500, 502, 503, 504]);
122
136
  function encodePath(segment) {
123
137
  return segment.split("/").map((s) => encodeURIComponent(s)).join("/");
124
138
  }
@@ -137,66 +151,109 @@ async function parseResponse(response) {
137
151
  }
138
152
  return body;
139
153
  }
154
+ function retryDelay(attempt, retryAfterHeader) {
155
+ if (retryAfterHeader) {
156
+ const seconds = Number(retryAfterHeader);
157
+ if (!isNaN(seconds) && seconds > 0) {
158
+ return Math.min(seconds * 1e3, MAX_RETRY_DELAY);
159
+ }
160
+ }
161
+ const base = Math.min(INITIAL_RETRY_DELAY * 2 ** attempt, MAX_RETRY_DELAY);
162
+ const jitter = base * JITTER_FACTOR * (2 * Math.random() - 1);
163
+ return Math.max(0, base + jitter);
164
+ }
140
165
  var MarketplaceModels = class {
141
166
  constructor(_opts) {
142
167
  this._opts = _opts;
143
168
  }
144
169
  _opts;
170
+ /** List models in the marketplace catalog. */
145
171
  async list(params) {
146
172
  const search = new URLSearchParams();
147
173
  search.set("limit", String(params?.limit ?? 20));
148
174
  search.set("offset", String(params?.offset ?? 0));
149
175
  if (params?.q) search.set("q", params.q);
150
- const resp = await this._fetch(`/api/mkt/models?${search}`);
176
+ const resp = await fetchWithRetry(this._opts, `/api/mkt/models?${search}`);
151
177
  return await parseResponse(resp);
152
178
  }
179
+ /** Get detailed info for a specific model, including provider offers. */
153
180
  async get(modelId) {
154
- const resp = await this._fetch(`/api/mkt/models/${encodePath(modelId)}`);
181
+ const resp = await fetchWithRetry(this._opts, `/api/mkt/models/${encodePath(modelId)}`);
155
182
  let data = await parseResponse(resp);
156
183
  if (data && typeof data === "object" && "data" in data) {
157
184
  data = data.data;
158
185
  }
159
186
  return data;
160
187
  }
161
- _fetch(path, init) {
162
- return fetchWithOpts(this._opts, path, init);
163
- }
164
188
  };
165
189
  var MarketplaceProviders = class {
166
190
  constructor(_opts) {
167
191
  this._opts = _opts;
168
192
  }
169
193
  _opts;
194
+ /** List providers on the marketplace. */
170
195
  async list(params) {
171
196
  const search = new URLSearchParams();
172
197
  if (params?.sort) search.set("sort", params.sort);
173
198
  if (params?.q) search.set("q", params.q);
174
199
  const qs = search.toString();
175
- const resp = await this._fetch(`/api/mkt/providers${qs ? `?${qs}` : ""}`);
200
+ const resp = await fetchWithRetry(this._opts, `/api/mkt/providers${qs ? `?${qs}` : ""}`);
176
201
  return await parseResponse(resp);
177
202
  }
203
+ /** Get detailed info for a specific provider. */
178
204
  async get(slug) {
179
- const resp = await this._fetch(`/api/mkt/provider/${encodePath(slug)}`);
205
+ const resp = await fetchWithRetry(this._opts, `/api/mkt/provider/${encodePath(slug)}`);
180
206
  let data = await parseResponse(resp);
181
207
  if (data && typeof data === "object" && "data" in data) {
182
208
  data = data.data;
183
209
  }
184
210
  return data;
185
211
  }
186
- _fetch(path, init) {
187
- return fetchWithOpts(this._opts, path, init);
212
+ };
213
+ var MarketplaceRankings = class {
214
+ constructor(_opts) {
215
+ this._opts = _opts;
216
+ }
217
+ _opts;
218
+ /** Get the model usage leaderboard and chart series. */
219
+ async models(params) {
220
+ const search = new URLSearchParams();
221
+ if (params?.sort) search.set("sort", params.sort);
222
+ if (params?.window) search.set("window", params.window);
223
+ if (params?.limit != null) search.set("limit", String(params.limit));
224
+ if (params?.offset != null) search.set("offset", String(params.offset));
225
+ const qs = search.toString();
226
+ const resp = await fetchWithRetry(this._opts, `/api/mkt/rankings/models${qs ? `?${qs}` : ""}`);
227
+ return await parseResponse(resp);
228
+ }
229
+ /** Get the app rankings list. */
230
+ async apps(params) {
231
+ const search = new URLSearchParams();
232
+ if (params?.sort) search.set("sort", params.sort);
233
+ if (params?.window) search.set("window", params.window);
234
+ if (params?.category) search.set("category", params.category);
235
+ if (params?.subcategory) search.set("subcategory", params.subcategory);
236
+ if (params?.page != null) search.set("page", String(params.page));
237
+ if (params?.limit != null) search.set("limit", String(params.limit));
238
+ const qs = search.toString();
239
+ const resp = await fetchWithRetry(this._opts, `/api/mkt/apps${qs ? `?${qs}` : ""}`);
240
+ return await parseResponse(resp);
188
241
  }
189
242
  };
190
243
  var Marketplace = class {
244
+ /** Browse and search models. */
191
245
  models;
246
+ /** Browse and search providers. */
192
247
  providers;
248
+ /** Model and app usage rankings. */
249
+ rankings;
193
250
  constructor(opts) {
194
251
  this.models = new MarketplaceModels(opts);
195
252
  this.providers = new MarketplaceProviders(opts);
253
+ this.rankings = new MarketplaceRankings(opts);
196
254
  }
197
255
  };
198
- function fetchWithOpts(opts, path, init) {
199
- const url = `${opts.baseURL.replace(/\/$/, "")}${path}`;
256
+ function buildFetchInit(opts, init) {
200
257
  const headers = {
201
258
  "User-Agent": `onlist-js/${VERSION}`,
202
259
  Accept: "application/json",
@@ -206,17 +263,39 @@ function fetchWithOpts(opts, path, init) {
206
263
  headers["Authorization"] = `Bearer ${opts.apiKey}`;
207
264
  }
208
265
  const signal = AbortSignal.timeout(opts.timeout ?? DEFAULT_TIMEOUT);
209
- return fetch(url, { ...init, headers, signal });
266
+ return { ...init, headers, signal };
267
+ }
268
+ async function fetchWithRetry(opts, path, init) {
269
+ const url = `${opts.baseURL.replace(/\/$/, "")}${path}`;
270
+ const fetchInit = buildFetchInit(opts, init);
271
+ const maxRetries = opts.maxRetries ?? DEFAULT_MAX_RETRIES;
272
+ let lastError;
273
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
274
+ try {
275
+ const response = await fetch(url, fetchInit);
276
+ if (response.ok || !RETRYABLE_STATUSES.has(response.status) || attempt === maxRetries) {
277
+ return response;
278
+ }
279
+ const delay = retryDelay(attempt, response.headers.get("Retry-After"));
280
+ await new Promise((resolve) => setTimeout(resolve, delay));
281
+ } catch (err) {
282
+ lastError = err;
283
+ if (attempt === maxRetries) break;
284
+ const delay = retryDelay(attempt, null);
285
+ await new Promise((resolve) => setTimeout(resolve, delay));
286
+ }
287
+ }
288
+ throw lastError;
210
289
  }
211
290
 
212
291
  // src/client.ts
213
292
  var BASE_URL = "https://onlist.io/v1";
214
293
  var MARKETPLACE_BASE_URL = "https://onlist.io";
215
- var ENV_API_KEY = "ONLIST_API_KEY";
216
294
  var Onlist = class extends import_openai.default {
295
+ /** Access to marketplace data: models, providers, and rankings. */
217
296
  marketplace;
218
297
  constructor(opts) {
219
- const apiKey = opts?.apiKey ?? (typeof process !== "undefined" ? process.env?.[ENV_API_KEY] : void 0) ?? void 0;
298
+ const apiKey = opts?.apiKey ?? (typeof process !== "undefined" ? process.env?.ONLIST_API_KEY ?? process.env?.OPENAI_API_KEY : void 0) ?? void 0;
220
299
  const baseURL = opts?.baseURL ?? BASE_URL;
221
300
  super({
222
301
  ...opts,
@@ -231,7 +310,8 @@ var Onlist = class extends import_openai.default {
231
310
  const marketplaceBase = String(baseURL).split("/v1")[0] || MARKETPLACE_BASE_URL;
232
311
  this.marketplace = new Marketplace({
233
312
  apiKey: this.apiKey,
234
- baseURL: marketplaceBase
313
+ baseURL: marketplaceBase,
314
+ maxRetries: opts?.maxRetries
235
315
  });
236
316
  }
237
317
  };
@@ -243,6 +323,8 @@ var Onlist = class extends import_openai.default {
243
323
  Marketplace,
244
324
  MarketplaceModels,
245
325
  MarketplaceProviders,
326
+ MarketplaceRankings,
327
+ NotFoundError,
246
328
  Onlist,
247
329
  OnlistError,
248
330
  ProviderError,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/client.ts","../src/errors.ts","../src/version.ts","../src/marketplace.ts"],"sourcesContent":["export { Onlist } from \"./client.js\";\nexport type { OnlistOptions } from \"./client.js\";\n\nexport { Marketplace, MarketplaceModels, MarketplaceProviders } from \"./marketplace.js\";\nexport type { MarketplaceOptions } from \"./marketplace.js\";\n\nexport {\n OnlistError,\n APIError,\n AuthenticationError,\n InsufficientBalanceError,\n RateLimitError,\n ProviderError,\n} from \"./errors.js\";\n\nexport type {\n Pricing,\n Architecture,\n TopProvider,\n Model,\n ProviderOffer,\n ModelDetail,\n ModelListResponse,\n Provider,\n ProviderDetail,\n ProviderListResponse,\n MaxPrice,\n ProviderRouting,\n} from \"./types/index.js\";\n\nexport { VERSION } from \"./version.js\";\n","import OpenAI from \"openai\";\nimport type { ClientOptions } from \"openai\";\nimport { Marketplace } from \"./marketplace.js\";\nimport { VERSION } from \"./version.js\";\n\nconst BASE_URL = \"https://onlist.io/v1\";\nconst MARKETPLACE_BASE_URL = \"https://onlist.io\";\nconst ENV_API_KEY = \"ONLIST_API_KEY\";\n\nexport interface OnlistOptions extends Omit<ClientOptions, \"apiKey\" | \"baseURL\"> {\n apiKey?: string | null;\n baseURL?: string | null;\n}\n\nexport class Onlist extends OpenAI {\n readonly marketplace: Marketplace;\n\n constructor(opts?: OnlistOptions) {\n const apiKey =\n opts?.apiKey ??\n (typeof process !== \"undefined\" ? process.env?.[ENV_API_KEY] : undefined) ??\n undefined;\n\n const baseURL = opts?.baseURL ?? BASE_URL;\n\n super({\n ...opts,\n apiKey: apiKey ?? undefined,\n baseURL,\n defaultHeaders: {\n \"User-Agent\": `onlist-js/${VERSION}`,\n \"HTTP-Referer\": \"https://onlist.io\",\n ...opts?.defaultHeaders,\n },\n });\n\n const marketplaceBase = String(baseURL).split(\"/v1\")[0] || MARKETPLACE_BASE_URL;\n\n this.marketplace = new Marketplace({\n apiKey: this.apiKey,\n baseURL: marketplaceBase,\n });\n }\n}\n","export class OnlistError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"OnlistError\";\n }\n}\n\nexport class APIError extends OnlistError {\n readonly status: number;\n readonly type: string | null;\n readonly code: string | null;\n readonly param: string | null;\n readonly body: unknown;\n\n constructor(\n message: string,\n opts: {\n status: number;\n type?: string | null;\n code?: string | null;\n param?: string | null;\n body?: unknown;\n },\n ) {\n super(message);\n this.name = \"APIError\";\n this.status = opts.status;\n this.type = opts.type ?? null;\n this.code = opts.code ?? null;\n this.param = opts.param ?? null;\n this.body = opts.body ?? null;\n }\n}\n\nexport class AuthenticationError extends APIError {\n constructor(message = \"Invalid API key\", opts?: Partial<ConstructorParameters<typeof APIError>[1]>) {\n super(message, { status: 401, ...opts });\n this.name = \"AuthenticationError\";\n }\n}\n\nexport class InsufficientBalanceError extends APIError {\n constructor(message = \"Insufficient balance\", opts?: Partial<ConstructorParameters<typeof APIError>[1]>) {\n super(message, { status: 402, ...opts });\n this.name = \"InsufficientBalanceError\";\n }\n}\n\nexport class RateLimitError extends APIError {\n constructor(message = \"Rate limited\", opts?: Partial<ConstructorParameters<typeof APIError>[1]>) {\n super(message, { status: 429, ...opts });\n this.name = \"RateLimitError\";\n }\n}\n\nexport class ProviderError extends APIError {\n constructor(message: string, opts: ConstructorParameters<typeof APIError>[1]) {\n super(message, opts);\n this.name = \"ProviderError\";\n }\n}\n\nexport function raiseForStatus(status: number, body: unknown): never {\n let error: Record<string, unknown> = {};\n if (body && typeof body === \"object\" && \"error\" in body) {\n const e = (body as Record<string, unknown>).error;\n error = typeof e === \"object\" && e !== null ? (e as Record<string, unknown>) : {};\n } else if (body && typeof body === \"object\") {\n error = body as Record<string, unknown>;\n }\n\n const message = (typeof error.message === \"string\" ? error.message : String(body)) || \"Unknown error\";\n const type = typeof error.type === \"string\" ? error.type : null;\n const code = typeof error.code === \"string\" ? error.code : null;\n const param = typeof error.param === \"string\" ? error.param : null;\n const opts = { status, type, code, param, body };\n\n if (status === 401) throw new AuthenticationError(message, opts);\n if (status === 402) throw new InsufficientBalanceError(message, opts);\n if (status === 429) throw new RateLimitError(message, opts);\n if (code && code.startsWith(\"no_provider\")) throw new ProviderError(message, opts);\n\n throw new APIError(message, opts);\n}\n","export const VERSION = \"0.1.0\";\n","import { raiseForStatus } from \"./errors.js\";\nimport { VERSION } from \"./version.js\";\nimport type { ModelDetail, ModelListResponse } from \"./types/model.js\";\nimport type { ProviderDetail, ProviderListResponse } from \"./types/provider.js\";\n\nconst DEFAULT_TIMEOUT = 30_000;\n\nfunction encodePath(segment: string): string {\n return segment\n .split(\"/\")\n .map((s) => encodeURIComponent(s))\n .join(\"/\");\n}\n\nasync function parseResponse(response: Response): Promise<unknown> {\n let body: unknown;\n try {\n body = await response.json();\n } catch {\n body = await response.text().catch(() => \"\");\n }\n\n if (!response.ok) {\n raiseForStatus(response.status, body);\n }\n\n if (body && typeof body === \"object\" && \"data\" in body && \"success\" in body) {\n return (body as Record<string, unknown>).data;\n }\n return body;\n}\n\nexport interface MarketplaceOptions {\n apiKey?: string | null;\n baseURL: string;\n timeout?: number;\n}\n\nexport class MarketplaceModels {\n constructor(private readonly _opts: MarketplaceOptions) {}\n\n async list(params?: { limit?: number; offset?: number; q?: string }): Promise<ModelListResponse> {\n const search = new URLSearchParams();\n search.set(\"limit\", String(params?.limit ?? 20));\n search.set(\"offset\", String(params?.offset ?? 0));\n if (params?.q) search.set(\"q\", params.q);\n\n const resp = await this._fetch(`/api/mkt/models?${search}`);\n return (await parseResponse(resp)) as ModelListResponse;\n }\n\n async get(modelId: string): Promise<ModelDetail> {\n const resp = await this._fetch(`/api/mkt/models/${encodePath(modelId)}`);\n let data = (await parseResponse(resp)) as Record<string, unknown>;\n if (data && typeof data === \"object\" && \"data\" in data) {\n data = data.data as Record<string, unknown>;\n }\n return data as unknown as ModelDetail;\n }\n\n private _fetch(path: string, init?: RequestInit): Promise<Response> {\n return fetchWithOpts(this._opts, path, init);\n }\n}\n\nexport class MarketplaceProviders {\n constructor(private readonly _opts: MarketplaceOptions) {}\n\n async list(params?: { sort?: string; q?: string }): Promise<ProviderListResponse> {\n const search = new URLSearchParams();\n if (params?.sort) search.set(\"sort\", params.sort);\n if (params?.q) search.set(\"q\", params.q);\n\n const qs = search.toString();\n const resp = await this._fetch(`/api/mkt/providers${qs ? `?${qs}` : \"\"}`);\n return (await parseResponse(resp)) as ProviderListResponse;\n }\n\n async get(slug: string): Promise<ProviderDetail> {\n const resp = await this._fetch(`/api/mkt/provider/${encodePath(slug)}`);\n let data = (await parseResponse(resp)) as Record<string, unknown>;\n if (data && typeof data === \"object\" && \"data\" in data) {\n data = data.data as Record<string, unknown>;\n }\n return data as unknown as ProviderDetail;\n }\n\n private _fetch(path: string, init?: RequestInit): Promise<Response> {\n return fetchWithOpts(this._opts, path, init);\n }\n}\n\nexport class Marketplace {\n readonly models: MarketplaceModels;\n readonly providers: MarketplaceProviders;\n\n constructor(opts: MarketplaceOptions) {\n this.models = new MarketplaceModels(opts);\n this.providers = new MarketplaceProviders(opts);\n }\n}\n\nfunction fetchWithOpts(opts: MarketplaceOptions, path: string, init?: RequestInit): Promise<Response> {\n const url = `${opts.baseURL.replace(/\\/$/, \"\")}${path}`;\n const headers: Record<string, string> = {\n \"User-Agent\": `onlist-js/${VERSION}`,\n Accept: \"application/json\",\n ...(init?.headers as Record<string, string>),\n };\n if (opts.apiKey) {\n headers[\"Authorization\"] = `Bearer ${opts.apiKey}`;\n }\n const signal = AbortSignal.timeout(opts.timeout ?? DEFAULT_TIMEOUT);\n return fetch(url, { ...init, headers, signal });\n}\n"],"mappings":"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","names":["OpenAI"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/client.ts","../src/errors.ts","../src/version.ts","../src/marketplace.ts"],"sourcesContent":["export { Onlist } from \"./client.js\";\nexport type { OnlistOptions } from \"./client.js\";\n\nexport { Marketplace, MarketplaceModels, MarketplaceProviders, MarketplaceRankings } from \"./marketplace.js\";\nexport type { MarketplaceOptions } from \"./marketplace.js\";\n\nexport {\n OnlistError,\n APIError,\n AuthenticationError,\n InsufficientBalanceError,\n NotFoundError,\n RateLimitError,\n ProviderError,\n} from \"./errors.js\";\n\nexport type {\n Pricing,\n Architecture,\n TopProvider,\n Model,\n ProviderOffer,\n ModelDetail,\n ModelListResponse,\n Provider,\n ProviderDetail,\n ProviderListResponse,\n MaxPrice,\n ProviderRouting,\n ModelRanking,\n ModelSeriesPoint,\n ModelRankingsResponse,\n ModelRankingsParams,\n AppRanking,\n AppRankingsResponse,\n AppRankingsParams,\n} from \"./types/index.js\";\n\nexport { VERSION } from \"./version.js\";\n","import OpenAI from \"openai\";\nimport type { ClientOptions } from \"openai\";\nimport { Marketplace } from \"./marketplace.js\";\nimport { VERSION } from \"./version.js\";\n\nconst BASE_URL = \"https://onlist.io/v1\";\nconst MARKETPLACE_BASE_URL = \"https://onlist.io\";\n\n/** Options for creating an Onlist client. */\nexport interface OnlistOptions extends Omit<ClientOptions, \"apiKey\" | \"baseURL\"> {\n /** API key. Falls back to ONLIST_API_KEY then OPENAI_API_KEY env vars. */\n apiKey?: string | null;\n /** Base URL for the API. Defaults to https://onlist.io/v1. */\n baseURL?: string | null;\n /** Maximum retry attempts for marketplace API calls. Defaults to 2. */\n maxRetries?: number;\n}\n\n/** Onlist API client, extending the OpenAI SDK with marketplace features. */\nexport class Onlist extends OpenAI {\n /** Access to marketplace data: models, providers, and rankings. */\n readonly marketplace: Marketplace;\n\n constructor(opts?: OnlistOptions) {\n const apiKey =\n opts?.apiKey ??\n (typeof process !== \"undefined\"\n ? process.env?.ONLIST_API_KEY ?? process.env?.OPENAI_API_KEY\n : undefined) ??\n undefined;\n\n const baseURL = opts?.baseURL ?? BASE_URL;\n\n super({\n ...opts,\n apiKey: apiKey ?? undefined,\n baseURL,\n defaultHeaders: {\n \"User-Agent\": `onlist-js/${VERSION}`,\n \"HTTP-Referer\": \"https://onlist.io\",\n ...opts?.defaultHeaders,\n },\n });\n\n const marketplaceBase = String(baseURL).split(\"/v1\")[0] || MARKETPLACE_BASE_URL;\n\n this.marketplace = new Marketplace({\n apiKey: this.apiKey,\n baseURL: marketplaceBase,\n maxRetries: opts?.maxRetries,\n });\n }\n}\n","/** Base error class for all Onlist SDK errors. */\nexport class OnlistError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"OnlistError\";\n }\n}\n\n/** Error thrown when an API request fails. */\nexport class APIError extends OnlistError {\n readonly status: number;\n readonly type: string | null;\n readonly code: string | null;\n readonly param: string | null;\n readonly body: unknown;\n\n constructor(\n message: string,\n opts: {\n status: number;\n type?: string | null;\n code?: string | null;\n param?: string | null;\n body?: unknown;\n },\n ) {\n super(message);\n this.name = \"APIError\";\n this.status = opts.status;\n this.type = opts.type ?? null;\n this.code = opts.code ?? null;\n this.param = opts.param ?? null;\n this.body = opts.body ?? null;\n }\n}\n\n/** Error thrown when the API key is invalid or missing. */\nexport class AuthenticationError extends APIError {\n constructor(message = \"Invalid API key\", opts?: Partial<ConstructorParameters<typeof APIError>[1]>) {\n super(message, { status: 401, ...opts });\n this.name = \"AuthenticationError\";\n }\n}\n\n/** Error thrown when the account balance is insufficient. */\nexport class InsufficientBalanceError extends APIError {\n constructor(message = \"Insufficient balance\", opts?: Partial<ConstructorParameters<typeof APIError>[1]>) {\n super(message, { status: 402, ...opts });\n this.name = \"InsufficientBalanceError\";\n }\n}\n\n/** Error thrown when the request is rate-limited. */\nexport class RateLimitError extends APIError {\n constructor(message = \"Rate limited\", opts?: Partial<ConstructorParameters<typeof APIError>[1]>) {\n super(message, { status: 429, ...opts });\n this.name = \"RateLimitError\";\n }\n}\n\n/** Error thrown when no matching provider is available. */\nexport class ProviderError extends APIError {\n constructor(message: string, opts: ConstructorParameters<typeof APIError>[1]) {\n super(message, opts);\n this.name = \"ProviderError\";\n }\n}\n\n/** Error thrown when a requested resource is not found. */\nexport class NotFoundError extends APIError {\n constructor(message = \"Not found\", opts?: Partial<ConstructorParameters<typeof APIError>[1]>) {\n super(message, { status: 404, ...opts });\n this.name = \"NotFoundError\";\n }\n}\n\nexport function raiseForStatus(status: number, body: unknown): never {\n let error: Record<string, unknown> = {};\n if (body && typeof body === \"object\" && \"error\" in body) {\n const e = (body as Record<string, unknown>).error;\n error = typeof e === \"object\" && e !== null ? (e as Record<string, unknown>) : {};\n } else if (body && typeof body === \"object\") {\n error = body as Record<string, unknown>;\n }\n\n const message = (typeof error.message === \"string\" ? error.message : String(body)) || \"Unknown error\";\n const type = typeof error.type === \"string\" ? error.type : null;\n const code = typeof error.code === \"string\" ? error.code : null;\n const param = typeof error.param === \"string\" ? error.param : null;\n const opts = { status, type, code, param, body };\n\n if (status === 401) throw new AuthenticationError(message, opts);\n if (status === 402) throw new InsufficientBalanceError(message, opts);\n if (status === 404) throw new NotFoundError(message, opts);\n if (status === 429) throw new RateLimitError(message, opts);\n if (code && code.startsWith(\"no_provider\")) throw new ProviderError(message, opts);\n\n throw new APIError(message, opts);\n}\n","export const VERSION = \"0.2.0\";\n","import { raiseForStatus } from \"./errors.js\";\nimport { VERSION } from \"./version.js\";\nimport type { ModelDetail, ModelListResponse } from \"./types/model.js\";\nimport type { ProviderDetail, ProviderListResponse } from \"./types/provider.js\";\nimport type {\n ModelRankingsResponse,\n ModelRankingsParams,\n AppRankingsResponse,\n AppRankingsParams,\n} from \"./types/rankings.js\";\n\nconst DEFAULT_TIMEOUT = 30_000;\nconst DEFAULT_MAX_RETRIES = 2;\nconst INITIAL_RETRY_DELAY = 500;\nconst MAX_RETRY_DELAY = 8_000;\nconst JITTER_FACTOR = 0.25;\n\n/** Retryable status codes: timeouts, rate limits, and server errors. */\nconst RETRYABLE_STATUSES = new Set([408, 429, 500, 502, 503, 504]);\n\nfunction encodePath(segment: string): string {\n return segment\n .split(\"/\")\n .map((s) => encodeURIComponent(s))\n .join(\"/\");\n}\n\nasync function parseResponse(response: Response): Promise<unknown> {\n let body: unknown;\n try {\n body = await response.json();\n } catch {\n body = await response.text().catch(() => \"\");\n }\n\n if (!response.ok) {\n raiseForStatus(response.status, body);\n }\n\n if (body && typeof body === \"object\" && \"data\" in body && \"success\" in body) {\n return (body as Record<string, unknown>).data;\n }\n return body;\n}\n\n/** Calculates the retry delay with exponential backoff and jitter. */\nfunction retryDelay(attempt: number, retryAfterHeader: string | null): number {\n if (retryAfterHeader) {\n const seconds = Number(retryAfterHeader);\n if (!isNaN(seconds) && seconds > 0) {\n return Math.min(seconds * 1000, MAX_RETRY_DELAY);\n }\n }\n const base = Math.min(INITIAL_RETRY_DELAY * 2 ** attempt, MAX_RETRY_DELAY);\n const jitter = base * JITTER_FACTOR * (2 * Math.random() - 1);\n return Math.max(0, base + jitter);\n}\n\n/** Options for creating a Marketplace client. */\nexport interface MarketplaceOptions {\n apiKey?: string | null;\n baseURL: string;\n timeout?: number;\n /** Maximum retry attempts for failed requests. Defaults to 2. */\n maxRetries?: number;\n}\n\n/** Access to marketplace model data. */\nexport class MarketplaceModels {\n constructor(private readonly _opts: MarketplaceOptions) {}\n\n /** List models in the marketplace catalog. */\n async list(params?: { limit?: number; offset?: number; q?: string }): Promise<ModelListResponse> {\n const search = new URLSearchParams();\n search.set(\"limit\", String(params?.limit ?? 20));\n search.set(\"offset\", String(params?.offset ?? 0));\n if (params?.q) search.set(\"q\", params.q);\n\n const resp = await fetchWithRetry(this._opts, `/api/mkt/models?${search}`);\n return (await parseResponse(resp)) as ModelListResponse;\n }\n\n /** Get detailed info for a specific model, including provider offers. */\n async get(modelId: string): Promise<ModelDetail> {\n const resp = await fetchWithRetry(this._opts, `/api/mkt/models/${encodePath(modelId)}`);\n let data = (await parseResponse(resp)) as Record<string, unknown>;\n if (data && typeof data === \"object\" && \"data\" in data) {\n data = data.data as Record<string, unknown>;\n }\n return data as unknown as ModelDetail;\n }\n}\n\n/** Access to marketplace provider data. */\nexport class MarketplaceProviders {\n constructor(private readonly _opts: MarketplaceOptions) {}\n\n /** List providers on the marketplace. */\n async list(params?: { sort?: string; q?: string }): Promise<ProviderListResponse> {\n const search = new URLSearchParams();\n if (params?.sort) search.set(\"sort\", params.sort);\n if (params?.q) search.set(\"q\", params.q);\n\n const qs = search.toString();\n const resp = await fetchWithRetry(this._opts, `/api/mkt/providers${qs ? `?${qs}` : \"\"}`);\n return (await parseResponse(resp)) as ProviderListResponse;\n }\n\n /** Get detailed info for a specific provider. */\n async get(slug: string): Promise<ProviderDetail> {\n const resp = await fetchWithRetry(this._opts, `/api/mkt/provider/${encodePath(slug)}`);\n let data = (await parseResponse(resp)) as Record<string, unknown>;\n if (data && typeof data === \"object\" && \"data\" in data) {\n data = data.data as Record<string, unknown>;\n }\n return data as unknown as ProviderDetail;\n }\n}\n\n/** Access to marketplace rankings (models and apps). */\nexport class MarketplaceRankings {\n constructor(private readonly _opts: MarketplaceOptions) {}\n\n /** Get the model usage leaderboard and chart series. */\n async models(params?: ModelRankingsParams): Promise<ModelRankingsResponse> {\n const search = new URLSearchParams();\n if (params?.sort) search.set(\"sort\", params.sort);\n if (params?.window) search.set(\"window\", params.window);\n if (params?.limit != null) search.set(\"limit\", String(params.limit));\n if (params?.offset != null) search.set(\"offset\", String(params.offset));\n\n const qs = search.toString();\n const resp = await fetchWithRetry(this._opts, `/api/mkt/rankings/models${qs ? `?${qs}` : \"\"}`);\n return (await parseResponse(resp)) as ModelRankingsResponse;\n }\n\n /** Get the app rankings list. */\n async apps(params?: AppRankingsParams): Promise<AppRankingsResponse> {\n const search = new URLSearchParams();\n if (params?.sort) search.set(\"sort\", params.sort);\n if (params?.window) search.set(\"window\", params.window);\n if (params?.category) search.set(\"category\", params.category);\n if (params?.subcategory) search.set(\"subcategory\", params.subcategory);\n if (params?.page != null) search.set(\"page\", String(params.page));\n if (params?.limit != null) search.set(\"limit\", String(params.limit));\n\n const qs = search.toString();\n const resp = await fetchWithRetry(this._opts, `/api/mkt/apps${qs ? `?${qs}` : \"\"}`);\n return (await parseResponse(resp)) as AppRankingsResponse;\n }\n}\n\n/** Client for the Onlist marketplace public API. */\nexport class Marketplace {\n /** Browse and search models. */\n readonly models: MarketplaceModels;\n /** Browse and search providers. */\n readonly providers: MarketplaceProviders;\n /** Model and app usage rankings. */\n readonly rankings: MarketplaceRankings;\n\n constructor(opts: MarketplaceOptions) {\n this.models = new MarketplaceModels(opts);\n this.providers = new MarketplaceProviders(opts);\n this.rankings = new MarketplaceRankings(opts);\n }\n}\n\nfunction buildFetchInit(opts: MarketplaceOptions, init?: RequestInit): RequestInit {\n const headers: Record<string, string> = {\n \"User-Agent\": `onlist-js/${VERSION}`,\n Accept: \"application/json\",\n ...(init?.headers as Record<string, string>),\n };\n if (opts.apiKey) {\n headers[\"Authorization\"] = `Bearer ${opts.apiKey}`;\n }\n const signal = AbortSignal.timeout(opts.timeout ?? DEFAULT_TIMEOUT);\n return { ...init, headers, signal };\n}\n\nasync function fetchWithRetry(\n opts: MarketplaceOptions,\n path: string,\n init?: RequestInit,\n): Promise<Response> {\n const url = `${opts.baseURL.replace(/\\/$/, \"\")}${path}`;\n const fetchInit = buildFetchInit(opts, init);\n const maxRetries = opts.maxRetries ?? DEFAULT_MAX_RETRIES;\n\n let lastError: unknown;\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n const response = await fetch(url, fetchInit);\n if (response.ok || !RETRYABLE_STATUSES.has(response.status) || attempt === maxRetries) {\n return response;\n }\n const delay = retryDelay(attempt, response.headers.get(\"Retry-After\"));\n await new Promise((resolve) => setTimeout(resolve, delay));\n } catch (err) {\n lastError = err;\n if (attempt === maxRetries) break;\n const delay = retryDelay(attempt, null);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n throw lastError;\n}\n"],"mappings":"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","names":["OpenAI"]}