@getanyapi/sdk 0.21.1 → 0.23.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/dist/index.js CHANGED
@@ -123,23 +123,92 @@ function pageIdempotencyKey(key, pageNumber) {
123
123
 
124
124
  // src/core/account.ts
125
125
  var DEFAULT_BASE_URL = "https://api.getanyapi.com";
126
+ function mapProfile(raw) {
127
+ const profile = {
128
+ id: raw.id,
129
+ status: raw.status,
130
+ createdAt: raw.createdAt,
131
+ onboardingComplete: raw.onboardingComplete
132
+ };
133
+ if (raw.email !== void 0 && raw.email !== null) {
134
+ profile.email = raw.email;
135
+ }
136
+ return profile;
137
+ }
138
+ async function agentSignup(options = {}) {
139
+ const fetchImpl = options.fetch ?? globalThis.fetch;
140
+ if (typeof fetchImpl !== "function") {
141
+ throw new AnyAPIError(
142
+ "no fetch implementation available: pass options.fetch or run on a runtime with global fetch",
143
+ 0
144
+ );
145
+ }
146
+ const base = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
147
+ const body = {};
148
+ if (options.sponsorEmail !== void 0) {
149
+ body["sponsorEmail"] = options.sponsorEmail;
150
+ }
151
+ if (options.label !== void 0) {
152
+ body["label"] = options.label;
153
+ }
154
+ let response;
155
+ try {
156
+ response = await fetchImpl(`${base}/agent/signup`, {
157
+ method: "POST",
158
+ headers: {
159
+ "Content-Type": "application/json",
160
+ Accept: "application/json"
161
+ },
162
+ body: JSON.stringify(body)
163
+ });
164
+ } catch (err) {
165
+ throw new ConnectionError(
166
+ err instanceof Error ? err.message : "connection failed",
167
+ 0
168
+ );
169
+ }
170
+ const requestId = requestIdOf(response.headers);
171
+ const text = await response.text().catch(() => "");
172
+ if (response.status !== 200) {
173
+ let message = `request failed with status ${response.status}`;
174
+ let code;
175
+ try {
176
+ const parsed2 = JSON.parse(text);
177
+ if (typeof parsed2.error === "string" && parsed2.error !== "") {
178
+ message = parsed2.error;
179
+ }
180
+ if (typeof parsed2.code === "string" && parsed2.code !== "") {
181
+ code = parsed2.code;
182
+ }
183
+ } catch {
184
+ }
185
+ throw errorFromStatus(response.status, message, requestId, code);
186
+ }
187
+ const parsed = JSON.parse(text);
188
+ return {
189
+ secret: parsed.secret,
190
+ capUsd: parsed.capUsd,
191
+ claimToken: parsed.claimToken,
192
+ claimUrl: parsed.claimUrl
193
+ };
194
+ }
195
+
196
+ // src/core/discovery-validation.ts
126
197
  function malformed(path) {
127
198
  throw new AnyAPIError(`malformed discovery response: ${path}`, 0);
128
199
  }
129
- function rejectUnsafeDiscoveryFields(value, path) {
200
+ function rejectUnsafeFields(value, path) {
130
201
  if (Array.isArray(value)) {
131
202
  value.forEach(
132
- (item, index) => rejectUnsafeDiscoveryFields(item, `${path}[${index}]`)
203
+ (item, index) => rejectUnsafeFields(item, `${path}[${index}]`)
133
204
  );
134
205
  return;
135
206
  }
136
207
  if (typeof value !== "object" || value === null) return;
137
208
  for (const [key, item] of Object.entries(value)) {
138
209
  if (key.toLowerCase().includes("credit")) malformed(`${path}.${key}`);
139
- if (key === "provider" && item !== "AnyAPI") {
140
- malformed(`${path}.${key}`);
141
- }
142
- rejectUnsafeDiscoveryFields(item, `${path}.${key}`);
210
+ if (key === "provider" && item !== "AnyAPI") malformed(`${path}.${key}`);
211
+ rejectUnsafeFields(item, `${path}.${key}`);
143
212
  }
144
213
  }
145
214
  function record(value, path) {
@@ -150,8 +219,7 @@ function record(value, path) {
150
219
  }
151
220
  function stringField(raw, key, path) {
152
221
  const value = raw[key];
153
- if (typeof value !== "string") return malformed(`${path}.${key}`);
154
- return value;
222
+ return typeof value === "string" ? value : malformed(`${path}.${key}`);
155
223
  }
156
224
  function numberField(raw, key, path) {
157
225
  const value = raw[key];
@@ -162,7 +230,16 @@ function numberField(raw, key, path) {
162
230
  }
163
231
  function integerField(raw, key, path) {
164
232
  const value = numberField(raw, key, path);
165
- if (!Number.isInteger(value)) return malformed(`${path}.${key}`);
233
+ return Number.isInteger(value) ? value : malformed(`${path}.${key}`);
234
+ }
235
+ function methodField(raw, key, path) {
236
+ return stringField(raw, key, path) === "POST" ? "POST" : malformed(`${path}.${key}`);
237
+ }
238
+ function pathField(raw, key, path) {
239
+ const value = stringField(raw, key, path);
240
+ if (value.length < 2 || !value.startsWith("/") || value.startsWith("//")) {
241
+ return malformed(`${path}.${key}`);
242
+ }
166
243
  return value;
167
244
  }
168
245
  function boundedNumberField(raw, key, path, minimumExclusive, maximumInclusive) {
@@ -178,22 +255,17 @@ function parseOffer(value, path) {
178
255
  const unit = stringField(raw, "unit", path);
179
256
  const maxUsd = numberField(raw, "maxUsd", path);
180
257
  if (model === "flat") {
181
- if (unit !== "request") {
182
- return malformed(path);
183
- }
184
- return { model, unit, maxUsd };
185
- }
186
- if (model === "linear") {
187
- if (unit.length === 0) return malformed(`${path}.unit`);
188
- return {
189
- model,
190
- unit,
191
- baseUsd: numberField(raw, "baseUsd", path),
192
- perUnitUsd: numberField(raw, "perUnitUsd", path),
193
- maxUsd
194
- };
258
+ return unit === "request" ? { model, unit, maxUsd } : malformed(path);
195
259
  }
196
- return malformed(`${path}.model`);
260
+ if (model !== "linear") return malformed(`${path}.model`);
261
+ if (unit.length === 0) return malformed(`${path}.unit`);
262
+ return {
263
+ model,
264
+ unit,
265
+ baseUsd: numberField(raw, "baseUsd", path),
266
+ perUnitUsd: numberField(raw, "perUnitUsd", path),
267
+ maxUsd
268
+ };
197
269
  }
198
270
  function parsePricing(value, path) {
199
271
  const raw = record(value, path);
@@ -202,31 +274,64 @@ function parsePricing(value, path) {
202
274
  failoverMaxUsd: numberField(raw, "failoverMaxUsd", path)
203
275
  };
204
276
  }
277
+ function parseExecution(value, path) {
278
+ const raw = record(value, path);
279
+ const mode = stringField(raw, "mode", path);
280
+ return mode === "sync" || mode === "durable" ? { mode } : malformed(`${path}.mode`);
281
+ }
282
+ function parseSource(value, path) {
283
+ const raw = record(value, path);
284
+ const kind = stringField(raw, "kind", path);
285
+ if (kind !== "anonymous" && kind !== "brand")
286
+ return malformed(`${path}.kind`);
287
+ return {
288
+ id: stringField(raw, "id", path),
289
+ name: stringField(raw, "name", path),
290
+ kind,
291
+ artworkKey: stringField(raw, "artworkKey", path)
292
+ };
293
+ }
205
294
  function parseHealth(value, path) {
206
295
  const raw = record(value, path);
207
296
  return {
208
297
  window: stringField(raw, "window", path),
209
298
  uptimePct: boundedNumberField(raw, "uptimePct", path, void 0, 100),
210
299
  latencyP50Ms: integerField(raw, "latencyP50Ms", path),
211
- requests: integerField(raw, "requests", path)
300
+ uptimeSample: integerField(raw, "uptimeSample", path),
301
+ latencySample: integerField(raw, "latencySample", path),
302
+ requests: integerField(raw, "requests", path),
303
+ servedRequests: integerField(raw, "servedRequests", path)
212
304
  };
213
305
  }
214
306
  function parseLane(value, path) {
215
307
  const raw = record(value, path);
216
308
  const lane = {
217
- pricing: parseOffer(raw["pricing"], `${path}.pricing`)
309
+ pricing: parseOffer(raw["pricing"], `${path}.pricing`),
310
+ source: parseSource(raw["source"], `${path}.source`)
218
311
  };
219
- if (raw["health"] !== void 0) {
312
+ if (raw["health"] !== void 0)
220
313
  lane.health = parseHealth(raw["health"], `${path}.health`);
221
- }
222
314
  return lane;
223
315
  }
224
- function parseProvider(raw, path) {
225
- if (raw["provider"] !== "AnyAPI") return malformed(`${path}.provider`);
226
- return "AnyAPI";
316
+ function parseLatency(value, path) {
317
+ const raw = record(value, path);
318
+ const basis = stringField(raw, "basis", path);
319
+ if (basis !== "service_time_excludes_caller_requested_delay") {
320
+ return malformed(`${path}.basis`);
321
+ }
322
+ const sample = integerField(raw, "sample", path);
323
+ if (sample < 1) return malformed(`${path}.sample`);
324
+ return {
325
+ window: stringField(raw, "window", path),
326
+ p50Ms: integerField(raw, "p50Ms", path),
327
+ p95Ms: integerField(raw, "p95Ms", path),
328
+ p99Ms: integerField(raw, "p99Ms", path),
329
+ sample,
330
+ basis
331
+ };
227
332
  }
228
- function parseSchema(value, path) {
229
- return record(value, path);
333
+ function parseProvider(raw, path) {
334
+ return raw["provider"] === "AnyAPI" ? "AnyAPI" : malformed(`${path}.provider`);
230
335
  }
231
336
  function parseHighlight(value, path) {
232
337
  const raw = record(value, path);
@@ -237,31 +342,22 @@ function parseHighlight(value, path) {
237
342
  if (raw["why"] !== void 0) field.why = stringField(raw, "why", path);
238
343
  return field;
239
344
  }
240
- function mapProfile(raw) {
241
- const profile = {
242
- id: raw.id,
243
- status: raw.status,
244
- createdAt: raw.createdAt,
245
- onboardingComplete: raw.onboardingComplete
246
- };
247
- if (raw.email !== void 0 && raw.email !== null) {
248
- profile.email = raw.email;
249
- }
250
- return profile;
251
- }
345
+
346
+ // src/core/discovery.ts
252
347
  function mapCatalogEntry(raw) {
253
- rejectUnsafeDiscoveryFields(raw, "api");
348
+ rejectUnsafeFields(raw, "api");
254
349
  const value = record(raw, "api");
255
350
  const lanesRaw = value["lanes"];
256
- if (!Array.isArray(lanesRaw)) {
257
- return malformed("api.lanes");
258
- }
351
+ if (!Array.isArray(lanesRaw)) return malformed("api.lanes");
259
352
  const entry = {
260
353
  id: stringField(value, "id", "api"),
261
354
  slug: stringField(value, "slug", "api"),
262
355
  category: stringField(value, "category", "api"),
263
356
  name: stringField(value, "name", "api"),
264
357
  description: stringField(value, "description", "api"),
358
+ method: methodField(value, "method", "api"),
359
+ path: pathField(value, "path", "api"),
360
+ execution: parseExecution(value["execution"], "api.execution"),
265
361
  provider: parseProvider(value, "api"),
266
362
  pricing: parsePricing(value["pricing"], "api.pricing"),
267
363
  lanes: lanesRaw.map(
@@ -270,37 +366,42 @@ function mapCatalogEntry(raw) {
270
366
  heavy: value["heavy"] === void 0 ? false : value["heavy"] === true,
271
367
  tryEligible: value["tryEligible"] === true
272
368
  };
273
- if (value["heavy"] !== void 0 && typeof value["heavy"] !== "boolean") {
274
- return malformed("api.heavy");
369
+ if (value["heavy"] !== void 0 && typeof value["heavy"] !== "boolean")
370
+ malformed("api.heavy");
371
+ if (typeof value["tryEligible"] !== "boolean") malformed("api.tryEligible");
372
+ if (value["tryMaxItems"] !== void 0) {
373
+ const tryMaxItems = integerField(value, "tryMaxItems", "api");
374
+ if (tryMaxItems < 1) malformed("api.tryMaxItems");
375
+ entry.tryMaxItems = tryMaxItems;
275
376
  }
276
- if (typeof value["tryEligible"] !== "boolean")
277
- return malformed("api.tryEligible");
278
377
  if (value["failover"] !== void 0) {
279
- if (typeof value["failover"] !== "boolean")
280
- return malformed("api.failover");
378
+ if (typeof value["failover"] !== "boolean") malformed("api.failover");
281
379
  entry.failover = value["failover"];
282
380
  }
283
381
  if (value["excludesCallerDelay"] !== void 0) {
284
382
  if (typeof value["excludesCallerDelay"] !== "boolean")
285
- return malformed("api.excludesCallerDelay");
383
+ malformed("api.excludesCallerDelay");
286
384
  entry.excludesCallerDelay = value["excludesCallerDelay"];
287
385
  }
288
- if (value["inputSchema"] !== void 0) {
289
- entry.inputSchema = parseSchema(value["inputSchema"], "api.inputSchema");
290
- }
291
- if (value["outputSchema"] !== void 0) {
292
- entry.outputSchema = parseSchema(value["outputSchema"], "api.outputSchema");
386
+ if (value["inputSchema"] !== void 0)
387
+ entry.inputSchema = record(value["inputSchema"], "api.inputSchema");
388
+ if (value["outputSchema"] !== void 0)
389
+ entry.outputSchema = record(value["outputSchema"], "api.outputSchema");
390
+ if (value["latency"] !== void 0) {
391
+ entry.latency = value["latency"] === null ? null : parseLatency(value["latency"], "api.latency");
293
392
  }
294
393
  return entry;
295
394
  }
296
395
  function mapCatalogDetail(raw) {
297
396
  const entry = mapCatalogEntry(raw);
397
+ const value = record(raw, "api");
298
398
  if (entry.inputSchema === void 0) return malformed("api.inputSchema");
299
399
  if (entry.outputSchema === void 0) return malformed("api.outputSchema");
400
+ if (!("latency" in value)) return malformed("api.latency");
300
401
  return entry;
301
402
  }
302
403
  function mapCatalogList(raw) {
303
- rejectUnsafeDiscoveryFields(raw, "catalog");
404
+ rejectUnsafeFields(raw, "catalog");
304
405
  const envelope = record(raw, "catalog");
305
406
  if (!Array.isArray(envelope["apis"])) return malformed("catalog.apis");
306
407
  return envelope["apis"].map(mapCatalogEntry);
@@ -313,13 +414,27 @@ function mapSearchResult(value, path) {
313
414
  name: stringField(raw, "name", path),
314
415
  description: stringField(raw, "description", path),
315
416
  category: stringField(raw, "category", path),
417
+ method: methodField(raw, "method", path),
418
+ path: pathField(raw, "path", path),
419
+ execution: parseExecution(raw["execution"], `${path}.execution`),
316
420
  provider: parseProvider(raw, path),
317
421
  pricing: parsePricing(raw["pricing"], `${path}.pricing`),
422
+ failover: typeof raw["failover"] === "boolean" ? raw["failover"] : malformed(`${path}.failover`),
318
423
  relevance: boundedNumberField(raw, "relevance", path, 0, 1)
319
424
  };
425
+ if (raw["tryMaxItems"] !== void 0) {
426
+ const tryMaxItems = integerField(raw, "tryMaxItems", path);
427
+ if (tryMaxItems < 1) malformed(`${path}.tryMaxItems`);
428
+ result.tryMaxItems = tryMaxItems;
429
+ }
430
+ if (raw["excludesCallerDelay"] !== void 0) {
431
+ if (typeof raw["excludesCallerDelay"] !== "boolean")
432
+ malformed(`${path}.excludesCallerDelay`);
433
+ result.excludesCallerDelay = raw["excludesCallerDelay"];
434
+ }
320
435
  if (raw["highlightFields"] !== void 0) {
321
436
  if (!Array.isArray(raw["highlightFields"]))
322
- return malformed(`${path}.highlightFields`);
437
+ malformed(`${path}.highlightFields`);
323
438
  result.highlightFields = raw["highlightFields"].map(
324
439
  (field, index) => parseHighlight(field, `${path}.highlightFields[${index}]`)
325
440
  );
@@ -327,7 +442,7 @@ function mapSearchResult(value, path) {
327
442
  return result;
328
443
  }
329
444
  function mapCatalogSearch(raw) {
330
- rejectUnsafeDiscoveryFields(raw, "search");
445
+ rejectUnsafeFields(raw, "search");
331
446
  const envelope = record(raw, "search");
332
447
  if (!Array.isArray(envelope["results"])) return malformed("search.results");
333
448
  const ranking = envelope["ranking"];
@@ -341,63 +456,6 @@ function mapCatalogSearch(raw) {
341
456
  ranking
342
457
  };
343
458
  }
344
- async function agentSignup(options = {}) {
345
- const fetchImpl = options.fetch ?? globalThis.fetch;
346
- if (typeof fetchImpl !== "function") {
347
- throw new AnyAPIError(
348
- "no fetch implementation available: pass options.fetch or run on a runtime with global fetch",
349
- 0
350
- );
351
- }
352
- const base = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
353
- const body = {};
354
- if (options.sponsorEmail !== void 0) {
355
- body["sponsorEmail"] = options.sponsorEmail;
356
- }
357
- if (options.label !== void 0) {
358
- body["label"] = options.label;
359
- }
360
- let response;
361
- try {
362
- response = await fetchImpl(`${base}/agent/signup`, {
363
- method: "POST",
364
- headers: {
365
- "Content-Type": "application/json",
366
- Accept: "application/json"
367
- },
368
- body: JSON.stringify(body)
369
- });
370
- } catch (err) {
371
- throw new ConnectionError(
372
- err instanceof Error ? err.message : "connection failed",
373
- 0
374
- );
375
- }
376
- const requestId = requestIdOf(response.headers);
377
- const text = await response.text().catch(() => "");
378
- if (response.status !== 200) {
379
- let message = `request failed with status ${response.status}`;
380
- let code;
381
- try {
382
- const parsed2 = JSON.parse(text);
383
- if (typeof parsed2.error === "string" && parsed2.error !== "") {
384
- message = parsed2.error;
385
- }
386
- if (typeof parsed2.code === "string" && parsed2.code !== "") {
387
- code = parsed2.code;
388
- }
389
- } catch {
390
- }
391
- throw errorFromStatus(response.status, message, requestId, code);
392
- }
393
- const parsed = JSON.parse(text);
394
- return {
395
- secret: parsed.secret,
396
- capUsd: parsed.capUsd,
397
- claimToken: parsed.claimToken,
398
- claimUrl: parsed.claimUrl
399
- };
400
- }
401
459
 
402
460
  // src/core/client.ts
403
461
  var DEFAULT_BASE_URL2 = "https://api.getanyapi.com";