@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 +2 -2
- package/dist/index.js +129 -48
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +129 -48
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/runtime/transport.ts +148 -51
package/README.md
CHANGED
|
@@ -113,8 +113,8 @@ try {
|
|
|
113
113
|
```typescript
|
|
114
114
|
const client = new AceDataCloud({
|
|
115
115
|
apiToken: 'your-token',
|
|
116
|
-
|
|
117
|
-
|
|
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://
|
|
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
|
-
|
|
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
|
|
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:
|
|
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
|
-
|
|
261
|
-
|
|
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
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
const
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
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
|
-
|
|
286
|
-
|
|
287
|
-
|
|
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
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
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
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
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();
|