@superblocksteam/library 2.0.131 → 2.0.132

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.
@@ -1,4 +1,4 @@
1
- import { _ as root_store_default, t as makeWrappedComponent, x as tracker } from "../jsx-wrapper-BpJeKbJA.js";
1
+ import { S as tracker, t as makeWrappedComponent, v as root_store_default } from "../jsx-wrapper-wJs8wFGh.js";
2
2
  import { SOURCE_ID_ATTRIBUTE } from "@superblocksteam/library-shared";
3
3
  import * as ReactJsxDevRuntime from "react/jsx-dev-runtime";
4
4
  //#region src/jsx-dev-runtime/jsx-dev-runtime.ts
@@ -1867,7 +1867,7 @@ function getTraceContextHeadersFromSpan(span) {
1867
1867
  //#endregion
1868
1868
  //#region src/lib/internal-details/lib/features/api-utils.ts
1869
1869
  async function executeV2Api(params) {
1870
- const { body, apiName, controlFlowOnlyFiles, notifyOnSystemError, eventType, onMessage, processStreamEvents, responseType, abortController, baseUrl, viewMode, accessToken, token, traceHeaders } = params;
1870
+ const { body, apiName, controlFlowOnlyFiles, notifyOnSystemError, eventType, onMessage, processStreamEvents, responseType, abortController, baseUrl, viewMode, accessToken, token, maxResponseBytes, traceHeaders } = params;
1871
1871
  let parentContext = context.active();
1872
1872
  if (traceHeaders) parentContext = getContextFromTraceHeaders(traceHeaders);
1873
1873
  let applicationId = "unknown";
@@ -1908,17 +1908,31 @@ async function executeV2Api(params) {
1908
1908
  fullUrl: baseUrl,
1909
1909
  timeoutId: setTimeout(() => {}, 1e3),
1910
1910
  onMessage,
1911
- processStreamEvents
1911
+ processStreamEvents,
1912
+ maxResponseBytes
1912
1913
  }) : await fetchServer({
1913
1914
  augmentedInit: init,
1914
1915
  fullUrl: baseUrl,
1915
- timeoutId: setTimeout(() => {}, 1e3)
1916
+ timeoutId: setTimeout(() => {}, 1e3),
1917
+ maxResponseBytes
1916
1918
  });
1917
1919
  } catch (err) {
1918
1920
  const message = `Failed to execute ${apiName || "API"}. ${err}`;
1919
1921
  const suppressError = viewMode !== ViewMode.EDITOR && err?.code === 20;
1920
1922
  if (notifyOnSystemError && !suppressError) console.log(`[internal] [executeV2Api] ${message}`);
1921
- const statusCode = err instanceof HttpError ? err.code : void 0;
1923
+ if (err instanceof ResponseSizeLimitError) {
1924
+ span.recordException(err);
1925
+ span.setAttributes({
1926
+ "response_size_limit.exceeded": true,
1927
+ "response_size_limit.limit_bytes": err.limitBytes
1928
+ });
1929
+ console.warn("[internal] [executeV2Api] orchestrator /execute response size limit exceeded", {
1930
+ apiName: apiName ?? "unknown",
1931
+ applicationId,
1932
+ limitBytes: err.limitBytes
1933
+ });
1934
+ }
1935
+ const statusCode = err instanceof HttpError ? err.code : err instanceof ResponseSizeLimitError ? 413 : void 0;
1922
1936
  let errorType = "GENERAL";
1923
1937
  const errorMessage = err instanceof Error ? err.message : String(err);
1924
1938
  const errorConstructorName = err?.constructor?.name;
@@ -1942,7 +1956,11 @@ const HttpMethod = {
1942
1956
  Patch: "PATCH",
1943
1957
  Delete: "DELETE"
1944
1958
  };
1945
- const stream = async ({ url, headers, body, onMessage, onComplete, onError, defaultError, method, baseUrl = "/api/", signal, init: overrideInit }) => {
1959
+ const cancelReaderBestEffort = async (reader) => {
1960
+ await reader.cancel().catch(() => void 0);
1961
+ };
1962
+ const isResponseSizeLimitEnabled = (maxResponseBytes) => maxResponseBytes !== void 0 && Number.isFinite(maxResponseBytes) && maxResponseBytes > 0;
1963
+ const stream = async ({ url, headers, body, onMessage, onComplete, onError, defaultError, method, baseUrl = "/api/", signal, init: overrideInit, maxResponseBytes }) => {
1946
1964
  const init = overrideInit ?? {
1947
1965
  body: JSON.stringify(body),
1948
1966
  headers,
@@ -1951,20 +1969,28 @@ const stream = async ({ url, headers, body, onMessage, onComplete, onError, defa
1951
1969
  try {
1952
1970
  const response = await fetch(`${baseUrl}${url}`, init);
1953
1971
  if (!response.ok) try {
1954
- const parsed = await response.json();
1972
+ const parsed = await readJsonResponseWithLimit(response, maxResponseBytes);
1955
1973
  throw new HttpError(response.status, !response.status || response.status >= 500, parsed?.error?.message ?? parsed?.responseMeta?.error?.message ?? defaultError);
1956
1974
  } catch (e) {
1957
- if (e instanceof HttpError) throw e;
1975
+ if (e instanceof HttpError || e instanceof ResponseSizeLimitError) throw e;
1958
1976
  throw new HttpError(response.status, !response.status || response.status >= 500, response.statusText);
1959
1977
  }
1960
1978
  if (!response.body) return;
1961
1979
  const reader = response.body.getReader();
1962
1980
  const decoder = new TextDecoder();
1963
1981
  let done = false;
1982
+ let totalBytes = 0;
1964
1983
  let lastChunk = "";
1965
1984
  while (!done) {
1966
1985
  if (signal && signal.aborted) return;
1967
1986
  const { value, done: readerDone } = await reader.read();
1987
+ if (value) {
1988
+ totalBytes += value.byteLength;
1989
+ if (isResponseSizeLimitEnabled(maxResponseBytes) && totalBytes > maxResponseBytes) {
1990
+ await cancelReaderBestEffort(reader);
1991
+ throw new ResponseSizeLimitError(maxResponseBytes);
1992
+ }
1993
+ }
1968
1994
  const chunk = lastChunk + decoder.decode(value);
1969
1995
  const messages = chunk.split("\n");
1970
1996
  let jsonValues = [];
@@ -1986,12 +2012,13 @@ const stream = async ({ url, headers, body, onMessage, onComplete, onError, defa
1986
2012
  }
1987
2013
  } catch (e) {
1988
2014
  if (e.name === "AbortError") console.log("[internal] [stream] Fetch was cancelled");
2015
+ else if (e instanceof ResponseSizeLimitError) throw e;
1989
2016
  else onError(e.message ?? defaultError, e.code);
1990
2017
  } finally {
1991
2018
  onComplete();
1992
2019
  }
1993
2020
  };
1994
- const fetchServerStream = async ({ augmentedInit, fullUrl, timeoutId, onMessage, processStreamEvents }) => {
2021
+ const fetchServerStream = async ({ augmentedInit, fullUrl, timeoutId, onMessage, processStreamEvents, maxResponseBytes }) => {
1995
2022
  const handleMessage = (message) => {
1996
2023
  if (message?.result?.event?.data) onMessage && onMessage(message.result.event.data);
1997
2024
  else if (message?.result?.event?.start || message?.result?.event?.end) processStreamEvents && processStreamEvents(message);
@@ -2010,7 +2037,8 @@ const fetchServerStream = async ({ augmentedInit, fullUrl, timeoutId, onMessage,
2010
2037
  onComplete,
2011
2038
  onError,
2012
2039
  baseUrl: "",
2013
- signal: augmentedInit?.signal ?? void 0
2040
+ signal: augmentedInit?.signal ?? void 0,
2041
+ maxResponseBytes
2014
2042
  });
2015
2043
  };
2016
2044
  const getErrorMessageFromObject = (message) => {
@@ -2018,11 +2046,11 @@ const getErrorMessageFromObject = (message) => {
2018
2046
  const match = /"message"\s*:\s*"([^"]*)"/.exec(messageJSONString);
2019
2047
  return match ? match[1] : messageJSONString;
2020
2048
  };
2021
- const fetchServer = ({ augmentedInit, fullUrl, timeoutId }) => {
2049
+ const fetchServer = ({ augmentedInit, fullUrl, timeoutId, maxResponseBytes }) => {
2022
2050
  return fetch(fullUrl, augmentedInit).then(async (response) => {
2023
2051
  try {
2024
2052
  if (response.status === 204) return null;
2025
- const json = await response.json();
2053
+ const json = await readJsonResponseWithLimit(response, maxResponseBytes);
2026
2054
  if (response.ok && json) {
2027
2055
  if (json.data == null) return json;
2028
2056
  return json.data;
@@ -2032,7 +2060,7 @@ const fetchServer = ({ augmentedInit, fullUrl, timeoutId }) => {
2032
2060
  throw new HttpError(response.status, !response.status || response.status >= 500, message);
2033
2061
  }
2034
2062
  } catch (e) {
2035
- if (e instanceof HttpError) throw e;
2063
+ if (e instanceof HttpError || e instanceof ResponseSizeLimitError) throw e;
2036
2064
  throw new HttpError(response.status, !response.status || response.status >= 500, response.statusText);
2037
2065
  }
2038
2066
  }).finally(() => clearTimeout(timeoutId));
@@ -2046,6 +2074,49 @@ var HttpError = class extends Error {
2046
2074
  this.critical = critical;
2047
2075
  }
2048
2076
  };
2077
+ var ResponseSizeLimitError = class extends Error {
2078
+ constructor(limitBytes) {
2079
+ super(`Response blocked: exceeded orchestrator /execute response limit of ${limitBytes} bytes.`);
2080
+ this.limitBytes = limitBytes;
2081
+ this.name = "ResponseSizeLimitError";
2082
+ }
2083
+ };
2084
+ const readTextResponseWithLimit = async (response, maxResponseBytes) => {
2085
+ if (!response.body) {
2086
+ const text = await response.text();
2087
+ if (isResponseSizeLimitEnabled(maxResponseBytes) && new TextEncoder().encode(text).byteLength > maxResponseBytes) throw new ResponseSizeLimitError(maxResponseBytes);
2088
+ return text;
2089
+ }
2090
+ const reader = response.body.getReader();
2091
+ const chunks = [];
2092
+ let totalBytes = 0;
2093
+ while (true) {
2094
+ const { value, done } = await reader.read();
2095
+ if (done) break;
2096
+ if (!value) continue;
2097
+ totalBytes += value.byteLength;
2098
+ if (isResponseSizeLimitEnabled(maxResponseBytes) && totalBytes > maxResponseBytes) {
2099
+ await cancelReaderBestEffort(reader);
2100
+ throw new ResponseSizeLimitError(maxResponseBytes);
2101
+ }
2102
+ chunks.push(value);
2103
+ }
2104
+ const body = new Uint8Array(totalBytes);
2105
+ let offset = 0;
2106
+ for (const chunk of chunks) {
2107
+ body.set(chunk, offset);
2108
+ offset += chunk.byteLength;
2109
+ }
2110
+ return new TextDecoder().decode(body);
2111
+ };
2112
+ const isLegacyJsonOnlyResponseMock = (response) => {
2113
+ const maybeResponse = response;
2114
+ return !maybeResponse.body && typeof maybeResponse.text !== "function" && typeof maybeResponse.json === "function";
2115
+ };
2116
+ const readJsonResponseWithLimit = async (response, maxResponseBytes) => {
2117
+ if (isLegacyJsonOnlyResponseMock(response)) return response.json();
2118
+ return JSON.parse(await readTextResponseWithLimit(response, maxResponseBytes));
2119
+ };
2049
2120
  const parseStreamResult = (streamResult, options) => {
2050
2121
  if (!streamResult || !Array.isArray(streamResult) || !streamResult.length) return;
2051
2122
  const execution = streamResult[0].result.execution;
@@ -2533,6 +2604,7 @@ var ApiManager = class {
2533
2604
  viewMode: editMode ? ViewMode.EDITOR : ViewMode.DEPLOYED,
2534
2605
  accessToken: this.accessToken ?? "",
2535
2606
  token: this.token ?? "",
2607
+ maxResponseBytes: this.rootStore.orchestratorExecuteResponseSizeLimitBytes,
2536
2608
  traceHeaders,
2537
2609
  abortController,
2538
2610
  onMessage: (message) => {
@@ -2543,7 +2615,8 @@ var ApiManager = class {
2543
2615
  editorBridge.sendStreamedApiEvent(event, apiName);
2544
2616
  }
2545
2617
  });
2546
- const parsedResult = (isStream ? parseStreamResult(events, { includeFinalOutput: true }) ?? syncResponse : syncResponse) ?? void 0;
2618
+ const hasSystemError = syncResponse != null && typeof syncResponse === "object" && "systemError" in syncResponse;
2619
+ const parsedResult = (isStream ? hasSystemError ? syncResponse : parseStreamResult(events, { includeFinalOutput: true }) ?? syncResponse : syncResponse) ?? void 0;
2547
2620
  if (parsedResult) decodeBytestringsInV2ExecutionResponse(parsedResult);
2548
2621
  this.runningApiControllers[apiName]?.delete(abortController);
2549
2622
  const error = this.findError(parsedResult ?? void 0);
@@ -2775,8 +2848,8 @@ var ApiManager = class {
2775
2848
  signal: abortController.signal
2776
2849
  });
2777
2850
  if (!response.ok) {
2778
- const text = await response.text();
2779
2851
  networkMs = Math.round(performance.now() - fetchPerfT0);
2852
+ const text = await readTextResponseWithLimit(response, this.rootStore.orchestratorExecuteResponseSizeLimitBytes);
2780
2853
  let message;
2781
2854
  try {
2782
2855
  const json = JSON.parse(text);
@@ -2799,8 +2872,8 @@ var ApiManager = class {
2799
2872
  timingBreakdown: buildTimingBreakdown()
2800
2873
  };
2801
2874
  }
2802
- const result = await response.json();
2803
2875
  networkMs = Math.round(performance.now() - fetchPerfT0);
2876
+ const result = await readJsonResponseWithLimit(response, this.rootStore.orchestratorExecuteResponseSizeLimitBytes);
2804
2877
  const eventPerf = result.events?.find((e) => e.end?.performance != null);
2805
2878
  const perfObj = result.performance ?? (eventPerf?.end)?.performance;
2806
2879
  const executionStartMs = perfObj?.start != null && Number.isFinite(Number(perfObj.start)) ? Number(perfObj.start) : void 0;
@@ -2828,6 +2901,21 @@ var ApiManager = class {
2828
2901
  timingBreakdown
2829
2902
  };
2830
2903
  } catch (error) {
2904
+ if (error instanceof ResponseSizeLimitError) {
2905
+ console.warn("[api-store] orchestrator /execute response size limit exceeded", {
2906
+ apiName,
2907
+ applicationId,
2908
+ limitBytes: error.limitBytes
2909
+ });
2910
+ return {
2911
+ success: false,
2912
+ error: {
2913
+ code: "SYSTEM_ERROR",
2914
+ message: error.message
2915
+ },
2916
+ timingBreakdown: buildTimingBreakdown()
2917
+ };
2918
+ }
2831
2919
  if (error instanceof Error && error.name === "AbortError") return {
2832
2920
  success: false,
2833
2921
  error: {
@@ -3360,6 +3448,7 @@ var ComponentRegistry = class {
3360
3448
  };
3361
3449
  //#endregion
3362
3450
  //#region src/lib/internal-details/lib/root-store.ts
3451
+ const ORCHESTRATOR_EXECUTE_RESPONSE_SIZE_LIMIT_FLAG = "orchestrator.execute.response-size-limit.bytes";
3363
3452
  /**
3364
3453
  * Default user object for when no user info is available.
3365
3454
  */
@@ -3395,6 +3484,7 @@ var RootStore = class {
3395
3484
  * Passed to the library via the ui.data-plane-gateway.enabled bootstrap flag.
3396
3485
  */
3397
3486
  dataPlaneGatewayEnabled = false;
3487
+ orchestratorExecuteResponseSizeLimitBytes;
3398
3488
  /** Selected integration profile for orchestrator API calls */
3399
3489
  profile;
3400
3490
  /** Current git branch name for editor-mode API execution */
@@ -3441,6 +3531,8 @@ var RootStore = class {
3441
3531
  setSdkApiEnabled: action,
3442
3532
  dataPlaneGatewayEnabled: observable,
3443
3533
  setDataPlaneGatewayEnabled: action,
3534
+ orchestratorExecuteResponseSizeLimitBytes: observable,
3535
+ setOrchestratorExecuteResponseSizeLimitBytes: action,
3444
3536
  profile: observable.ref,
3445
3537
  setProfile: action,
3446
3538
  branchName: observable,
@@ -3477,6 +3569,10 @@ var RootStore = class {
3477
3569
  setDataPlaneGatewayEnabled(enabled) {
3478
3570
  this.dataPlaneGatewayEnabled = enabled;
3479
3571
  }
3572
+ setOrchestratorExecuteResponseSizeLimitBytes(value) {
3573
+ const parsedValue = typeof value === "number" ? value : typeof value === "string" && value.trim() !== "" ? Number(value.trim()) : void 0;
3574
+ this.orchestratorExecuteResponseSizeLimitBytes = typeof parsedValue === "number" && Number.isFinite(parsedValue) && parsedValue > 0 ? Math.floor(parsedValue) : void 0;
3575
+ }
3480
3576
  setProfile(profile) {
3481
3577
  this.profile = profile;
3482
3578
  }
@@ -4186,6 +4282,6 @@ const useJSXContext = () => {
4186
4282
  return React.useContext(JSXContext);
4187
4283
  };
4188
4284
  //#endregion
4189
- export { useSuperblocksProfiles as A, sendMessageImmediately as B, rejectById as C, useSuperblocksContext as D, getAppMode as E, colors as F, Section as G, createManagedPropsList as H, editorBridge as I, createPropertiesPanelDefinition as K, getParentOrigin as L, embedStore as M, generateId as N, useSuperblocksDataTags as O, sendNotification as P, iframeMessageHandler as R, addNewPromise as S, SuperblocksContextProvider as T, Prop as U, isEditMode as V, PropsCategory as W, root_store_default as _, FixWithClarkButton as a, getContextFromTraceHeaders as b, ErrorContent as c, ErrorMessage as d, ErrorStack as f, StyledClarkIcon as g, SecondaryButton as h, getWidgetRectAnchorName as i, useSuperblocksUser as j, useSuperblocksGroups as k, ErrorDetails as l, ErrorTitle as m, useJSXContext as n, ActionsContainer as o, ErrorSummary as p, getEditStore as q, getWidgetAnchorName as r, ErrorContainer as s, makeWrappedComponent as t, ErrorIconContainer as u, startEditorSync as v, resolveById as w, tracker as x, createIframeSpan as y, isEmbeddedBySuperblocksFirstParty as z };
4285
+ export { useSuperblocksGroups as A, isEmbeddedBySuperblocksFirstParty as B, addNewPromise as C, getAppMode as D, SuperblocksContextProvider as E, sendNotification as F, PropsCategory as G, isEditMode as H, colors as I, getEditStore as J, Section as K, editorBridge as L, useSuperblocksUser as M, embedStore as N, useSuperblocksContext as O, generateId as P, getParentOrigin as R, tracker as S, resolveById as T, createManagedPropsList as U, sendMessageImmediately as V, Prop as W, ORCHESTRATOR_EXECUTE_RESPONSE_SIZE_LIMIT_FLAG as _, FixWithClarkButton as a, createIframeSpan as b, ErrorContent as c, ErrorMessage as d, ErrorStack as f, StyledClarkIcon as g, SecondaryButton as h, getWidgetRectAnchorName as i, useSuperblocksProfiles as j, useSuperblocksDataTags as k, ErrorDetails as l, ErrorTitle as m, useJSXContext as n, ActionsContainer as o, ErrorSummary as p, createPropertiesPanelDefinition as q, getWidgetAnchorName as r, ErrorContainer as s, makeWrappedComponent as t, ErrorIconContainer as u, root_store_default as v, rejectById as w, getContextFromTraceHeaders as x, startEditorSync as y, iframeMessageHandler as z };
4190
4286
 
4191
- //# sourceMappingURL=jsx-wrapper-BpJeKbJA.js.map
4287
+ //# sourceMappingURL=jsx-wrapper-wJs8wFGh.js.map