@ragable/sdk 0.7.9 → 0.8.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.
package/dist/index.mjs CHANGED
@@ -3896,6 +3896,99 @@ var RagableBrowserMailClient = class {
3896
3896
  return message;
3897
3897
  }
3898
3898
  };
3899
+ var RagableBrowserFunctionsClient = class {
3900
+ constructor(options, auth) {
3901
+ this.options = options;
3902
+ this.auth = auth;
3903
+ __publicField(this, "fetchImpl");
3904
+ this.fetchImpl = bindFetch(options.fetch);
3905
+ }
3906
+ requireWebsiteId() {
3907
+ const websiteId = this.options.websiteId?.trim();
3908
+ if (!websiteId) {
3909
+ throw new RagableError(
3910
+ "websiteId is required for functions. Use createWebsiteRagableClient()/createAppClient() or pass createBrowserClient({ websiteId, ... }).",
3911
+ 400,
3912
+ { code: "SDK_MISSING_WEBSITE_ID" }
3913
+ );
3914
+ }
3915
+ return websiteId;
3916
+ }
3917
+ toUrl(name) {
3918
+ const orgId = this.options.organizationId;
3919
+ const websiteId = this.requireWebsiteId();
3920
+ return `${normalizeBrowserApiBase()}/public/organizations/${orgId}/websites/${websiteId}/functions/${encodeURIComponent(
3921
+ name
3922
+ )}/invoke`;
3923
+ }
3924
+ /**
3925
+ * Best-effort end-user bearer, forwarded to the function as `context.auth.token`.
3926
+ * Functions are public, so this never throws — anonymous calls send no token.
3927
+ */
3928
+ async getOptionalToken() {
3929
+ if (this.auth) {
3930
+ const token = await this.auth.getValidAccessToken().catch(() => null);
3931
+ if (token) return token;
3932
+ }
3933
+ const caller = await Promise.resolve(this.options.getAccessToken?.()).catch(
3934
+ () => null
3935
+ );
3936
+ if (typeof caller === "string" && caller.trim()) return caller.trim();
3937
+ const staticKey = this.options.dataStaticKey?.trim();
3938
+ if (staticKey) return staticKey;
3939
+ return null;
3940
+ }
3941
+ /**
3942
+ * Invoke a function by name. Prefer the typed `client.functions.<name>(input)`
3943
+ * accessors; use this when the name is dynamic.
3944
+ */
3945
+ async invoke(name, input, options) {
3946
+ const fnName = String(name ?? "").trim();
3947
+ if (!fnName) {
3948
+ throw new RagableError(
3949
+ "functions.invoke requires a function name",
3950
+ 400,
3951
+ { code: "SDK_MISSING_FUNCTION_NAME" }
3952
+ );
3953
+ }
3954
+ const headers = new Headers(options?.headers ?? this.options.headers);
3955
+ headers.set("Content-Type", "application/json");
3956
+ const token = await this.getOptionalToken();
3957
+ if (token) headers.set("Authorization", `Bearer ${token}`);
3958
+ const response = await this.fetchImpl(this.toUrl(fnName), {
3959
+ method: "POST",
3960
+ headers,
3961
+ body: JSON.stringify({ input: input ?? null }),
3962
+ ...options?.signal ? { signal: options.signal } : {}
3963
+ });
3964
+ const payload = await parseMaybeJsonBody(response);
3965
+ if (!response.ok) {
3966
+ const message = extractErrorMessage(payload, response.statusText);
3967
+ throw new RagableError(message, response.status, payload);
3968
+ }
3969
+ if (payload && typeof payload === "object" && !Array.isArray(payload) && "result" in payload) {
3970
+ return payload.result;
3971
+ }
3972
+ return payload;
3973
+ }
3974
+ /** Build the typed Proxy exposed as `client.functions`. */
3975
+ asInvoker() {
3976
+ const invoke = this.invoke.bind(this);
3977
+ return new Proxy(
3978
+ {},
3979
+ {
3980
+ get: (_target, prop) => {
3981
+ if (typeof prop !== "string") return void 0;
3982
+ if (prop === "then") return void 0;
3983
+ if (prop === "invoke") {
3984
+ return (name, input, options) => invoke(name, input, options);
3985
+ }
3986
+ return (input, options) => invoke(prop, input, options);
3987
+ }
3988
+ }
3989
+ );
3990
+ }
3991
+ };
3899
3992
  var RagableBrowserAgentsClient = class {
3900
3993
  constructor(options) {
3901
3994
  this.options = options;
@@ -4223,6 +4316,11 @@ var RagableBrowser = class {
4223
4316
  __publicField(this, "db");
4224
4317
  __publicField(this, "storage");
4225
4318
  __publicField(this, "mail");
4319
+ /**
4320
+ * Backend edge functions — call a `/functions/<name>.ts` handler with
4321
+ * `client.functions.<name>(input)`. Runs server-side. See {@link FunctionInvoker}.
4322
+ */
4323
+ __publicField(this, "functions");
4226
4324
  __publicField(this, "transport");
4227
4325
  __publicField(this, "_ragableAuth");
4228
4326
  /** Delegates to `database.from()`. Kept for back-compat — prefer `database.from()`. */
@@ -4269,6 +4367,10 @@ var RagableBrowser = class {
4269
4367
  this.db = this.database;
4270
4368
  this.storage = new RagableBrowserStorageClient(options, bindFetch(options.fetch));
4271
4369
  this.mail = new RagableBrowserMailClient(options, this._ragableAuth);
4370
+ this.functions = new RagableBrowserFunctionsClient(
4371
+ options,
4372
+ this._ragableAuth
4373
+ ).asInvoker();
4272
4374
  }
4273
4375
  destroy() {
4274
4376
  this._ragableAuth?.destroy();
@@ -4309,6 +4411,7 @@ export {
4309
4411
  RagableBrowserAiClient,
4310
4412
  RagableBrowserAuthClient,
4311
4413
  RagableBrowserDatabaseClient,
4414
+ RagableBrowserFunctionsClient,
4312
4415
  RagableBrowserMailClient,
4313
4416
  RagableBrowserStorageClient,
4314
4417
  RagableError,