@proveanything/smartlinks 1.8.1 → 1.8.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/dist/api/ai.js +3 -99
- package/dist/docs/API_SUMMARY.md +41 -1
- package/dist/docs/iframe-streaming-parent-changes.md +308 -0
- package/dist/http.d.ts +9 -0
- package/dist/http.js +236 -0
- package/dist/iframeResponder.d.ts +4 -0
- package/dist/iframeResponder.js +152 -0
- package/dist/openapi.yaml +63 -0
- package/dist/types/iframeResponder.d.ts +20 -0
- package/docs/API_SUMMARY.md +41 -1
- package/docs/iframe-streaming-parent-changes.md +308 -0
- package/openapi.yaml +63 -0
- package/package.json +1 -1
package/dist/http.js
CHANGED
|
@@ -13,6 +13,18 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
13
13
|
}
|
|
14
14
|
return t;
|
|
15
15
|
};
|
|
16
|
+
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
|
|
17
|
+
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
|
|
18
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
19
|
+
var g = generator.apply(thisArg, _arguments || []), i, q = [];
|
|
20
|
+
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
|
|
21
|
+
function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
|
|
22
|
+
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
|
|
23
|
+
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
|
|
24
|
+
function fulfill(value) { resume("next", value); }
|
|
25
|
+
function reject(value) { resume("throw", value); }
|
|
26
|
+
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
|
|
27
|
+
};
|
|
16
28
|
import { SmartlinksApiError, SmartlinksOfflineError } from "./types/error";
|
|
17
29
|
import { idbGet, idbSet, idbClear } from './persistentCache';
|
|
18
30
|
let baseURL = null;
|
|
@@ -514,15 +526,178 @@ export function invalidateCache(urlPattern) {
|
|
|
514
526
|
}
|
|
515
527
|
// Map of pending proxy requests: id -> {resolve, reject}
|
|
516
528
|
const proxyPending = {};
|
|
529
|
+
const proxyStreamPending = new Map();
|
|
517
530
|
function generateProxyId() {
|
|
518
531
|
return "proxy_" + Math.random().toString(36).slice(2) + Date.now();
|
|
519
532
|
}
|
|
533
|
+
async function createFetchError(response, url) {
|
|
534
|
+
let responseBody;
|
|
535
|
+
try {
|
|
536
|
+
responseBody = await response.json();
|
|
537
|
+
}
|
|
538
|
+
catch (_a) {
|
|
539
|
+
responseBody = null;
|
|
540
|
+
}
|
|
541
|
+
const errBody = normalizeErrorResponse(responseBody, response.status);
|
|
542
|
+
return new SmartlinksApiError(`Error ${errBody.code}: ${errBody.message}`, response.status, errBody, url);
|
|
543
|
+
}
|
|
544
|
+
function createProxyStreamIterable(id) {
|
|
545
|
+
const queue = [];
|
|
546
|
+
const waiters = [];
|
|
547
|
+
let done = false;
|
|
548
|
+
let failure = null;
|
|
549
|
+
const flushDone = () => {
|
|
550
|
+
while (waiters.length) {
|
|
551
|
+
const waiter = waiters.shift();
|
|
552
|
+
waiter === null || waiter === void 0 ? void 0 : waiter.resolve({ value: undefined, done: true });
|
|
553
|
+
}
|
|
554
|
+
};
|
|
555
|
+
const flushError = (error) => {
|
|
556
|
+
while (waiters.length) {
|
|
557
|
+
const waiter = waiters.shift();
|
|
558
|
+
waiter === null || waiter === void 0 ? void 0 : waiter.reject(error);
|
|
559
|
+
}
|
|
560
|
+
};
|
|
561
|
+
const iterator = {
|
|
562
|
+
next() {
|
|
563
|
+
if (queue.length) {
|
|
564
|
+
return Promise.resolve({ value: queue.shift(), done: false });
|
|
565
|
+
}
|
|
566
|
+
if (failure) {
|
|
567
|
+
return Promise.reject(failure);
|
|
568
|
+
}
|
|
569
|
+
if (done) {
|
|
570
|
+
return Promise.resolve({ value: undefined, done: true });
|
|
571
|
+
}
|
|
572
|
+
return new Promise((resolve, reject) => {
|
|
573
|
+
waiters.push({ resolve, reject });
|
|
574
|
+
});
|
|
575
|
+
},
|
|
576
|
+
async return() {
|
|
577
|
+
if (!done && !failure) {
|
|
578
|
+
done = true;
|
|
579
|
+
proxyStreamPending.delete(id);
|
|
580
|
+
try {
|
|
581
|
+
window.parent.postMessage({ _smartlinksProxyStreamAbort: true, id }, '*');
|
|
582
|
+
}
|
|
583
|
+
catch (_a) { }
|
|
584
|
+
}
|
|
585
|
+
flushDone();
|
|
586
|
+
return { value: undefined, done: true };
|
|
587
|
+
},
|
|
588
|
+
async throw(error) {
|
|
589
|
+
failure = error || new Error('Proxy stream failed');
|
|
590
|
+
done = true;
|
|
591
|
+
proxyStreamPending.delete(id);
|
|
592
|
+
flushError(failure);
|
|
593
|
+
throw failure;
|
|
594
|
+
},
|
|
595
|
+
};
|
|
596
|
+
return {
|
|
597
|
+
push(value) {
|
|
598
|
+
if (done || failure)
|
|
599
|
+
return;
|
|
600
|
+
const waiter = waiters.shift();
|
|
601
|
+
if (waiter) {
|
|
602
|
+
waiter.resolve({ value, done: false });
|
|
603
|
+
return;
|
|
604
|
+
}
|
|
605
|
+
queue.push(value);
|
|
606
|
+
},
|
|
607
|
+
finish() {
|
|
608
|
+
if (done || failure)
|
|
609
|
+
return;
|
|
610
|
+
done = true;
|
|
611
|
+
proxyStreamPending.delete(id);
|
|
612
|
+
flushDone();
|
|
613
|
+
},
|
|
614
|
+
fail(error) {
|
|
615
|
+
if (done || failure)
|
|
616
|
+
return;
|
|
617
|
+
failure = error;
|
|
618
|
+
done = true;
|
|
619
|
+
proxyStreamPending.delete(id);
|
|
620
|
+
flushError(error);
|
|
621
|
+
},
|
|
622
|
+
iterable: {
|
|
623
|
+
[Symbol.asyncIterator]() {
|
|
624
|
+
return iterator;
|
|
625
|
+
},
|
|
626
|
+
},
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
function parseSsePayload(payload) {
|
|
630
|
+
if (!payload || payload === '[DONE]')
|
|
631
|
+
return undefined;
|
|
632
|
+
try {
|
|
633
|
+
return JSON.parse(payload);
|
|
634
|
+
}
|
|
635
|
+
catch (_a) {
|
|
636
|
+
return undefined;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
function parseSseStream(stream) {
|
|
640
|
+
return __asyncGenerator(this, arguments, function* parseSseStream_1() {
|
|
641
|
+
const reader = stream.getReader();
|
|
642
|
+
const decoder = new TextDecoder();
|
|
643
|
+
let buffer = '';
|
|
644
|
+
let dataLines = [];
|
|
645
|
+
while (true) {
|
|
646
|
+
const { done, value } = yield __await(reader.read());
|
|
647
|
+
if (done)
|
|
648
|
+
break;
|
|
649
|
+
buffer += decoder.decode(value, { stream: true });
|
|
650
|
+
const lines = buffer.split(/\r?\n/);
|
|
651
|
+
buffer = lines.pop() || '';
|
|
652
|
+
for (const rawLine of lines) {
|
|
653
|
+
const line = rawLine.trimEnd();
|
|
654
|
+
if (!line) {
|
|
655
|
+
if (!dataLines.length)
|
|
656
|
+
continue;
|
|
657
|
+
const parsed = parseSsePayload(dataLines.join('\n'));
|
|
658
|
+
dataLines = [];
|
|
659
|
+
if (parsed !== undefined) {
|
|
660
|
+
yield yield __await(parsed);
|
|
661
|
+
}
|
|
662
|
+
continue;
|
|
663
|
+
}
|
|
664
|
+
if (line.startsWith('data:')) {
|
|
665
|
+
dataLines.push(line.slice(5).trimStart());
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
if (dataLines.length) {
|
|
670
|
+
const parsed = parseSsePayload(dataLines.join('\n'));
|
|
671
|
+
if (parsed !== undefined) {
|
|
672
|
+
yield yield __await(parsed);
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
});
|
|
676
|
+
}
|
|
520
677
|
// Shared listener for proxy responses
|
|
521
678
|
function ensureProxyListener() {
|
|
522
679
|
if (window._smartlinksProxyListener)
|
|
523
680
|
return;
|
|
524
681
|
window.addEventListener("message", (event) => {
|
|
525
682
|
const msg = event.data;
|
|
683
|
+
if ((msg === null || msg === void 0 ? void 0 : msg._smartlinksProxyStream) && msg.id) {
|
|
684
|
+
const pendingStream = proxyStreamPending.get(msg.id);
|
|
685
|
+
if (!pendingStream)
|
|
686
|
+
return;
|
|
687
|
+
if (msg.phase === 'event') {
|
|
688
|
+
pendingStream.push(msg.data);
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
691
|
+
if (msg.phase === 'end') {
|
|
692
|
+
pendingStream.finish();
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
695
|
+
if (msg.phase === 'error') {
|
|
696
|
+
pendingStream.fail(new Error(msg.error || 'Proxy stream failed'));
|
|
697
|
+
return;
|
|
698
|
+
}
|
|
699
|
+
return;
|
|
700
|
+
}
|
|
526
701
|
if (!msg || !msg._smartlinksProxyResponse || !msg.id)
|
|
527
702
|
return;
|
|
528
703
|
logDebug('[smartlinks] proxy:response', { id: msg.id, ok: !msg.error, keys: Object.keys(msg) });
|
|
@@ -539,6 +714,32 @@ function ensureProxyListener() {
|
|
|
539
714
|
});
|
|
540
715
|
window._smartlinksProxyListener = true;
|
|
541
716
|
}
|
|
717
|
+
async function proxyStreamRequest(method, path, body, headers) {
|
|
718
|
+
ensureProxyListener();
|
|
719
|
+
const payloadBody = (typeof FormData !== 'undefined' && body instanceof FormData)
|
|
720
|
+
? serializeFormDataForProxy(body)
|
|
721
|
+
: body;
|
|
722
|
+
const id = generateProxyId();
|
|
723
|
+
const streamController = createProxyStreamIterable(id);
|
|
724
|
+
proxyStreamPending.set(id, streamController);
|
|
725
|
+
const msg = {
|
|
726
|
+
_smartlinksProxyStreamRequest: true,
|
|
727
|
+
id,
|
|
728
|
+
method,
|
|
729
|
+
path,
|
|
730
|
+
body: payloadBody,
|
|
731
|
+
headers,
|
|
732
|
+
};
|
|
733
|
+
logDebug('[smartlinks] proxy:stream postMessage', {
|
|
734
|
+
id,
|
|
735
|
+
method,
|
|
736
|
+
path,
|
|
737
|
+
headers: headers ? redactHeaders(headers) : undefined,
|
|
738
|
+
hasBody: !!body,
|
|
739
|
+
});
|
|
740
|
+
window.parent.postMessage(msg, '*');
|
|
741
|
+
return streamController.iterable;
|
|
742
|
+
}
|
|
542
743
|
// Proxy request implementation
|
|
543
744
|
function serializeFormDataForProxy(fd) {
|
|
544
745
|
const entries = [];
|
|
@@ -1105,6 +1306,41 @@ export async function requestWithOptions(path, options) {
|
|
|
1105
1306
|
}
|
|
1106
1307
|
return fetchPromise;
|
|
1107
1308
|
}
|
|
1309
|
+
/**
|
|
1310
|
+
* Internal helper that performs a streaming request using the shared auth and proxy transport.
|
|
1311
|
+
* The response is expected to be `text/event-stream` with JSON payloads in `data:` frames.
|
|
1312
|
+
*/
|
|
1313
|
+
export async function requestStream(path, options) {
|
|
1314
|
+
const method = (options === null || options === void 0 ? void 0 : options.method) || 'POST';
|
|
1315
|
+
const body = options === null || options === void 0 ? void 0 : options.body;
|
|
1316
|
+
const extraHeaders = (options === null || options === void 0 ? void 0 : options.headers) || {};
|
|
1317
|
+
const headers = Object.assign(Object.assign(Object.assign({}, extraHeaders), getApiHeaders()), { Accept: 'text/event-stream' });
|
|
1318
|
+
if (!(typeof FormData !== 'undefined' && body instanceof FormData) && body !== undefined && !Object.keys(headers).some(k => k.toLowerCase() === 'content-type')) {
|
|
1319
|
+
headers['Content-Type'] = 'application/json';
|
|
1320
|
+
}
|
|
1321
|
+
if (proxyMode) {
|
|
1322
|
+
logDebug('[smartlinks] stream via proxy', { path, method });
|
|
1323
|
+
return proxyStreamRequest(method, path, body, headers);
|
|
1324
|
+
}
|
|
1325
|
+
if (!baseURL) {
|
|
1326
|
+
throw new Error("HTTP client is not initialized. Call initializeApi(...) first.");
|
|
1327
|
+
}
|
|
1328
|
+
const url = `${baseURL}${path}`;
|
|
1329
|
+
logDebug('[smartlinks] stream fetch', { url, method, headers: redactHeaders(headers), body: safeBodyPreview(body) });
|
|
1330
|
+
const response = await fetch(url, {
|
|
1331
|
+
method,
|
|
1332
|
+
headers,
|
|
1333
|
+
body: body === undefined ? undefined : (body instanceof FormData ? body : JSON.stringify(body)),
|
|
1334
|
+
});
|
|
1335
|
+
logDebug('[smartlinks] stream response', { url, status: response.status, ok: response.ok });
|
|
1336
|
+
if (!response.ok) {
|
|
1337
|
+
throw await createFetchError(response, url);
|
|
1338
|
+
}
|
|
1339
|
+
if (!response.body) {
|
|
1340
|
+
throw new Error('Streaming response body is unavailable in this environment');
|
|
1341
|
+
}
|
|
1342
|
+
return parseSseStream(response.body);
|
|
1343
|
+
}
|
|
1108
1344
|
/**
|
|
1109
1345
|
* Internal helper that performs a DELETE request to `${baseURL}${path}`,
|
|
1110
1346
|
* injecting headers for apiKey or bearerToken if present.
|
|
@@ -31,6 +31,7 @@ export declare class IframeResponder {
|
|
|
31
31
|
private options;
|
|
32
32
|
private cache;
|
|
33
33
|
private uploads;
|
|
34
|
+
private activeStreams;
|
|
34
35
|
private isInitialLoad;
|
|
35
36
|
private messageHandler;
|
|
36
37
|
private resizeHandler;
|
|
@@ -59,6 +60,9 @@ export declare class IframeResponder {
|
|
|
59
60
|
private handleRouteChange;
|
|
60
61
|
private handleStandardMessage;
|
|
61
62
|
private handleProxyRequest;
|
|
63
|
+
private handleProxyStreamAbort;
|
|
64
|
+
private handleProxyStreamRequest;
|
|
65
|
+
private forwardProxyStream;
|
|
62
66
|
private getCachedResponse;
|
|
63
67
|
private handleUpload;
|
|
64
68
|
private sendResponse;
|
package/dist/iframeResponder.js
CHANGED
|
@@ -35,6 +35,7 @@ export class IframeResponder {
|
|
|
35
35
|
constructor(options) {
|
|
36
36
|
this.iframe = null;
|
|
37
37
|
this.uploads = new Map();
|
|
38
|
+
this.activeStreams = new Map();
|
|
38
39
|
this.isInitialLoad = true;
|
|
39
40
|
this.messageHandler = null;
|
|
40
41
|
this.resizeHandler = null;
|
|
@@ -97,6 +98,8 @@ export class IframeResponder {
|
|
|
97
98
|
this.resizeHandler = null;
|
|
98
99
|
}
|
|
99
100
|
this.uploads.clear();
|
|
101
|
+
this.activeStreams.forEach(controller => controller.abort());
|
|
102
|
+
this.activeStreams.clear();
|
|
100
103
|
this.iframe = null;
|
|
101
104
|
}
|
|
102
105
|
// ===========================================================================
|
|
@@ -263,6 +266,16 @@ export class IframeResponder {
|
|
|
263
266
|
await this.handleUpload(data, event);
|
|
264
267
|
return;
|
|
265
268
|
}
|
|
269
|
+
// Stream proxy aborts
|
|
270
|
+
if (data._smartlinksProxyStreamAbort) {
|
|
271
|
+
this.handleProxyStreamAbort(data);
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
// Stream proxy requests
|
|
275
|
+
if (data._smartlinksProxyStreamRequest) {
|
|
276
|
+
await this.handleProxyStreamRequest(data, event);
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
266
279
|
// API proxy requests
|
|
267
280
|
if (data._smartlinksProxyRequest || data._smartlinksCustomProxyRequest) {
|
|
268
281
|
await this.handleProxyRequest(data, event);
|
|
@@ -426,6 +439,145 @@ export class IframeResponder {
|
|
|
426
439
|
}
|
|
427
440
|
this.sendResponse(event, response);
|
|
428
441
|
}
|
|
442
|
+
handleProxyStreamAbort(data) {
|
|
443
|
+
const controller = this.activeStreams.get(data.id);
|
|
444
|
+
if (!controller) {
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
controller.abort();
|
|
448
|
+
this.activeStreams.delete(data.id);
|
|
449
|
+
}
|
|
450
|
+
async handleProxyStreamRequest(data, event) {
|
|
451
|
+
var _a, _b, _c;
|
|
452
|
+
const controller = new AbortController();
|
|
453
|
+
this.activeStreams.set(data.id, controller);
|
|
454
|
+
try {
|
|
455
|
+
const path = data.path.startsWith('/') ? data.path.slice(1) : data.path;
|
|
456
|
+
const baseUrl = getBaseURL();
|
|
457
|
+
if (!baseUrl) {
|
|
458
|
+
throw new Error('SDK not initialized - call initializeApi() first');
|
|
459
|
+
}
|
|
460
|
+
const fetchOptions = {
|
|
461
|
+
method: data.method,
|
|
462
|
+
headers: data.headers,
|
|
463
|
+
signal: controller.signal,
|
|
464
|
+
};
|
|
465
|
+
if (data.body && data.method !== 'GET') {
|
|
466
|
+
fetchOptions.body = JSON.stringify(data.body);
|
|
467
|
+
fetchOptions.headers = Object.assign(Object.assign({}, fetchOptions.headers), { 'Content-Type': 'application/json' });
|
|
468
|
+
}
|
|
469
|
+
const response = await fetch(`${baseUrl}/${path}`, fetchOptions);
|
|
470
|
+
if (!response.ok) {
|
|
471
|
+
let responseBody = null;
|
|
472
|
+
try {
|
|
473
|
+
responseBody = await response.json();
|
|
474
|
+
}
|
|
475
|
+
catch (_d) {
|
|
476
|
+
responseBody = null;
|
|
477
|
+
}
|
|
478
|
+
const message = (responseBody === null || responseBody === void 0 ? void 0 : responseBody.message) || ((_a = responseBody === null || responseBody === void 0 ? void 0 : responseBody.error) === null || _a === void 0 ? void 0 : _a.message) || `Request failed with status ${response.status}`;
|
|
479
|
+
this.sendResponse(event, {
|
|
480
|
+
_smartlinksProxyStream: true,
|
|
481
|
+
id: data.id,
|
|
482
|
+
phase: 'error',
|
|
483
|
+
status: response.status,
|
|
484
|
+
error: message,
|
|
485
|
+
});
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
488
|
+
if (!response.body) {
|
|
489
|
+
throw new Error('Streaming response body is unavailable in this environment');
|
|
490
|
+
}
|
|
491
|
+
this.sendResponse(event, {
|
|
492
|
+
_smartlinksProxyStream: true,
|
|
493
|
+
id: data.id,
|
|
494
|
+
phase: 'open',
|
|
495
|
+
});
|
|
496
|
+
await this.forwardProxyStream(data.id, response.body, event);
|
|
497
|
+
this.sendResponse(event, {
|
|
498
|
+
_smartlinksProxyStream: true,
|
|
499
|
+
id: data.id,
|
|
500
|
+
phase: 'end',
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
catch (err) {
|
|
504
|
+
if ((err === null || err === void 0 ? void 0 : err.name) === 'AbortError') {
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
console.error('[IframeResponder] Proxy stream error:', err);
|
|
508
|
+
this.sendResponse(event, {
|
|
509
|
+
_smartlinksProxyStream: true,
|
|
510
|
+
id: data.id,
|
|
511
|
+
phase: 'error',
|
|
512
|
+
error: (err === null || err === void 0 ? void 0 : err.message) || 'Unknown streaming error',
|
|
513
|
+
});
|
|
514
|
+
(_c = (_b = this.options).onError) === null || _c === void 0 ? void 0 : _c.call(_b, err);
|
|
515
|
+
}
|
|
516
|
+
finally {
|
|
517
|
+
this.activeStreams.delete(data.id);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
async forwardProxyStream(id, stream, event) {
|
|
521
|
+
const reader = stream.getReader();
|
|
522
|
+
const decoder = new TextDecoder();
|
|
523
|
+
let buffer = '';
|
|
524
|
+
let dataLines = [];
|
|
525
|
+
while (true) {
|
|
526
|
+
const { done, value } = await reader.read();
|
|
527
|
+
if (done) {
|
|
528
|
+
break;
|
|
529
|
+
}
|
|
530
|
+
buffer += decoder.decode(value, { stream: true });
|
|
531
|
+
const lines = buffer.split(/\r?\n/);
|
|
532
|
+
buffer = lines.pop() || '';
|
|
533
|
+
for (const rawLine of lines) {
|
|
534
|
+
const line = rawLine.trimEnd();
|
|
535
|
+
if (!line) {
|
|
536
|
+
if (!dataLines.length) {
|
|
537
|
+
continue;
|
|
538
|
+
}
|
|
539
|
+
const payload = dataLines.join('\n');
|
|
540
|
+
dataLines = [];
|
|
541
|
+
if (payload === '[DONE]') {
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
544
|
+
try {
|
|
545
|
+
const parsed = JSON.parse(payload);
|
|
546
|
+
this.sendResponse(event, {
|
|
547
|
+
_smartlinksProxyStream: true,
|
|
548
|
+
id,
|
|
549
|
+
phase: 'event',
|
|
550
|
+
data: parsed,
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
catch (_a) {
|
|
554
|
+
// Ignore malformed event chunks
|
|
555
|
+
}
|
|
556
|
+
continue;
|
|
557
|
+
}
|
|
558
|
+
if (line.startsWith('data:')) {
|
|
559
|
+
dataLines.push(line.slice(5).trimStart());
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
if (dataLines.length) {
|
|
564
|
+
const payload = dataLines.join('\n');
|
|
565
|
+
if (payload !== '[DONE]') {
|
|
566
|
+
try {
|
|
567
|
+
const parsed = JSON.parse(payload);
|
|
568
|
+
this.sendResponse(event, {
|
|
569
|
+
_smartlinksProxyStream: true,
|
|
570
|
+
id,
|
|
571
|
+
phase: 'event',
|
|
572
|
+
data: parsed,
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
catch (_b) {
|
|
576
|
+
// Ignore malformed trailing event chunk
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
}
|
|
429
581
|
getCachedResponse(path) {
|
|
430
582
|
// App data endpoints should NOT be cached - they need fresh data from API
|
|
431
583
|
// These are the new separated app config endpoints
|
package/dist/openapi.yaml
CHANGED
|
@@ -15478,6 +15478,69 @@ components:
|
|
|
15478
15478
|
required:
|
|
15479
15479
|
- _smartlinksProxyResponse
|
|
15480
15480
|
- id
|
|
15481
|
+
ProxyStreamRequest:
|
|
15482
|
+
type: object
|
|
15483
|
+
properties:
|
|
15484
|
+
_smartlinksProxyStreamRequest:
|
|
15485
|
+
type: object
|
|
15486
|
+
additionalProperties: true
|
|
15487
|
+
id:
|
|
15488
|
+
type: string
|
|
15489
|
+
method:
|
|
15490
|
+
type: string
|
|
15491
|
+
enum:
|
|
15492
|
+
- GET
|
|
15493
|
+
- POST
|
|
15494
|
+
- PUT
|
|
15495
|
+
- PATCH
|
|
15496
|
+
- DELETE
|
|
15497
|
+
path:
|
|
15498
|
+
type: string
|
|
15499
|
+
body: {}
|
|
15500
|
+
headers:
|
|
15501
|
+
type: object
|
|
15502
|
+
additionalProperties:
|
|
15503
|
+
type: string
|
|
15504
|
+
required:
|
|
15505
|
+
- _smartlinksProxyStreamRequest
|
|
15506
|
+
- id
|
|
15507
|
+
- method
|
|
15508
|
+
- path
|
|
15509
|
+
ProxyStreamAbortMessage:
|
|
15510
|
+
type: object
|
|
15511
|
+
properties:
|
|
15512
|
+
_smartlinksProxyStreamAbort:
|
|
15513
|
+
type: object
|
|
15514
|
+
additionalProperties: true
|
|
15515
|
+
id:
|
|
15516
|
+
type: string
|
|
15517
|
+
required:
|
|
15518
|
+
- _smartlinksProxyStreamAbort
|
|
15519
|
+
- id
|
|
15520
|
+
ProxyStreamMessage:
|
|
15521
|
+
type: object
|
|
15522
|
+
properties:
|
|
15523
|
+
_smartlinksProxyStream:
|
|
15524
|
+
type: object
|
|
15525
|
+
additionalProperties: true
|
|
15526
|
+
id:
|
|
15527
|
+
type: string
|
|
15528
|
+
phase:
|
|
15529
|
+
type: string
|
|
15530
|
+
enum:
|
|
15531
|
+
- open
|
|
15532
|
+
- event
|
|
15533
|
+
- end
|
|
15534
|
+
- error
|
|
15535
|
+
data: {}
|
|
15536
|
+
error:
|
|
15537
|
+
type: string
|
|
15538
|
+
status:
|
|
15539
|
+
type: number
|
|
15540
|
+
required:
|
|
15541
|
+
- _smartlinksProxyStream
|
|
15542
|
+
- id
|
|
15543
|
+
- phase
|
|
15481
15544
|
UploadStartMessage:
|
|
15482
15545
|
type: object
|
|
15483
15546
|
properties:
|
|
@@ -68,6 +68,26 @@ export interface ProxyResponse {
|
|
|
68
68
|
data?: any;
|
|
69
69
|
error?: string;
|
|
70
70
|
}
|
|
71
|
+
export interface ProxyStreamRequest {
|
|
72
|
+
_smartlinksProxyStreamRequest: true;
|
|
73
|
+
id: string;
|
|
74
|
+
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
75
|
+
path: string;
|
|
76
|
+
body?: any;
|
|
77
|
+
headers?: Record<string, string>;
|
|
78
|
+
}
|
|
79
|
+
export interface ProxyStreamAbortMessage {
|
|
80
|
+
_smartlinksProxyStreamAbort: true;
|
|
81
|
+
id: string;
|
|
82
|
+
}
|
|
83
|
+
export interface ProxyStreamMessage {
|
|
84
|
+
_smartlinksProxyStream: true;
|
|
85
|
+
id: string;
|
|
86
|
+
phase: 'open' | 'event' | 'end' | 'error';
|
|
87
|
+
data?: any;
|
|
88
|
+
error?: string;
|
|
89
|
+
status?: number;
|
|
90
|
+
}
|
|
71
91
|
export interface UploadStartMessage {
|
|
72
92
|
_smartlinksProxyUpload: true;
|
|
73
93
|
phase: 'start';
|
package/docs/API_SUMMARY.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Smartlinks API Summary
|
|
2
2
|
|
|
3
|
-
Version: 1.8.
|
|
3
|
+
Version: 1.8.2 | Generated: 2026-03-14T10:21:47.666Z
|
|
4
4
|
|
|
5
5
|
This is a concise summary of all available API functions and types.
|
|
6
6
|
|
|
@@ -166,6 +166,14 @@ Internal helper that performs a PATCH request to `${baseURL}${path}`, injecting
|
|
|
166
166
|
options: RequestInit) → `Promise<T>`
|
|
167
167
|
Internal helper that performs a request to `${baseURL}${path}` with custom options, injecting headers for apiKey or bearerToken if present. Returns the parsed JSON as T, or throws an Error.
|
|
168
168
|
|
|
169
|
+
**requestStream**(path: string,
|
|
170
|
+
options?: {
|
|
171
|
+
method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'
|
|
172
|
+
body?: any
|
|
173
|
+
headers?: Record<string, string>
|
|
174
|
+
}) → `Promise<AsyncIterable<T>>`
|
|
175
|
+
Internal helper that performs a streaming request using the shared auth and proxy transport. The response is expected to be `text/event-stream` with JSON payloads in `data:` frames.
|
|
176
|
+
|
|
169
177
|
**del**(path: string,
|
|
170
178
|
extraHeaders?: Record<string, string>) → `Promise<T>`
|
|
171
179
|
Internal helper that performs a DELETE request to `${baseURL}${path}`, injecting headers for apiKey or bearerToken if present. Returns the parsed JSON as T, or throws an Error.
|
|
@@ -4205,6 +4213,38 @@ interface ProxyResponse {
|
|
|
4205
4213
|
}
|
|
4206
4214
|
```
|
|
4207
4215
|
|
|
4216
|
+
**ProxyStreamRequest** (interface)
|
|
4217
|
+
```typescript
|
|
4218
|
+
interface ProxyStreamRequest {
|
|
4219
|
+
_smartlinksProxyStreamRequest: true;
|
|
4220
|
+
id: string;
|
|
4221
|
+
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
4222
|
+
path: string;
|
|
4223
|
+
body?: any;
|
|
4224
|
+
headers?: Record<string, string>;
|
|
4225
|
+
}
|
|
4226
|
+
```
|
|
4227
|
+
|
|
4228
|
+
**ProxyStreamAbortMessage** (interface)
|
|
4229
|
+
```typescript
|
|
4230
|
+
interface ProxyStreamAbortMessage {
|
|
4231
|
+
_smartlinksProxyStreamAbort: true;
|
|
4232
|
+
id: string;
|
|
4233
|
+
}
|
|
4234
|
+
```
|
|
4235
|
+
|
|
4236
|
+
**ProxyStreamMessage** (interface)
|
|
4237
|
+
```typescript
|
|
4238
|
+
interface ProxyStreamMessage {
|
|
4239
|
+
_smartlinksProxyStream: true;
|
|
4240
|
+
id: string;
|
|
4241
|
+
phase: 'open' | 'event' | 'end' | 'error';
|
|
4242
|
+
data?: any;
|
|
4243
|
+
error?: string;
|
|
4244
|
+
status?: number;
|
|
4245
|
+
}
|
|
4246
|
+
```
|
|
4247
|
+
|
|
4208
4248
|
**UploadStartMessage** (interface)
|
|
4209
4249
|
```typescript
|
|
4210
4250
|
interface UploadStartMessage {
|