@proveanything/smartlinks 1.8.1 → 1.8.3

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/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 = [];
@@ -548,6 +749,19 @@ function serializeFormDataForProxy(fd) {
548
749
  });
549
750
  return { _isFormData: true, entries };
550
751
  }
752
+ function sanitizeProxyRequestOptions(options) {
753
+ if (!options)
754
+ return undefined;
755
+ const _a = options, { signal, body, headers, method, window, duplex } = _a, rest = __rest(_a, ["signal", "body", "headers", "method", "window", "duplex"]);
756
+ void signal;
757
+ void body;
758
+ void headers;
759
+ void method;
760
+ void window;
761
+ void duplex;
762
+ const sanitized = Object.fromEntries(Object.entries(rest).filter(([, value]) => value !== undefined));
763
+ return Object.keys(sanitized).length ? sanitized : undefined;
764
+ }
551
765
  async function proxyRequest(method, path, body, headers, options) {
552
766
  ensureProxyListener();
553
767
  const payloadBody = (typeof FormData !== 'undefined' && body instanceof FormData)
@@ -561,7 +775,7 @@ async function proxyRequest(method, path, body, headers, options) {
561
775
  path,
562
776
  body: payloadBody,
563
777
  headers,
564
- options,
778
+ options: sanitizeProxyRequestOptions(options),
565
779
  };
566
780
  logDebug('[smartlinks] proxy:postMessage', { id, method, path, headers: headers ? redactHeaders(headers) : undefined, hasBody: !!body });
567
781
  return new Promise((resolve, reject) => {
@@ -1105,6 +1319,41 @@ export async function requestWithOptions(path, options) {
1105
1319
  }
1106
1320
  return fetchPromise;
1107
1321
  }
1322
+ /**
1323
+ * Internal helper that performs a streaming request using the shared auth and proxy transport.
1324
+ * The response is expected to be `text/event-stream` with JSON payloads in `data:` frames.
1325
+ */
1326
+ export async function requestStream(path, options) {
1327
+ const method = (options === null || options === void 0 ? void 0 : options.method) || 'POST';
1328
+ const body = options === null || options === void 0 ? void 0 : options.body;
1329
+ const extraHeaders = (options === null || options === void 0 ? void 0 : options.headers) || {};
1330
+ const headers = Object.assign(Object.assign(Object.assign({}, extraHeaders), getApiHeaders()), { Accept: 'text/event-stream' });
1331
+ if (!(typeof FormData !== 'undefined' && body instanceof FormData) && body !== undefined && !Object.keys(headers).some(k => k.toLowerCase() === 'content-type')) {
1332
+ headers['Content-Type'] = 'application/json';
1333
+ }
1334
+ if (proxyMode) {
1335
+ logDebug('[smartlinks] stream via proxy', { path, method });
1336
+ return proxyStreamRequest(method, path, body, headers);
1337
+ }
1338
+ if (!baseURL) {
1339
+ throw new Error("HTTP client is not initialized. Call initializeApi(...) first.");
1340
+ }
1341
+ const url = `${baseURL}${path}`;
1342
+ logDebug('[smartlinks] stream fetch', { url, method, headers: redactHeaders(headers), body: safeBodyPreview(body) });
1343
+ const response = await fetch(url, {
1344
+ method,
1345
+ headers,
1346
+ body: body === undefined ? undefined : (body instanceof FormData ? body : JSON.stringify(body)),
1347
+ });
1348
+ logDebug('[smartlinks] stream response', { url, status: response.status, ok: response.ok });
1349
+ if (!response.ok) {
1350
+ throw await createFetchError(response, url);
1351
+ }
1352
+ if (!response.body) {
1353
+ throw new Error('Streaming response body is unavailable in this environment');
1354
+ }
1355
+ return parseSseStream(response.body);
1356
+ }
1108
1357
  /**
1109
1358
  * Internal helper that performs a DELETE request to `${baseURL}${path}`,
1110
1359
  * 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;
@@ -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';
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 1.8.1 | Generated: 2026-03-14T09:21:59.178Z
3
+ Version: 1.8.3 | Generated: 2026-03-14T10:31:32.637Z
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 {