@oxy-hq/sdk 2.4.0 → 2.6.0

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.
@@ -30,7 +30,7 @@ let react = require("react");
30
30
  react = __toESM(react, 1);
31
31
  let react_jsx_runtime = require("react/jsx-runtime");
32
32
 
33
- //#region src/customer-app/logger.ts
33
+ //#region src/custom-app/logger.ts
34
34
  let activeLogger = createConsoleLogger();
35
35
  /** Replace the global logger. Pass `null` to silence everything. */
36
36
  function setOxyAppLogger(logger) {
@@ -70,9 +70,9 @@ function silentLogger() {
70
70
  }
71
71
 
72
72
  //#endregion
73
- //#region src/customer-app/errors.ts
73
+ //#region src/custom-app/errors.ts
74
74
  /**
75
- * Error thrown by all customer-app hooks when an API call returns a
75
+ * Error thrown by all custom-app hooks when an API call returns a
76
76
  * non-2xx response. Carries the structured `code` + `hint` the server
77
77
  * emits so bundle UIs can render an actionable message instead of
78
78
  * "404: { ...json... }".
@@ -119,12 +119,12 @@ async function apiErrorFromResponse(resp) {
119
119
  }
120
120
  const ARCH_DOC = "internal-docs/customer-apps.md";
121
121
  /** Interpret a thrown error as a structured report for UI display. */
122
- function interpretCustomerAppError(err) {
122
+ function interpretCustomAppError(err) {
123
123
  const message = err instanceof Error ? err.message : String(err);
124
124
  if (/Failed to load oxy-app\.json.*HTTP 404/.test(message)) return {
125
125
  title: "Manifest not found",
126
126
  message,
127
- hint: "The bundle is being served, but oxy-app.json was not. Check that public/oxy-app.json is committed in the customer-app repo and that the build copied it into the static output. If you're using Next.js, anything under public/ is auto-copied to out/.",
127
+ hint: "The bundle is being served, but oxy-app.json was not. Check that public/oxy-app.json is committed in the custom-app repo and that the build copied it into the static output. If you're using Next.js, anything under public/ is auto-copied to out/.",
128
128
  docs: ARCH_DOC
129
129
  };
130
130
  if (/Failed to load oxy-app\.json/.test(message)) return {
@@ -160,7 +160,7 @@ function interpretCustomerAppError(err) {
160
160
  if (/^403:.*SELECT.*WITH/im.test(message)) return {
161
161
  title: "Query rejected — read-only endpoint",
162
162
  message,
163
- hint: "This proxy only runs SELECT or WITH queries. Mutations (INSERT/UPDATE/DELETE/DROP) are not allowed from customer-app bundles.",
163
+ hint: "This proxy only runs SELECT or WITH queries. Mutations (INSERT/UPDATE/DELETE/DROP) are not allowed from custom-app bundles.",
164
164
  docs: ARCH_DOC
165
165
  };
166
166
  if (/^403:/m.test(message)) return {
@@ -196,7 +196,7 @@ function interpretCustomerAppError(err) {
196
196
  if (/Unexpected token '<'|<!doctype/i.test(message)) return {
197
197
  title: "Fetched HTML where JSON was expected",
198
198
  message,
199
- hint: "Most likely the built bundle is stale — built against an old SDK whose endpoints no longer exist on the server. Rebuild the bundle (vite build) with @oxy-hq/sdk@^2.0.0 and reload. If the bundle is current, check that OXY_APP_BASE_PATH matches the path the customer-app row is served at.",
199
+ hint: "Most likely the built bundle is stale — built against an old SDK whose endpoints no longer exist on the server. Rebuild the bundle (vite build) with @oxy-hq/sdk@^2.0.0 and reload. If the bundle is current, check that OXY_APP_BASE_PATH matches the path the custom-app row is served at.",
200
200
  docs: ARCH_DOC
201
201
  };
202
202
  return {
@@ -208,7 +208,7 @@ function interpretCustomerAppError(err) {
208
208
  }
209
209
 
210
210
  //#endregion
211
- //#region src/customer-app/inject.ts
211
+ //#region src/custom-app/inject.ts
212
212
  /**
213
213
  * Read the runtime app-config oxy injected at serve time. Returns
214
214
  * `undefined` outside the browser or when the global isn't set
@@ -221,18 +221,18 @@ function readInjectedAppConfig() {
221
221
  }
222
222
 
223
223
  //#endregion
224
- //#region src/customer-app/manifest.ts
224
+ //#region src/custom-app/manifest.ts
225
225
  let cached = null;
226
226
  /**
227
227
  * Load + validate the manifest. Cached after the first call so callers
228
228
  * can invoke this from every component without coordinating.
229
229
  */
230
- function loadCustomerAppManifest(options = {}) {
230
+ function loadCustomAppManifest(options = {}) {
231
231
  if (!cached) cached = fetchAndValidate(options);
232
232
  return cached;
233
233
  }
234
234
  /** For tests: reset the cache between runs. */
235
- function _resetCustomerAppManifestCacheForTest() {
235
+ function _resetCustomAppManifestCacheForTest() {
236
236
  cached = null;
237
237
  }
238
238
  async function fetchAndValidate(options) {
@@ -254,7 +254,7 @@ async function fetchAndValidate(options) {
254
254
  status: res.status,
255
255
  statusText: res.statusText
256
256
  });
257
- throw new Error(`Failed to load oxy-app.json from ${manifestUrl} (HTTP ${res.status}). The customer-app repo must commit this file alongside the bundle.`);
257
+ throw new Error(`Failed to load oxy-app.json from ${manifestUrl} (HTTP ${res.status}). The custom-app repo must commit this file alongside the bundle.`);
258
258
  }
259
259
  const manifest = validateManifest(await res.json(), manifestUrl);
260
260
  const resolved = {
@@ -319,7 +319,7 @@ const FUNCTION_NAME_RE = /^[a-z][a-z0-9-]{0,63}$/;
319
319
  /**
320
320
  * Validate the optional `functions` map. Each key is a function name;
321
321
  * each value declares how the function is invoked. Mirrors the
322
- * server-side validation in `customer_apps_publish.rs` so a bad
322
+ * server-side validation in `custom_apps_publish.rs` so a bad
323
323
  * manifest fails at build, not at publish.
324
324
  */
325
325
  function validateFunctions(raw) {
@@ -397,7 +397,7 @@ function isRecord(v) {
397
397
  }
398
398
 
399
399
  //#endregion
400
- //#region src/customer-app/function-invoke.ts
400
+ //#region src/custom-app/function-invoke.ts
401
401
  const inflight$1 = /* @__PURE__ */ new Map();
402
402
  /**
403
403
  * Dedup key for an invocation: function name + its (stable-serialized) body,
@@ -423,7 +423,7 @@ function sharedFunctionInvoke(key, run) {
423
423
  }
424
424
 
425
425
  //#endregion
426
- //#region src/customer-app/function-sse.ts
426
+ //#region src/custom-app/function-sse.ts
427
427
  /**
428
428
  * Read a `text/event-stream` function response to completion. Resolves with the
429
429
  * decoded result + captured logs, or rejects (with `.logs` attached) on an
@@ -480,7 +480,7 @@ async function readFunctionSseStream(resp) {
480
480
  }
481
481
 
482
482
  //#endregion
483
- //#region src/customer-app/interpolate.ts
483
+ //#region src/custom-app/interpolate.ts
484
484
  /**
485
485
  * Interpolate `{{ params.X }}` and `{{ params.X | sqlquote }}` placeholders
486
486
  * in a SQL template.
@@ -509,7 +509,7 @@ function interpolateSqlParams(sql, params) {
509
509
  }
510
510
 
511
511
  //#endregion
512
- //#region src/customer-app/markdown.ts
512
+ //#region src/custom-app/markdown.ts
513
513
  /**
514
514
  * Allowlist for `[text](url)` href values in agent-emitted markdown.
515
515
  * Markdown comes from an LLM, which sits across an external trust
@@ -585,7 +585,7 @@ function isTableStart(lines, idx) {
585
585
  }
586
586
 
587
587
  //#endregion
588
- //#region src/customer-app/query-cache.ts
588
+ //#region src/custom-app/query-cache.ts
589
589
  const SWR_TTL_MS = 3e4;
590
590
  const inflight = /* @__PURE__ */ new Map();
591
591
  const cache = /* @__PURE__ */ new Map();
@@ -629,28 +629,48 @@ async function sharedQuery(fetcher, projectId, sql, db, opts = {}) {
629
629
  }
630
630
 
631
631
  //#endregion
632
- //#region src/customer-app/react.tsx
632
+ //#region src/custom-app/react.tsx
633
633
  function defaultFetcher(input, init) {
634
634
  return fetch(input, {
635
635
  credentials: "include",
636
636
  ...init
637
637
  });
638
638
  }
639
+ /**
640
+ * Resolve relative ("/…") request paths against `backendUrl` so the SDK's API
641
+ * calls reach a cross-origin oxy backend instead of the app's own origin.
642
+ *
643
+ * This is what lets a standalone dev app (e.g. served on `localhost:3005`)
644
+ * drive the wired shell — `shell-context`, Ask Oxygen agent asks, events —
645
+ * against oxy on another origin (`localhost:3000`) WITHOUT a same-origin dev
646
+ * proxy. The target origin must permit the app's origin (oxy's main `/api`
647
+ * allows configured dev origins + `credentials`); the external data API is a
648
+ * separate, wildcard-CORS surface.
649
+ *
650
+ * Opt-in: when `backendUrl` is unset the base fetcher is returned unchanged, so
651
+ * apps served same-origin by oxy keep their existing relative-URL behaviour.
652
+ * Absolute URLs and non-string inputs pass through untouched (no double-prefix).
653
+ */
654
+ function withBackendBase(base, backendUrl) {
655
+ if (!backendUrl) return base;
656
+ const origin = backendUrl.replace(/\/+$/, "");
657
+ return (input, init) => base(typeof input === "string" && input.startsWith("/") ? origin + input : input, init);
658
+ }
639
659
  const OxyAppContext = react.createContext(void 0);
640
660
  /**
641
661
  * Top-level provider. Loads the manifest once on mount; children only
642
662
  * render after the manifest is ready (or the error fallback fires).
643
663
  */
644
664
  function OxyAppProvider(props) {
645
- const { manifestOptions, fallback, errorFallback, fetcher: fetcherProp, children } = props;
646
- const fetcher = fetcherProp ?? defaultFetcher;
665
+ const { manifestOptions, fallback, errorFallback, fetcher: fetcherProp, backendUrl, children } = props;
666
+ const fetcher = react.useMemo(() => withBackendBase(fetcherProp ?? defaultFetcher, backendUrl), [fetcherProp, backendUrl]);
647
667
  const [state, setState] = react.useState({
648
668
  status: "loading",
649
669
  fetcher
650
670
  });
651
671
  react.useEffect(() => {
652
672
  let cancelled = false;
653
- loadCustomerAppManifest(manifestOptions).then((resolved) => {
673
+ loadCustomAppManifest(manifestOptions).then((resolved) => {
654
674
  if (!cancelled) setState({
655
675
  status: "ready",
656
676
  resolved,
@@ -659,7 +679,7 @@ function OxyAppProvider(props) {
659
679
  }).catch((e) => {
660
680
  if (!cancelled) setState({
661
681
  status: "error",
662
- error: interpretCustomerAppError(e),
682
+ error: interpretCustomAppError(e),
663
683
  fetcher
664
684
  });
665
685
  });
@@ -761,7 +781,7 @@ function useOxyApp() {
761
781
  }
762
782
  /**
763
783
  * Execute an ad-hoc SQL query against the project linked to this
764
- * customer app. The query is specified inline by the caller; no
784
+ * custom app. The query is specified inline by the caller; no
765
785
  * manifest declaration is involved.
766
786
  *
767
787
  * Re-runs whenever `input` or enabled `params` change. Use the
@@ -2292,10 +2312,10 @@ Object.defineProperty(exports, '__toESM', {
2292
2312
  return __toESM;
2293
2313
  }
2294
2314
  });
2295
- Object.defineProperty(exports, '_resetCustomerAppManifestCacheForTest', {
2315
+ Object.defineProperty(exports, '_resetCustomAppManifestCacheForTest', {
2296
2316
  enumerable: true,
2297
2317
  get: function () {
2298
- return _resetCustomerAppManifestCacheForTest;
2318
+ return _resetCustomAppManifestCacheForTest;
2299
2319
  }
2300
2320
  });
2301
2321
  Object.defineProperty(exports, 'apiErrorFromResponse', {
@@ -2310,16 +2330,16 @@ Object.defineProperty(exports, 'getOxyAppLogger', {
2310
2330
  return getOxyAppLogger;
2311
2331
  }
2312
2332
  });
2313
- Object.defineProperty(exports, 'interpretCustomerAppError', {
2333
+ Object.defineProperty(exports, 'interpretCustomAppError', {
2314
2334
  enumerable: true,
2315
2335
  get: function () {
2316
- return interpretCustomerAppError;
2336
+ return interpretCustomAppError;
2317
2337
  }
2318
2338
  });
2319
- Object.defineProperty(exports, 'loadCustomerAppManifest', {
2339
+ Object.defineProperty(exports, 'loadCustomAppManifest', {
2320
2340
  enumerable: true,
2321
2341
  get: function () {
2322
- return loadCustomerAppManifest;
2342
+ return loadCustomAppManifest;
2323
2343
  }
2324
2344
  });
2325
2345
  Object.defineProperty(exports, 'readInjectedAppConfig', {
@@ -2382,4 +2402,4 @@ Object.defineProperty(exports, 'useTrackEvent', {
2382
2402
  return useTrackEvent;
2383
2403
  }
2384
2404
  });
2385
- //# sourceMappingURL=react-B7Blpmt7.cjs.map
2405
+ //# sourceMappingURL=react-BAiiXftp.cjs.map