@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.
- package/dist/jsx-dev-runtime/index.js +1 -1
- package/dist/{jsx-wrapper-BpJeKbJA.js → jsx-wrapper-wJs8wFGh.js} +113 -17
- package/dist/jsx-wrapper-wJs8wFGh.js.map +1 -0
- package/dist/lib/index.d.ts +2 -0
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +67 -16
- package/dist/lib/index.js.map +1 -1
- package/package.json +4 -4
- package/dist/jsx-wrapper-BpJeKbJA.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 {
|
|
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-
|
|
4287
|
+
//# sourceMappingURL=jsx-wrapper-wJs8wFGh.js.map
|