@superblocksteam/library 2.0.99 → 2.0.100-next.1

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 api_hmr_tracker_default } from "../jsx-wrapper-esyZ2hyZ.js";
1
+ import { _ as root_store_default, t as makeWrappedComponent, x as api_hmr_tracker_default } from "../jsx-wrapper-aSZhsulk.js";
2
2
  import { SOURCE_ID_ATTRIBUTE } from "@superblocksteam/library-shared";
3
3
  import * as ReactJsxDevRuntime from "react/jsx-dev-runtime";
4
4
 
@@ -2081,6 +2081,25 @@ const decodeBytestringsInV2ExecutionResponse = (response) => {
2081
2081
 
2082
2082
  //#endregion
2083
2083
  //#region src/lib/internal-details/lib/features/file-utils.ts
2084
+ function isNativeFile(value) {
2085
+ return typeof File !== "undefined" && value instanceof File;
2086
+ }
2087
+ function isFileLike(value) {
2088
+ if (isNativeFile(value)) return true;
2089
+ if (typeof value !== "object" || value == null) return false;
2090
+ return typeof value.name === "string" && typeof value.size === "number" && typeof value.type === "string" && typeof value.lastModified === "number" && typeof value.arrayBuffer === "function";
2091
+ }
2092
+ function isPathOnlyFileDescriptor(value) {
2093
+ if (typeof value !== "object" || value == null) return false;
2094
+ return typeof value.path === "string" && typeof value.arrayBuffer !== "function";
2095
+ }
2096
+ function bytesToBase64(bytes) {
2097
+ if (typeof Buffer !== "undefined") return Buffer.from(bytes).toString("base64");
2098
+ let binary = "";
2099
+ const chunkSize = 32768;
2100
+ for (let i = 0; i < bytes.length; i += chunkSize) binary += String.fromCharCode(...bytes.subarray(i, i + chunkSize));
2101
+ return btoa(binary);
2102
+ }
2084
2103
  function getFileUploadId(file) {
2085
2104
  return `${file.name.replace(/[^a-zA-Z0-9.-]/g, "_")}-${file.size}-${file.lastModified}`;
2086
2105
  }
@@ -2100,25 +2119,28 @@ function getFileInputData(f) {
2100
2119
  async function formatFileForRequest(file, fileId) {
2101
2120
  return {
2102
2121
  originalName: fileId,
2103
- buffer: await new Promise((resolve, reject) => {
2122
+ buffer: typeof file.arrayBuffer === "function" ? bytesToBase64(new Uint8Array(await file.arrayBuffer())) : await new Promise((resolve, reject) => {
2104
2123
  const reader = new FileReader();
2105
2124
  reader.onload = () => resolve(reader.result.split(",")[1]);
2106
2125
  reader.onerror = () => reject(new Error(reader.error?.message || "Unknown error reading file"));
2107
2126
  reader.readAsDataURL(file);
2108
2127
  }),
2109
2128
  encoding: "base64",
2110
- mimetype: "text/plain"
2129
+ mimeType: file.type || "application/octet-stream",
2130
+ size: String(file.size)
2111
2131
  };
2112
2132
  }
2113
2133
  async function getInputsWithFileMetadata(inputs) {
2114
2134
  const filesForRequest = {};
2115
2135
  const processValue = async (value) => {
2116
2136
  if (value === void 0) return null;
2117
- if (value instanceof File) {
2137
+ if (isFileLike(value)) {
2118
2138
  const inputData = getFileInputData(value);
2119
2139
  if (!filesForRequest[inputData.$superblocksId]) filesForRequest[inputData.$superblocksId] = await formatFileForRequest(value, inputData.$superblocksId);
2120
2140
  return inputData;
2121
- } else if (Array.isArray(value)) return await Promise.all(value.map((item) => processValue(item)));
2141
+ }
2142
+ if (isPathOnlyFileDescriptor(value)) throw new Error("File upload inputs must be browser File objects (or compatible file-like objects with arrayBuffer()). Received a path-only file descriptor instead.");
2143
+ else if (Array.isArray(value)) return await Promise.all(value.map((item) => processValue(item)));
2122
2144
  else if (typeof value === "object" && value != null && value.constructor === Object) return await processObject(value);
2123
2145
  return value;
2124
2146
  };
@@ -2178,6 +2200,11 @@ var ApiManager = class {
2178
2200
  * round-trip. Empty for cloud orgs.
2179
2201
  */
2180
2202
  _agents = [];
2203
+ /**
2204
+ * DP routing config mapping profile keys to DP URLs, sent by the parent.
2205
+ * Only populated when dataPlaneGatewayEnabled is true.
2206
+ */
2207
+ _dpRoutingConfig = {};
2181
2208
  token;
2182
2209
  accessToken;
2183
2210
  runningApiControllers = {};
@@ -2197,6 +2224,9 @@ var ApiManager = class {
2197
2224
  set agents(agents) {
2198
2225
  this._agents = agents;
2199
2226
  }
2227
+ set dpRoutingConfig(config) {
2228
+ this._dpRoutingConfig = config;
2229
+ }
2200
2230
  setTokens(token, accessToken) {
2201
2231
  this.token = token;
2202
2232
  this.accessToken = accessToken;
@@ -2360,7 +2390,14 @@ var ApiManager = class {
2360
2390
  };
2361
2391
  }
2362
2392
  const profileKey = context$1.profiles?.selected?.key ?? "staging";
2363
- const agentBaseUrl = this.getRandomAgentBaseUrl(profileKey);
2393
+ const agentBaseUrl = (() => {
2394
+ if (this.rootStore.dataPlaneGatewayEnabled) {
2395
+ const dpUrl = this._dpRoutingConfig[profileKey];
2396
+ if (dpUrl) return withTrailingSlash(dpUrl);
2397
+ return this._agentUrls[0] ? withTrailingSlash(this._agentUrls[0]) : this.getRandomAgentBaseUrl(profileKey);
2398
+ }
2399
+ return this.getRandomAgentBaseUrl(profileKey);
2400
+ })();
2364
2401
  if (!agentBaseUrl) {
2365
2402
  sendNotification({
2366
2403
  message: "No active agent found",
@@ -2396,6 +2433,7 @@ var ApiManager = class {
2396
2433
  }
2397
2434
  }, "*");
2398
2435
  });
2436
+ if (authResult?.tokens?.token && authResult?.tokens?.accessToken) this.setTokens(authResult.tokens.token, authResult.tokens.accessToken);
2399
2437
  if (authResult?.errors && authResult.errors.length > 0) console.error("API Authentication returned with errors", authResult.errors);
2400
2438
  const { traceHeaders, ...restArgs } = options;
2401
2439
  const { inputs: finalInputs, files } = await getInputsWithFileMetadata({
@@ -2545,7 +2583,7 @@ var ApiManager = class {
2545
2583
  * Reads execution context (profile, branch, tokens) from rootStore so the
2546
2584
  * caller doesn't need to resolve them through the parent frame.
2547
2585
  */
2548
- async executeSdkApiV3(apiName, inputs) {
2586
+ async executeSdkApiV3(apiName, inputs, options) {
2549
2587
  const applicationId = this.rootStore.applicationId;
2550
2588
  if (!applicationId) return {
2551
2589
  success: false,
@@ -2554,43 +2592,77 @@ var ApiManager = class {
2554
2592
  message: "No application ID found"
2555
2593
  }
2556
2594
  };
2557
- await this.rootStore.awaitDiscovery();
2558
- const entryPoint = this.rootStore.getApiEntryPoint(apiName);
2559
- if (!entryPoint) return {
2560
- success: false,
2561
- error: {
2562
- code: "UNKNOWN_API",
2563
- message: `No entryPoint registered for API "${apiName}". Was it discovered?`
2595
+ const abortController = new AbortController();
2596
+ this.runningApiControllers[apiName]?.abort();
2597
+ this.runningApiControllers[apiName] = abortController;
2598
+ const forwardAbort = () => abortController.abort();
2599
+ if (options?.signal) if (options.signal.aborted) abortController.abort();
2600
+ else options.signal.addEventListener("abort", forwardAbort, { once: true });
2601
+ try {
2602
+ let entryPoint = this.rootStore.getApiEntryPoint(apiName);
2603
+ if (!entryPoint) {
2604
+ await this.rootStore.awaitDiscovery();
2605
+ entryPoint = this.rootStore.getApiEntryPoint(apiName);
2564
2606
  }
2565
- };
2566
- const profile = this.rootStore.profile;
2567
- const branchName = this.rootStore.branchName;
2568
- const commitId = this.rootStore.commitId;
2569
- const editMode$1 = isEditMode();
2570
- const appMode$1 = getAppMode();
2571
- const viewMode = editMode$1 ? ViewMode.EDITOR : appMode$1 === AppMode.PREVIEW ? ViewMode.PREVIEW : ViewMode.DEPLOYED;
2572
- const profileKey = profile?.key ?? "default";
2573
- const agentBaseUrl = this.getRandomAgentBaseUrl(profileKey);
2574
- if (!agentBaseUrl) return {
2575
- success: false,
2576
- error: {
2577
- code: "NO_AGENT",
2578
- message: "Unable to resolve agent for API execution"
2607
+ if (!entryPoint) return {
2608
+ success: false,
2609
+ error: {
2610
+ code: "UNKNOWN_API",
2611
+ message: `No entryPoint registered for API "${apiName}". Was it discovered?`
2612
+ }
2613
+ };
2614
+ await this.rootStore.editStore?.operationManager.ensureFilesSynced();
2615
+ const profile = this.rootStore.profile;
2616
+ const branchName = this.rootStore.branchName;
2617
+ const commitId = this.rootStore.commitId;
2618
+ const editMode$1 = isEditMode();
2619
+ const appMode$1 = getAppMode();
2620
+ const viewMode = editMode$1 ? ViewMode.EDITOR : appMode$1 === AppMode.PREVIEW ? ViewMode.PREVIEW : ViewMode.DEPLOYED;
2621
+ const profileKey = profile?.key ?? "default";
2622
+ const agentBaseUrl = (() => {
2623
+ if (this.rootStore.dataPlaneGatewayEnabled) {
2624
+ const dpUrl = this._dpRoutingConfig[profileKey];
2625
+ if (dpUrl) return withTrailingSlash(dpUrl);
2626
+ return this._agentUrls[0] ? withTrailingSlash(this._agentUrls[0]) : this.getRandomAgentBaseUrl(profileKey);
2627
+ }
2628
+ return this.getRandomAgentBaseUrl(profileKey);
2629
+ })();
2630
+ if (!agentBaseUrl) return {
2631
+ success: false,
2632
+ error: {
2633
+ code: "NO_AGENT",
2634
+ message: "Unable to resolve agent for API execution"
2635
+ }
2636
+ };
2637
+ const { inputs: finalInputs, files } = await getInputsWithFileMetadata(inputs);
2638
+ const body = {
2639
+ applicationId,
2640
+ inputs: finalInputs,
2641
+ viewMode,
2642
+ entryPoint
2643
+ };
2644
+ if (files.length > 0) body.files = files;
2645
+ if (profile) body.profile = profile;
2646
+ if (editMode$1) {
2647
+ if (branchName) body.branchName = branchName;
2648
+ body.includeDiagnostics = true;
2649
+ }
2650
+ if (!editMode$1 && commitId) body.commitId = commitId;
2651
+ const integrationIds = (this.rootStore.getApiIntegrations(apiName) ?? []).map((integration) => integration.id);
2652
+ if (integrationIds.length > 0) {
2653
+ const authResult = await new Promise((resolve) => {
2654
+ const callbackId = addNewPromise(resolve);
2655
+ window.parent.postMessage({
2656
+ type: "authenticate-api-request",
2657
+ payload: {
2658
+ apiId: apiName,
2659
+ callbackId,
2660
+ integrationIds
2661
+ }
2662
+ }, "*");
2663
+ });
2664
+ if (authResult?.errors?.length > 0) console.error("SDK API authentication returned with errors", authResult.errors);
2579
2665
  }
2580
- };
2581
- const body = {
2582
- applicationId,
2583
- inputs,
2584
- viewMode,
2585
- entryPoint
2586
- };
2587
- if (profile) body.profile = profile;
2588
- if (editMode$1) {
2589
- if (branchName) body.branchName = branchName;
2590
- body.includeDiagnostics = true;
2591
- }
2592
- if (!editMode$1 && commitId) body.commitId = commitId;
2593
- try {
2594
2666
  const response = await fetch(`${agentBaseUrl}v3/execute`, {
2595
2667
  method: "POST",
2596
2668
  headers: {
@@ -2599,7 +2671,8 @@ var ApiManager = class {
2599
2671
  Authorization: `Bearer ${this.token}`,
2600
2672
  [SUPERBLOCKS_REQUEST_ID_HEADER]: generateId()
2601
2673
  },
2602
- body: JSON.stringify(body)
2674
+ body: JSON.stringify(body),
2675
+ signal: abortController.signal
2603
2676
  });
2604
2677
  if (!response.ok) {
2605
2678
  const text = await response.text();
@@ -2633,6 +2706,14 @@ var ApiManager = class {
2633
2706
  diagnostics: result.diagnostics
2634
2707
  };
2635
2708
  } catch (error) {
2709
+ if (error instanceof Error && error.name === "AbortError") return {
2710
+ success: false,
2711
+ error: {
2712
+ code: "ABORTED",
2713
+ message: `API "${apiName}" execution was aborted`
2714
+ }
2715
+ };
2716
+ console.error(`[api-store] executeSdkApiV3 failed for "${apiName}":`, error);
2636
2717
  return {
2637
2718
  success: false,
2638
2719
  error: {
@@ -2640,6 +2721,9 @@ var ApiManager = class {
2640
2721
  message: error instanceof Error ? error.message : "Network error occurred"
2641
2722
  }
2642
2723
  };
2724
+ } finally {
2725
+ options?.signal?.removeEventListener("abort", forwardAbort);
2726
+ if (this.runningApiControllers[apiName] === abortController) delete this.runningApiControllers[apiName];
2643
2727
  }
2644
2728
  }
2645
2729
  @action async cancelApi(apiName, _scopeId) {
@@ -2650,7 +2734,7 @@ var ApiManager = class {
2650
2734
  }
2651
2735
  abortController.abort();
2652
2736
  delete this.runningApiControllers[apiName];
2653
- editorBridge.setApiResponse(apiName, {
2737
+ if (!(this.rootStore.sdkApiEnabled || !!this.rootStore.getApiEntryPoint(apiName))) editorBridge.setApiResponse(apiName, {
2654
2738
  status: "STATUS_CANCELLED",
2655
2739
  execution: null,
2656
2740
  events: [],
@@ -3189,6 +3273,12 @@ var RootStore = class {
3189
3273
  * When false, the YAML-based API system is used instead.
3190
3274
  */
3191
3275
  sdkApiEnabled = false;
3276
+ /**
3277
+ * Whether execute requests should be routed through the data plane gateway
3278
+ * endpoint instead of direct agent URLs.
3279
+ * Passed to the library via the ui.data-plane-gateway.enabled bootstrap flag.
3280
+ */
3281
+ dataPlaneGatewayEnabled = false;
3192
3282
  /** Selected integration profile for orchestrator API calls */
3193
3283
  profile;
3194
3284
  /** Current git branch name for editor-mode API execution */
@@ -3202,6 +3292,11 @@ var RootStore = class {
3202
3292
  */
3203
3293
  apiEntryPoints = /* @__PURE__ */ new Map();
3204
3294
  /**
3295
+ * Maps API name → statically declared integrations.
3296
+ * Populated during edit-mode discovery and from the deployed build manifest.
3297
+ */
3298
+ apiIntegrations = /* @__PURE__ */ new Map();
3299
+ /**
3205
3300
  * Resolves when the initial SDK API discovery pass completes.
3206
3301
  * executeSdkApiV3 awaits this so callers don't race against discovery.
3207
3302
  */
@@ -3221,6 +3316,8 @@ var RootStore = class {
3221
3316
  setSdkUser: action,
3222
3317
  sdkApiEnabled: observable,
3223
3318
  setSdkApiEnabled: action,
3319
+ dataPlaneGatewayEnabled: observable,
3320
+ setDataPlaneGatewayEnabled: action,
3224
3321
  profile: observable.ref,
3225
3322
  setProfile: action,
3226
3323
  branchName: observable,
@@ -3254,6 +3351,9 @@ var RootStore = class {
3254
3351
  this.sdkApiEnabled = enabled;
3255
3352
  if (enabled && !this._resolveDiscovery) this.initDiscoveryGate();
3256
3353
  }
3354
+ setDataPlaneGatewayEnabled(enabled) {
3355
+ this.dataPlaneGatewayEnabled = enabled;
3356
+ }
3257
3357
  setProfile(profile) {
3258
3358
  this.profile = profile;
3259
3359
  }
@@ -3272,6 +3372,15 @@ var RootStore = class {
3272
3372
  clearApiEntryPoints() {
3273
3373
  this.apiEntryPoints.clear();
3274
3374
  }
3375
+ setApiIntegrations(apiName, integrations) {
3376
+ this.apiIntegrations.set(apiName, integrations);
3377
+ }
3378
+ getApiIntegrations(apiName) {
3379
+ return this.apiIntegrations.get(apiName);
3380
+ }
3381
+ clearApiIntegrations() {
3382
+ this.apiIntegrations.clear();
3383
+ }
3275
3384
  /**
3276
3385
  * Initialise (or re-initialise) the discovery gate. Called when discovery
3277
3386
  * starts so that executeSdkApiV3 awaits before checking entry points.
@@ -3963,4 +4072,4 @@ const useJSXContext = () => {
3963
4072
 
3964
4073
  //#endregion
3965
4074
  export { useSuperblocksProfiles as A, createManagedPropsList as B, rejectById as C, useSuperblocksContext as D, getAppMode as E, editorBridge as F, getEditStore as G, PropsCategory as H, iframeMessageHandler as I, isEmbeddedBySuperblocksFirstParty as L, generateId as M, sendNotification as N, useSuperblocksDataTags as O, colors as P, sendMessageImmediately as R, addNewPromise as S, SuperblocksContextProvider as T, Section as U, Prop as V, createPropertiesPanelDefinition 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, getWidgetAnchorName as r, ErrorContainer as s, makeWrappedComponent as t, ErrorIconContainer as u, startEditorSync as v, resolveById as w, api_hmr_tracker_default as x, createIframeSpan as y, isEditMode as z };
3966
- //# sourceMappingURL=jsx-wrapper-esyZ2hyZ.js.map
4075
+ //# sourceMappingURL=jsx-wrapper-aSZhsulk.js.map