@acedatacloud/sdk 2026.716.1 → 2026.718.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
@@ -113,8 +113,8 @@ try {
113
113
  ```typescript
114
114
  const client = new AceDataCloud({
115
115
  apiToken: 'your-token',
116
- baseUrl: 'https://api.acedata.cloud',
117
- platformBaseUrl: 'https://platform.acedata.cloud',
116
+ baseURL: 'https://x402.acedata.cloud',
117
+ platformBaseURL: 'https://platform.acedata.cloud',
118
118
  timeout: 300000, // ms
119
119
  maxRetries: 2,
120
120
  });
package/dist/index.js CHANGED
@@ -163,6 +163,16 @@ function backoffDelay(attempt) {
163
163
  function sleep(ms) {
164
164
  return new Promise((resolve) => setTimeout(resolve, ms));
165
165
  }
166
+ function isAbortError(error) {
167
+ return typeof error === "object" && error !== null && "name" in error && error.name === "AbortError";
168
+ }
169
+ function timeoutError(error) {
170
+ return new TimeoutError({
171
+ message: `Request timed out${error instanceof Error && error.message ? `: ${error.message}` : ""}`,
172
+ statusCode: 0,
173
+ code: "timeout"
174
+ });
175
+ }
166
176
  var Transport = class {
167
177
  baseURL;
168
178
  platformBaseURL;
@@ -179,7 +189,7 @@ var Transport = class {
179
189
  code: "no_token"
180
190
  });
181
191
  }
182
- this.baseURL = (opts.baseURL ?? "https://api.acedata.cloud").replace(/\/+$/, "");
192
+ this.baseURL = (opts.baseURL ?? "https://x402.acedata.cloud").replace(/\/+$/, "");
183
193
  this.platformBaseURL = (opts.platformBaseURL ?? "https://platform.acedata.cloud").replace(/\/+$/, "");
184
194
  this.timeout = opts.timeout ?? 3e5;
185
195
  this.maxRetries = opts.maxRetries ?? 2;
@@ -207,7 +217,8 @@ var Transport = class {
207
217
  let lastError = null;
208
218
  let paymentAttempted = false;
209
219
  let extraHeaders = {};
210
- for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
220
+ let attempt = 0;
221
+ while (true) {
211
222
  const controller = new AbortController();
212
223
  const timer = setTimeout(() => controller.abort(), timeoutMs);
213
224
  try {
@@ -226,14 +237,17 @@ var Transport = class {
226
237
  } catch {
227
238
  throw mapError(402, { error: { code: "invalid_402", message: text } });
228
239
  }
229
- if (!body.accepts?.length) {
240
+ if (!body || typeof body !== "object" || !Array.isArray(body.accepts) || !body.accepts.length || !body.accepts.every(
241
+ (requirement) => requirement !== null && typeof requirement === "object"
242
+ )) {
230
243
  throw mapError(402, { error: { code: "invalid_402", message: "No payment requirements" } });
231
244
  }
245
+ const paymentRequired = body;
232
246
  const result = await this.paymentHandler({
233
247
  url,
234
248
  method,
235
249
  body: opts.json,
236
- accepts: body.accepts
250
+ accepts: paymentRequired.accepts
237
251
  });
238
252
  extraHeaders = { ...extraHeaders, ...result.headers };
239
253
  paymentAttempted = true;
@@ -247,8 +261,9 @@ var Transport = class {
247
261
  } catch {
248
262
  body = { error: { code: "unknown", message: text } };
249
263
  }
250
- if (RETRY_STATUS_CODES.has(resp.status) && attempt < this.maxRetries) {
264
+ if (!paymentAttempted && RETRY_STATUS_CODES.has(resp.status) && attempt < this.maxRetries) {
251
265
  await sleep(backoffDelay(attempt) * 1e3);
266
+ attempt += 1;
252
267
  continue;
253
268
  }
254
269
  throw mapError(resp.status, body);
@@ -257,57 +272,117 @@ var Transport = class {
257
272
  } catch (err) {
258
273
  clearTimeout(timer);
259
274
  if (err instanceof APIError) throw err;
260
- lastError = err;
261
- if (attempt < this.maxRetries) {
275
+ if (isAbortError(err)) {
276
+ lastError = timeoutError(err);
277
+ } else {
278
+ lastError = err;
279
+ }
280
+ if (!paymentAttempted && attempt < this.maxRetries) {
262
281
  await sleep(backoffDelay(attempt) * 1e3);
282
+ attempt += 1;
263
283
  continue;
264
284
  }
285
+ throw lastError;
265
286
  }
266
287
  }
267
- throw lastError ?? new TransportError("Request failed after retries");
268
288
  }
269
289
  async *requestStream(method, path2, opts = {}) {
270
290
  const url = `${this.baseURL}${path2}`;
271
291
  const headers = { ...this.headers, accept: "text/event-stream" };
272
- const controller = new AbortController();
273
- const timer = setTimeout(() => controller.abort(), opts.timeout ?? this.timeout);
274
- try {
275
- const resp = await fetch(url, {
276
- method,
277
- headers,
278
- body: opts.json ? JSON.stringify(opts.json) : void 0,
279
- signal: controller.signal
280
- });
281
- if (resp.status >= 400) {
282
- const text = await resp.text();
283
- let body;
292
+ let paymentAttempted = false;
293
+ let extraHeaders = {};
294
+ while (true) {
295
+ const controller = new AbortController();
296
+ const timeoutMs = opts.timeout ?? this.timeout;
297
+ const connectionTimer = setTimeout(() => controller.abort(), timeoutMs);
298
+ try {
299
+ let resp;
284
300
  try {
285
- body = JSON.parse(text);
286
- } catch {
287
- body = { error: { code: "unknown", message: text } };
301
+ resp = await fetch(url, {
302
+ method,
303
+ headers: { ...headers, ...extraHeaders },
304
+ body: opts.json ? JSON.stringify(opts.json) : void 0,
305
+ signal: controller.signal
306
+ });
307
+ } catch (error) {
308
+ if (isAbortError(error)) throw timeoutError(error);
309
+ throw error;
310
+ } finally {
311
+ clearTimeout(connectionTimer);
288
312
  }
289
- throw mapError(resp.status, body);
290
- }
291
- if (!resp.body) throw new TransportError("No response body for stream");
292
- const reader = resp.body.getReader();
293
- const decoder = new TextDecoder();
294
- let buffer = "";
295
- while (true) {
296
- const { done, value } = await reader.read();
297
- if (done) break;
298
- buffer += decoder.decode(value, { stream: true });
299
- const lines = buffer.split("\n");
300
- buffer = lines.pop() ?? "";
301
- for (const line of lines) {
302
- if (line.startsWith("data: ")) {
303
- const data = line.slice(6);
304
- if (data === "[DONE]") return;
305
- yield data;
313
+ if (resp.status === 402 && this.paymentHandler && !paymentAttempted) {
314
+ const text = await resp.text();
315
+ let body;
316
+ try {
317
+ body = JSON.parse(text);
318
+ } catch {
319
+ throw mapError(402, { error: { code: "invalid_402", message: text } });
320
+ }
321
+ if (!body || typeof body !== "object" || !Array.isArray(body.accepts) || !body.accepts.length || !body.accepts.every(
322
+ (requirement) => requirement !== null && typeof requirement === "object"
323
+ )) {
324
+ throw mapError(402, { error: { code: "invalid_402", message: "No payment requirements" } });
325
+ }
326
+ const paymentRequired = body;
327
+ const result = await this.paymentHandler({
328
+ url,
329
+ method,
330
+ body: opts.json,
331
+ accepts: paymentRequired.accepts
332
+ });
333
+ extraHeaders = { ...extraHeaders, ...result.headers };
334
+ paymentAttempted = true;
335
+ continue;
336
+ }
337
+ if (resp.status >= 400) {
338
+ const text = await resp.text();
339
+ let body;
340
+ try {
341
+ body = JSON.parse(text);
342
+ } catch {
343
+ body = { error: { code: "unknown", message: text } };
344
+ }
345
+ throw mapError(resp.status, body);
346
+ }
347
+ if (!resp.body) throw new TransportError("No response body for stream");
348
+ const reader = resp.body.getReader();
349
+ const decoder = new TextDecoder();
350
+ let buffer = "";
351
+ try {
352
+ while (true) {
353
+ const idleTimer = setTimeout(() => controller.abort(), timeoutMs);
354
+ let result;
355
+ try {
356
+ result = await reader.read();
357
+ } catch (error) {
358
+ if (isAbortError(error)) throw timeoutError(error);
359
+ throw error;
360
+ } finally {
361
+ clearTimeout(idleTimer);
362
+ }
363
+ const { done, value } = result;
364
+ if (done) break;
365
+ buffer += decoder.decode(value, { stream: true });
366
+ const lines = buffer.split("\n");
367
+ buffer = lines.pop() ?? "";
368
+ for (const line of lines) {
369
+ if (line.startsWith("data: ")) {
370
+ const data = line.slice(6);
371
+ if (data === "[DONE]") return;
372
+ yield data;
373
+ }
374
+ }
375
+ }
376
+ } finally {
377
+ try {
378
+ await reader.cancel();
379
+ } catch {
306
380
  }
307
381
  }
382
+ return;
383
+ } finally {
384
+ clearTimeout(connectionTimer);
308
385
  }
309
- } finally {
310
- clearTimeout(timer);
311
386
  }
312
387
  }
313
388
  async upload(path2, fileData, filename, opts = {}) {
@@ -327,12 +402,18 @@ var Transport = class {
327
402
  const controller = new AbortController();
328
403
  const timer = setTimeout(() => controller.abort(), opts.timeout ?? this.timeout);
329
404
  try {
330
- const resp = await fetch(url, {
331
- method: "POST",
332
- headers: authHeaders,
333
- body,
334
- signal: controller.signal
335
- });
405
+ let resp;
406
+ try {
407
+ resp = await fetch(url, {
408
+ method: "POST",
409
+ headers: authHeaders,
410
+ body,
411
+ signal: controller.signal
412
+ });
413
+ } catch (error) {
414
+ if (isAbortError(error)) throw timeoutError(error);
415
+ throw error;
416
+ }
336
417
  clearTimeout(timer);
337
418
  if (resp.status >= 400) {
338
419
  const text = await resp.text();