@ragable/sdk 0.8.1 → 0.8.3

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.d.mts CHANGED
@@ -662,6 +662,265 @@ declare class PostgrestTableApi<Database extends RagableDatabase = DefaultRagabl
662
662
  upsert(values: TableInsertRow<Database, TableName> | TableInsertRow<Database, TableName>[], options: PostgrestUpsertOptions): PostgrestUpsertRootBuilder<TableRow<Database, TableName>>;
663
663
  }
664
664
 
665
+ /**
666
+ * Supabase-style chainable query builders for Ragable collections.
667
+ *
668
+ * ```ts
669
+ * const { data, error } = await client.db.collections.todos
670
+ * .select("*")
671
+ * .eq("done", false)
672
+ * .order("createdAt", { ascending: false })
673
+ * .limit(20);
674
+ * ```
675
+ *
676
+ * Rows come back **flat**: the JSON document's fields at the top level with the
677
+ * record envelope merged in (`id`, `createdAt`, `updatedAt` — envelope wins on
678
+ * name collisions).
679
+ */
680
+ /** A collection record as returned by the chainable builders. */
681
+ type CollectionRow<Row extends Record<string, unknown> = Record<string, unknown>> = Omit<Row, "id" | "createdAt" | "updatedAt"> & {
682
+ id: string;
683
+ createdAt: string;
684
+ updatedAt: string;
685
+ };
686
+ interface RecordEnvelope {
687
+ id: string;
688
+ data: Record<string, unknown>;
689
+ createdAt: string;
690
+ updatedAt: string;
691
+ }
692
+ interface CollectionSelectedEmbed {
693
+ /** Row key the embedded value lands under (defaults to the collection name). */
694
+ alias: string;
695
+ collection: string;
696
+ /** Linking field (`!hint`); when omitted the server infers it from schemas/conventions. */
697
+ hint?: string;
698
+ /** Projection of the embedded rows' fields (null = all). */
699
+ columns: string[] | null;
700
+ }
701
+ interface CollectionSelectedAggregate {
702
+ fn: "count" | "sum" | "avg" | "min" | "max";
703
+ field?: string;
704
+ alias: string;
705
+ }
706
+ interface ParsedSelectExpression {
707
+ /** Plain fields (group keys when aggregates are present); null = `*`. */
708
+ fields: string[] | null;
709
+ embeds: CollectionSelectedEmbed[];
710
+ aggregates: CollectionSelectedAggregate[];
711
+ }
712
+ /**
713
+ * Parse a `select()` string into plain columns, relation embeds, and
714
+ * aggregates (Supabase grammar):
715
+ *
716
+ * - `"*, author:users!author_id(name,avatar_url), comments(*)"` — embeds
717
+ * - `"category, count(), total:amount.sum()"` — aggregation grouped by `category`
718
+ */
719
+ declare function parseSelectExpression(columns: string | undefined): ParsedSelectExpression;
720
+ /**
721
+ * Transport bound to one collection: `path` is relative to the collection
722
+ * (e.g. `"/find"`, `"/records"`). Implemented by the database client.
723
+ */
724
+ type CollectionRequestFn = <T>(method: "GET" | "POST" | "PATCH" | "DELETE", path: string, body?: unknown, signal?: AbortSignal) => Promise<T>;
725
+ type CollectionFilterOp = "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "like" | "ilike" | "startsWith" | "endsWith" | "in" | "nin" | "contains" | "is" | "exists";
726
+ interface FilterEntry {
727
+ field: string;
728
+ op: CollectionFilterOp;
729
+ value: unknown;
730
+ not?: boolean;
731
+ }
732
+ /** Loose-but-helpful field name type: known row fields, envelope fields, or any string. */
733
+ type CollectionField<Row extends Record<string, unknown>> = Extract<keyof Row, string> | "id" | "createdAt" | "updatedAt" | (string & {});
734
+ /**
735
+ * Parse a Supabase-style `.or()` string into where-shaped OR groups.
736
+ * Top-level commas separate OR branches; `and(...)` groups conditions
737
+ * within one branch.
738
+ */
739
+ declare function parseOrString(input: string): Record<string, unknown>[];
740
+ declare abstract class CollectionConditionBuilder<Row extends Record<string, unknown>> {
741
+ protected filters: FilterEntry[];
742
+ protected orGroups: Record<string, unknown>[] | null;
743
+ protected signal?: AbortSignal;
744
+ /** `field = value` (or `IS NULL` when value is null). */
745
+ eq(field: CollectionField<Row>, value: unknown): this;
746
+ /** `field != value` (null-aware). */
747
+ neq(field: CollectionField<Row>, value: unknown): this;
748
+ gt(field: CollectionField<Row>, value: number | string): this;
749
+ gte(field: CollectionField<Row>, value: number | string): this;
750
+ lt(field: CollectionField<Row>, value: number | string): this;
751
+ lte(field: CollectionField<Row>, value: number | string): this;
752
+ /** SQL LIKE — you supply the `%` wildcards, e.g. `.like("title", "%report%")`. */
753
+ like(field: CollectionField<Row>, pattern: string): this;
754
+ /** Case-insensitive LIKE. */
755
+ ilike(field: CollectionField<Row>, pattern: string): this;
756
+ /** Prefix match; wildcard characters in `value` are matched literally. */
757
+ startsWith(field: CollectionField<Row>, value: string): this;
758
+ /** Suffix match; wildcard characters in `value` are matched literally. */
759
+ endsWith(field: CollectionField<Row>, value: string): this;
760
+ /** Value is one of `values`. */
761
+ in(field: CollectionField<Row>, values: unknown[]): this;
762
+ /** Value is NOT one of `values`. */
763
+ nin(field: CollectionField<Row>, values: unknown[]): this;
764
+ /**
765
+ * JSONB containment: array fields contain the given element(s), object
766
+ * fields contain the given key/value pairs.
767
+ * `.contains("tags", ["urgent"])`, `.contains("meta", { plan: "pro" })`.
768
+ */
769
+ contains(field: CollectionField<Row>, value: unknown): this;
770
+ /** Strict null / boolean check: `.is("archivedAt", null)`, `.is("done", true)`. */
771
+ is(field: CollectionField<Row>, value: null | boolean): this;
772
+ /** Whether the JSON key is present at all: `.exists("avatarUrl", false)`. */
773
+ exists(field: CollectionField<Row>, present?: boolean): this;
774
+ /** Negated condition: `.not("status", "eq", "archived")`. */
775
+ not(field: CollectionField<Row>, op: CollectionFilterOp, value: unknown): this;
776
+ /** Generic escape hatch, mirroring Supabase `.filter(column, op, value)`. */
777
+ filter(field: CollectionField<Row>, op: CollectionFilterOp, value: unknown): this;
778
+ /** Equality on every key of `query` (null values become IS NULL). */
779
+ match(query: Partial<Row> & Record<string, unknown>): this;
780
+ /**
781
+ * OR conditions, ANDed with the other filters. Accepts the Supabase string
782
+ * grammar — `.or('done.eq.true,priority.gte.3')`, with `and(...)` for a
783
+ * multi-condition branch — or an array of where-style objects:
784
+ * `.or([{ done: true }, { priority: { gte: 3 } }])`.
785
+ *
786
+ * One `.or()` per query: the wire format carries a single disjunction.
787
+ */
788
+ or(conditions: string | Record<string, unknown>[]): this;
789
+ abortSignal(signal: AbortSignal): this;
790
+ protected get hasConditions(): boolean;
791
+ protected wireFilters(): Array<Record<string, unknown>>;
792
+ private assertOp;
793
+ private push;
794
+ }
795
+ interface CollectionSelectOptions {
796
+ /** `"exact"` runs a COUNT(*) with the same filters; result lands on `count`. */
797
+ count?: "exact";
798
+ /** With `head: true`, no rows are fetched — only the count. */
799
+ head?: boolean;
800
+ }
801
+ /** List results carry `count` (populated when `{ count: "exact" }` was requested). */
802
+ type CollectionListResult<T> = {
803
+ data: T[];
804
+ error: null;
805
+ count: number | null;
806
+ } | {
807
+ data: null;
808
+ error: RagableError;
809
+ count: null;
810
+ };
811
+ declare class CollectionSelectBuilder<Row extends Record<string, unknown> = Record<string, unknown>, Out extends Record<string, unknown> = CollectionRow<Row>> extends CollectionConditionBuilder<Row> implements PromiseLike<CollectionListResult<Out>> {
812
+ private readonly request;
813
+ private _limit?;
814
+ private _offset?;
815
+ private _order;
816
+ private readonly parsed;
817
+ private readonly wantCount;
818
+ private readonly headOnly;
819
+ constructor(request: CollectionRequestFn, columns?: string, options?: CollectionSelectOptions);
820
+ /** Sort by a field. Call again to add secondary sort keys (max 4). */
821
+ order(field: CollectionField<Row>, options?: {
822
+ ascending?: boolean;
823
+ }): this;
824
+ limit(n: number): this;
825
+ offset(n: number): this;
826
+ /** Rows `from`..`to` inclusive (zero-based), like Supabase `.range()`. */
827
+ range(from: number, to: number): this;
828
+ then<TResult1 = CollectionListResult<Out>, TResult2 = never>(onfulfilled?: ((value: CollectionListResult<Out>) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
829
+ /**
830
+ * Exactly one row. 0 or >1 matching rows is an error (code PGRST116),
831
+ * mirroring Supabase `.single()`.
832
+ */
833
+ single(): Promise<PostgrestResult<Out>>;
834
+ /** One row or `null` — only >1 matching rows is an error. */
835
+ maybeSingle(): Promise<PostgrestResult<Out | null>>;
836
+ private buildBody;
837
+ /** Flatten the envelope and apply column + embedded-column projection. */
838
+ private shapeRow;
839
+ private executeRows;
840
+ private execute;
841
+ }
842
+ /**
843
+ * `.select()` stage of a mutation: resolves to the affected rows (flattened),
844
+ * with `single()` / `maybeSingle()` narrowing.
845
+ */
846
+ declare class CollectionMutationReturning<Row extends Record<string, unknown> = Record<string, unknown>> implements PromiseLike<PostgrestResult<CollectionRow<Row>[]>> {
847
+ private readonly run;
848
+ private readonly columns;
849
+ constructor(run: () => Promise<PostgrestResult<RecordEnvelope[]>>, columns: string[] | null);
850
+ then<TResult1 = PostgrestResult<CollectionRow<Row>[]>, TResult2 = never>(onfulfilled?: ((value: PostgrestResult<CollectionRow<Row>[]>) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
851
+ private executeMany;
852
+ single(): Promise<PostgrestResult<CollectionRow<Row>>>;
853
+ maybeSingle(): Promise<PostgrestResult<CollectionRow<Row> | null>>;
854
+ }
855
+ declare class CollectionUpdateBuilder<Row extends Record<string, unknown> = Record<string, unknown>> extends CollectionConditionBuilder<Row> implements PromiseLike<PostgrestResult<null>> {
856
+ private readonly request;
857
+ private readonly patch;
858
+ private _limit?;
859
+ constructor(request: CollectionRequestFn, patch: Record<string, unknown>);
860
+ limit(n: number): this;
861
+ select(columns?: string): CollectionMutationReturning<Row>;
862
+ then<TResult1 = PostgrestResult<null>, TResult2 = never>(onfulfilled?: ((value: PostgrestResult<null>) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
863
+ private execute;
864
+ }
865
+ declare class CollectionDeleteBuilder<Row extends Record<string, unknown> = Record<string, unknown>> extends CollectionConditionBuilder<Row> implements PromiseLike<PostgrestResult<null>> {
866
+ private readonly request;
867
+ private _limit?;
868
+ constructor(request: CollectionRequestFn);
869
+ limit(n: number): this;
870
+ select(columns?: string): CollectionMutationReturning<Row>;
871
+ then<TResult1 = PostgrestResult<null>, TResult2 = never>(onfulfilled?: ((value: PostgrestResult<null>) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
872
+ private execute;
873
+ }
874
+ /** A collection record envelope (`data` holds the JSON document). */
875
+ interface CollectionRecordEnvelope<Row extends Record<string, unknown> = Record<string, unknown>> {
876
+ id: string;
877
+ data: Row;
878
+ createdAt: string;
879
+ updatedAt: string;
880
+ }
881
+ /**
882
+ * Insert chain. Awaiting it directly resolves to the inserted record
883
+ * envelope(s) — a Ragable extension kept for back-compat (Supabase resolves to
884
+ * `null` without `.select()`). Chain `.select()` for flat rows.
885
+ */
886
+ declare class CollectionInsertChain<Row extends Record<string, unknown> = Record<string, unknown>, Resolved = CollectionRecordEnvelope<Row>> implements PromiseLike<PostgrestResult<Resolved>> {
887
+ private readonly request;
888
+ private readonly rows;
889
+ private readonly single;
890
+ private _signal?;
891
+ constructor(request: CollectionRequestFn, rows: Record<string, unknown>[], single: boolean);
892
+ abortSignal(signal: AbortSignal): this;
893
+ select(columns?: string): CollectionMutationReturning<Row>;
894
+ then<TResult1 = PostgrestResult<Resolved>, TResult2 = never>(onfulfilled?: ((value: PostgrestResult<Resolved>) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
895
+ private executeEnvelopes;
896
+ }
897
+ interface CollectionUpsertOptions {
898
+ /**
899
+ * Field to match existing records on: `"id"` (default) or a data field,
900
+ * e.g. `"slug"`. Collections have no unique indexes, so this is
901
+ * match-then-update: if several records share the value, all are updated.
902
+ */
903
+ onConflict?: string;
904
+ /** Skip items that match an existing record instead of updating them. */
905
+ ignoreDuplicates?: boolean;
906
+ }
907
+ interface CollectionUpsertSummary {
908
+ inserted: number;
909
+ updated: number;
910
+ skipped: number;
911
+ }
912
+ declare class CollectionUpsertBuilder<Row extends Record<string, unknown> = Record<string, unknown>> implements PromiseLike<PostgrestResult<CollectionUpsertSummary>> {
913
+ private readonly request;
914
+ private readonly rows;
915
+ private readonly options;
916
+ private _signal?;
917
+ constructor(request: CollectionRequestFn, rows: Record<string, unknown>[], options: CollectionUpsertOptions);
918
+ abortSignal(signal: AbortSignal): this;
919
+ select(columns?: string): CollectionMutationReturning<Row>;
920
+ then<TResult1 = PostgrestResult<CollectionUpsertSummary>, TResult2 = never>(onfulfilled?: ((value: PostgrestResult<CollectionUpsertSummary>) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
921
+ private execute;
922
+ }
923
+
665
924
  interface SessionStorage {
666
925
  getItem(key: string): string | null | Promise<string | null>;
667
926
  setItem(key: string, value: string): void | Promise<void>;
@@ -708,7 +967,9 @@ declare class AuthBroadcastChannel {
708
967
  close(): void;
709
968
  }
710
969
 
711
- type AuthChangeEvent = "INITIAL_SESSION" | "SIGNED_IN" | "SIGNED_OUT" | "TOKEN_REFRESHED" | "TOKEN_REFRESH_FAILED" | "USER_UPDATED";
970
+ type AuthChangeEvent = "INITIAL_SESSION" | "SIGNED_IN" | "SIGNED_OUT" | "TOKEN_REFRESHED" | "TOKEN_REFRESH_FAILED" | "PASSWORD_RECOVERY" | "USER_UPDATED";
971
+ /** Email token kinds accepted by {@link RagableAuth.verifyOtp}. `"email"` is an alias for `"magiclink"`. */
972
+ type AuthOtpType = "recovery" | "magiclink" | "email";
712
973
  type AuthUserMetadata = Record<string, unknown>;
713
974
  interface DefaultAuthUser<Metadata extends AuthUserMetadata = AuthUserMetadata> {
714
975
  id: string;
@@ -819,6 +1080,83 @@ declare class RagableAuth<U extends object = DefaultAuthUser> {
819
1080
  }): Promise<{
820
1081
  error: null;
821
1082
  }>;
1083
+ /**
1084
+ * Email a password-recovery link. The link points at `redirectTo` (or the
1085
+ * site's deployed domain when omitted) with `?token_hash=…&type=recovery`
1086
+ * appended. On that page, either:
1087
+ * - call {@link resetPassword} with the token and the new password, or
1088
+ * - call {@link verifyOtp} to sign the user in, then `updateUser({ password })`.
1089
+ *
1090
+ * Always resolves successfully for well-formed requests — whether the email
1091
+ * has an account is never revealed.
1092
+ */
1093
+ resetPasswordForEmail(email: string, options?: {
1094
+ redirectTo?: string;
1095
+ }): Promise<PostgrestResult<Record<string, never>>>;
1096
+ /**
1097
+ * Email a one-click sign-in (magic) link — passwordless auth. New addresses
1098
+ * get an account automatically unless `shouldCreateUser: false`. The emailed
1099
+ * link carries `?token_hash=…&type=magiclink`; complete sign-in on that page
1100
+ * with {@link verifyOtp}.
1101
+ */
1102
+ signInWithOtp(params: {
1103
+ email: string;
1104
+ options?: {
1105
+ emailRedirectTo?: string;
1106
+ shouldCreateUser?: boolean;
1107
+ };
1108
+ }): Promise<PostgrestResult<{
1109
+ user: null;
1110
+ session: null;
1111
+ }>>;
1112
+ /**
1113
+ * Exchange an emailed `token_hash` for a session. Reads the token from the
1114
+ * URL your recovery / magic-link page receives:
1115
+ *
1116
+ * ```ts
1117
+ * const qs = new URLSearchParams(window.location.search);
1118
+ * const { data, error } = await client.auth.verifyOtp({
1119
+ * token_hash: qs.get("token_hash")!,
1120
+ * type: qs.get("type") as "recovery" | "magiclink",
1121
+ * });
1122
+ * ```
1123
+ *
1124
+ * Emits `SIGNED_IN` (and `PASSWORD_RECOVERY` for recovery tokens — listen
1125
+ * for it to route to your "choose a new password" screen).
1126
+ */
1127
+ verifyOtp(params: {
1128
+ token_hash?: string;
1129
+ /** Alias for `token_hash`. */
1130
+ tokenHash?: string;
1131
+ type: AuthOtpType;
1132
+ }): Promise<PostgrestResult<{
1133
+ user: U;
1134
+ session: AuthSession<U>;
1135
+ }>>;
1136
+ /**
1137
+ * One-shot recovery: verify the emailed recovery token, set the new
1138
+ * password, and sign the user in — no intermediate session juggling.
1139
+ *
1140
+ * ```ts
1141
+ * const qs = new URLSearchParams(window.location.search);
1142
+ * const { data, error } = await client.auth.resetPassword({
1143
+ * tokenHash: qs.get("token_hash")!,
1144
+ * newPassword: form.password,
1145
+ * });
1146
+ * ```
1147
+ *
1148
+ * Recovery links are single-use: once the password changes, the same link
1149
+ * is rejected.
1150
+ */
1151
+ resetPassword(params: {
1152
+ tokenHash?: string;
1153
+ /** Alias for `tokenHash`. */
1154
+ token_hash?: string;
1155
+ newPassword: string;
1156
+ }): Promise<PostgrestResult<{
1157
+ user: U;
1158
+ session: AuthSession<U>;
1159
+ }>>;
822
1160
  refreshSession(refreshToken?: string): Promise<PostgrestResult<{
823
1161
  session: AuthSession<U>;
824
1162
  user: U;
@@ -1279,6 +1617,106 @@ declare function streamObjectFromContext<T = unknown>(ctx: InferenceRequestConte
1279
1617
  */
1280
1618
  declare function wrapStreamTextAsObject<T = unknown>(inner: StreamTextResult): StreamObjectResult<T>;
1281
1619
 
1620
+ /**
1621
+ * Server-side client — the authenticated SDK for code that runs on a trusted
1622
+ * server (a Ragable backend **function**, an Engine, or your own Node service).
1623
+ *
1624
+ * Unlike the browser client there is **no sign-in / session machinery** here:
1625
+ * a server is not a logged-in user. Instead you provide credentials up front and
1626
+ * the client speaks to the same Ragable data plane the browser uses, so the
1627
+ * semantics (collection security, `{ data, error }` shapes, PostgREST) are
1628
+ * identical — this reuses the exact same fetch-based sub-clients, never a
1629
+ * reimplementation.
1630
+ *
1631
+ * Two privilege levels:
1632
+ * - **caller** (default): acts as the end user who invoked you — uses their
1633
+ * forwarded access token, falling back to the public anon key for anonymous
1634
+ * callers. Collection security applies, exactly as in the browser.
1635
+ * - **admin**: authenticates with the auth group's **data-admin key**, which
1636
+ * bypasses collection security (owner/group/claim grants do not apply) and
1637
+ * can write protected collections. Reach for it deliberately.
1638
+ *
1639
+ * ```ts
1640
+ * // inside /functions/<name>.ts — `context.ragable` is a pre-built server client
1641
+ * export default async function createTask(input, context) {
1642
+ * // as the caller (respects collection security):
1643
+ * const { data, error } = await context.ragable.db.collections.tasks.insert(input);
1644
+ * // privileged work (bypasses collection security):
1645
+ * await context.ragable.asAdmin().db.collections.audit_log.insert({ action: "create" });
1646
+ * return data;
1647
+ * }
1648
+ * ```
1649
+ */
1650
+
1651
+ /** Which credential a server client authenticates with. */
1652
+ type ServerPrivilege = "caller" | "admin";
1653
+ /**
1654
+ * Inputs to {@link createServerClient}. The IDs and keys are normally supplied by
1655
+ * the runtime (a function's injected `context.ragable`); construct one by hand
1656
+ * only for a standalone server.
1657
+ */
1658
+ interface RagableServerClientConfig {
1659
+ organizationId: string;
1660
+ websiteId?: string;
1661
+ authGroupId?: string;
1662
+ databaseInstanceId?: string;
1663
+ storageBucketId?: string;
1664
+ mailAccountId?: string;
1665
+ /**
1666
+ * The auth group's **data-admin key**. Required for `admin` privilege; omit it
1667
+ * and `asAdmin()` throws. Server-only — never expose this to the browser.
1668
+ */
1669
+ adminKey?: string;
1670
+ /**
1671
+ * The invoking end user's access token (a real auth-group JWT), forwarded by
1672
+ * the runtime. `null`/omitted for anonymous callers. Used by `caller`
1673
+ * privilege; the public anon key is the fallback when this is absent.
1674
+ */
1675
+ callerToken?: string | null;
1676
+ /** Public anon key — the `caller` fallback when no end user is signed in. */
1677
+ publicAnonKey?: string;
1678
+ /** Default privilege for the returned client. Defaults to `"caller"`. */
1679
+ defaultPrivilege?: ServerPrivilege;
1680
+ fetch?: typeof fetch;
1681
+ headers?: HeadersInit;
1682
+ }
1683
+ /**
1684
+ * A trusted, server-side Ragable client. Surface mirrors the browser client
1685
+ * (`db`, `storage`, `mail`, `functions`, `ai`, `agents`) minus `auth` — a server
1686
+ * authenticates with keys, not a session. Switch privilege with {@link asAdmin}
1687
+ * / {@link asCaller}.
1688
+ */
1689
+ declare class RagableServerClient<Database extends RagableDatabase = DefaultRagableDatabase, Functions extends RagableFunctions = DefaultRagableFunctions> {
1690
+ private readonly config;
1691
+ readonly database: RagableBrowserDatabaseClient<Database>;
1692
+ readonly db: RagableBrowserDatabaseClient<Database>;
1693
+ readonly storage: RagableBrowserStorageClient;
1694
+ readonly mail: RagableBrowserMailClient;
1695
+ readonly functions: FunctionInvoker<Functions>;
1696
+ readonly ai: RagableBrowserAiClient;
1697
+ readonly agents: RagableBrowserAgentsClient;
1698
+ /** Which credential this client is using. */
1699
+ readonly privilege: ServerPrivilege;
1700
+ constructor(config: RagableServerClientConfig, privilege: ServerPrivilege);
1701
+ /**
1702
+ * A client authenticated with the **data-admin key** — bypasses collection
1703
+ * security (owner/group/claim grants do not apply) and can write protected
1704
+ * collections. Throws `SDK_ADMIN_KEY_REQUIRED` when no admin key is configured.
1705
+ */
1706
+ asAdmin(): RagableServerClient<Database, Functions>;
1707
+ /**
1708
+ * A client scoped to the invoking end user's identity (respects collection
1709
+ * security). This is already the default; use it to drop back from `asAdmin()`.
1710
+ */
1711
+ asCaller(): RagableServerClient<Database, Functions>;
1712
+ }
1713
+ /**
1714
+ * Create a server-side Ragable client. Defaults to **caller** privilege (acts as
1715
+ * the invoking end user, respecting collection security); call `.asAdmin()` for
1716
+ * privileged, security-bypassing access.
1717
+ */
1718
+ declare function createServerClient<Database extends RagableDatabase = DefaultRagableDatabase, Functions extends RagableFunctions = DefaultRagableFunctions>(config: RagableServerClientConfig): RagableServerClient<Database, Functions>;
1719
+
1282
1720
  /**
1283
1721
  * Backend "edge functions".
1284
1722
  *
@@ -1307,6 +1745,7 @@ declare function wrapStreamTextAsObject<T = unknown>(inner: StreamTextResult): S
1307
1745
  * The handler's second argument (`context`) is injected by the server; callers
1308
1746
  * pass only `input`.
1309
1747
  */
1748
+
1310
1749
  /**
1311
1750
  * Server-injected second argument to every function handler. Never constructed
1312
1751
  * on the client — the values come from the backend at invocation time.
@@ -1331,6 +1770,16 @@ interface RagableFunctionContext {
1331
1770
  auth: {
1332
1771
  token: string | null;
1333
1772
  };
1773
+ /**
1774
+ * A pre-authenticated {@link RagableServerClient} for talking back to your
1775
+ * Ragable Cloud (db / storage / mail / functions / ai / agents) — already
1776
+ * wired to this project, no setup or keys to manage.
1777
+ *
1778
+ * Defaults to the **caller's** identity, so collection security applies just
1779
+ * like in the browser. Call `context.ragable.asAdmin()` for privileged work
1780
+ * that must bypass collection security (e.g. owner-only writes, audit logs).
1781
+ */
1782
+ ragable: RagableServerClient;
1334
1783
  }
1335
1784
  /**
1336
1785
  * The shape a `/functions/<name>.ts` default export must satisfy. Type the
@@ -1461,6 +1910,39 @@ declare class RagableBrowserAuthClient<AuthUser extends object = DefaultAuthUser
1461
1910
  }): Promise<{
1462
1911
  error: null;
1463
1912
  }>;
1913
+ /** Email a password-recovery link — see {@link RagableAuth.resetPasswordForEmail}. */
1914
+ resetPasswordForEmail(email: string, options?: {
1915
+ redirectTo?: string;
1916
+ }): Promise<PostgrestResult<Record<string, never>>>;
1917
+ /** Email a magic sign-in link — see {@link RagableAuth.signInWithOtp}. */
1918
+ signInWithOtp(params: {
1919
+ email: string;
1920
+ options?: {
1921
+ emailRedirectTo?: string;
1922
+ shouldCreateUser?: boolean;
1923
+ };
1924
+ }): Promise<PostgrestResult<{
1925
+ user: null;
1926
+ session: null;
1927
+ }>>;
1928
+ /** Exchange an emailed token_hash for a session — see {@link RagableAuth.verifyOtp}. */
1929
+ verifyOtp(params: {
1930
+ token_hash?: string;
1931
+ tokenHash?: string;
1932
+ type: AuthOtpType;
1933
+ }): Promise<PostgrestResult<{
1934
+ user: AuthUser;
1935
+ session: AuthSession<AuthUser>;
1936
+ }>>;
1937
+ /** Verify a recovery token and set a new password in one call — see {@link RagableAuth.resetPassword}. */
1938
+ resetPassword(params: {
1939
+ tokenHash?: string;
1940
+ token_hash?: string;
1941
+ newPassword: string;
1942
+ }): Promise<PostgrestResult<{
1943
+ user: AuthUser;
1944
+ session: AuthSession<AuthUser>;
1945
+ }>>;
1464
1946
  register(body: {
1465
1947
  email: string;
1466
1948
  password: string;
@@ -1638,6 +2120,35 @@ declare class BrowserCollectionApi<Row extends Record<string, unknown> = Record<
1638
2120
  private readonly name;
1639
2121
  private readonly databaseInstanceId?;
1640
2122
  constructor(database: RagableBrowserDatabaseClient<any>, name: string, databaseInstanceId?: string | undefined);
2123
+ /** Transport for the chainable builders, bound to this collection. */
2124
+ private chainRequest;
2125
+ /**
2126
+ * Supabase-style chainable query. Rows come back flat (`id`, `createdAt`,
2127
+ * `updatedAt` merged into the document fields).
2128
+ *
2129
+ * ```ts
2130
+ * const { data, error, count } = await collections.todos
2131
+ * .select("*", { count: "exact" })
2132
+ * .eq("done", false)
2133
+ * .or("priority.gte.3,starred.eq.true")
2134
+ * .order("createdAt", { ascending: false })
2135
+ * .range(0, 19);
2136
+ * ```
2137
+ *
2138
+ * Relation embeds (one level): `select("*, author:users!author_id(name), comments(*)")`
2139
+ * — to-one embeds become an object (or null), to-many an array. Aggregations:
2140
+ * `select("category, count(), total:amount.sum()")` groups by the plain
2141
+ * columns; pass a type argument for the result shape:
2142
+ * `select<{ category: string; count: number }>("category, count()")`.
2143
+ */
2144
+ select: <Out extends Record<string, unknown> = CollectionRow<RowD<Row>>>(columns?: string, options?: CollectionSelectOptions) => CollectionSelectBuilder<RowD<Row>, Out>;
2145
+ /**
2146
+ * Insert-or-update matched on `onConflict` (`"id"` by default, or any data
2147
+ * field, e.g. `{ onConflict: "slug" }`). Chain `.select()` for the affected
2148
+ * rows. Match-based (no unique indexes): concurrent upserts of the same new
2149
+ * value can both insert.
2150
+ */
2151
+ upsert: (values: BrowserCollectionInsertData<Row, Insert> | BrowserCollectionInsertData<Row, Insert>[], options?: CollectionUpsertOptions) => CollectionUpsertBuilder<RowD<Row>>;
1641
2152
  private normalizeFindArgs;
1642
2153
  private requestFind;
1643
2154
  /**
@@ -1662,18 +2173,32 @@ declare class BrowserCollectionApi<Row extends Record<string, unknown> = Record<
1662
2173
  id: string;
1663
2174
  } & Partial<WhereInput<RowD<Row>>>;
1664
2175
  }) => Promise<PostgrestResult<BrowserCollectionRecord<RowD<Row>> | null>>;
1665
- insert: (data: BrowserCollectionInsertData<Row, Insert>) => Promise<PostgrestResult<BrowserCollectionRecord<RowD<Row>>>>;
2176
+ /**
2177
+ * Insert one row or an array of rows. Chain `.select()` for the inserted
2178
+ * rows in flat shape, or await directly for the record envelope(s)
2179
+ * (back-compat extension; Supabase resolves to null without `.select()`).
2180
+ */
2181
+ insert: {
2182
+ (data: BrowserCollectionInsertData<Row, Insert>[]): CollectionInsertChain<RowD<Row>, BrowserCollectionRecord<RowD<Row>>[]>;
2183
+ (data: BrowserCollectionInsertData<Row, Insert>): CollectionInsertChain<RowD<Row>, BrowserCollectionRecord<RowD<Row>>>;
2184
+ };
1666
2185
  /**
1667
2186
  * Insert multiple rows in one request (server multi-value `INSERT`, single transaction).
1668
2187
  * Empty **`items`** resolves to an empty array. Max batch size is enforced on the server (500).
1669
2188
  */
1670
2189
  insertMany: (items: BrowserCollectionInsertData<Row, Insert>[]) => Promise<PostgrestResult<BrowserCollectionRecord<RowD<Row>>[]>>;
1671
2190
  /**
1672
- * Update rows matching `where` (JSON fields, plus envelope `id` / `createdAt` / `updatedAt`).
2191
+ * Two forms:
2192
+ * - `update(patch)` — Supabase-style chain: add filters, then await.
2193
+ * `update({ done: true }).eq("id", id)` (optionally `.select()`).
2194
+ * - `update(where, patch)` — legacy direct call, returns updated records.
1673
2195
  */
1674
- update: (where: WhereInput<RowD<Row>>, patch: BrowserCollectionUpdateData<Row, Update>, options?: {
1675
- limit?: number;
1676
- }) => Promise<PostgrestResult<BrowserCollectionRecord<RowD<Row>>[]>>;
2196
+ update: {
2197
+ (patch: BrowserCollectionUpdateData<Row, Update>): CollectionUpdateBuilder<RowD<Row>>;
2198
+ (where: WhereInput<RowD<Row>>, patch: BrowserCollectionUpdateData<Row, Update>, options?: {
2199
+ limit?: number;
2200
+ }): Promise<PostgrestResult<BrowserCollectionRecord<RowD<Row>>[]>>;
2201
+ };
1677
2202
  /**
1678
2203
  * Like {@link BrowserCollectionApi.update} but the success payload includes
1679
2204
  * `meta.count` (number of rows returned from the update, bounded by `limit`).
@@ -1686,12 +2211,21 @@ declare class BrowserCollectionApi<Row extends Record<string, unknown> = Record<
1686
2211
  count: number;
1687
2212
  };
1688
2213
  }>>;
1689
- delete: (where: WhereInput<RowD<Row>>, options?: {
1690
- limit?: number;
1691
- }) => Promise<PostgrestResult<{
1692
- deleted: number;
1693
- records: BrowserCollectionRecord<RowD<Row>>[];
1694
- }>>;
2214
+ /**
2215
+ * Two forms:
2216
+ * - `delete()` Supabase-style chain: add filters, then await.
2217
+ * `delete().eq("id", id)` (optionally `.select()`).
2218
+ * - `delete(where)` — legacy direct call, returns `{ deleted, records }`.
2219
+ */
2220
+ delete: {
2221
+ (): CollectionDeleteBuilder<RowD<Row>>;
2222
+ (where: WhereInput<RowD<Row>>, options?: {
2223
+ limit?: number;
2224
+ }): Promise<PostgrestResult<{
2225
+ deleted: number;
2226
+ records: BrowserCollectionRecord<RowD<Row>>[];
2227
+ }>>;
2228
+ };
1695
2229
  /**
1696
2230
  * Like {@link BrowserCollectionApi.delete} but the success payload includes **`meta.count`**
1697
2231
  * (number of deleted rows), matching {@link BrowserCollectionApi.updateMany}.
@@ -1730,7 +2264,7 @@ declare class RagableBrowserDatabaseClient<Database extends RagableDatabase = De
1730
2264
  private toUrl;
1731
2265
  defineCollection: (name: string, schema?: Record<string, unknown>, databaseInstanceId?: string) => Promise<PostgrestResult<BrowserCollectionDefinition>>;
1732
2266
  listCollections: (databaseInstanceId?: string) => Promise<PostgrestResult<BrowserCollectionDefinition[]>>;
1733
- _requestCollection<T>(method: "GET" | "POST" | "PATCH" | "DELETE", path: string, body?: unknown, databaseInstanceId?: string): Promise<T>;
2267
+ _requestCollection<T>(method: "GET" | "POST" | "PATCH" | "DELETE", path: string, body?: unknown, databaseInstanceId?: string, signal?: AbortSignal): Promise<T>;
1734
2268
  query: <Row extends Record<string, unknown> = Record<string, unknown>>(params: BrowserSqlQueryParams) => Promise<PostgrestResult<BrowserSqlQueryResult<Row>>>;
1735
2269
  private baseHeaders;
1736
2270
  /**
@@ -2271,4 +2805,4 @@ declare function tryParsePartialJson(text: string): unknown | undefined;
2271
2805
 
2272
2806
  declare function createClient<Database extends RagableDatabase = DefaultRagableDatabase, AuthUser extends object = DefaultAuthUser, Functions extends RagableFunctions = DefaultRagableFunctions>(options: RagableBrowserClientOptions): RagableBrowser<Database, AuthUser, Functions>;
2273
2807
 
2274
- export { type AgentChatMessage, type AgentChatParams, type AgentChatStreamDonePayload, type AgentChatStreamHandlers, type AgentChatStreamResult, type AgentChatStreamUiHandlers, type AgentChatUiAssistantMessage, type AgentChatUiSegment, type AgentChatUiStreamResult, type AgentConversation, type AgentConversationMessage, type AgentConversationSubscription, type AgentPublicChatParams, type AgentStreamAgentInfoEvent, type AgentStreamEvent, AuthBroadcastChannel, type AuthBroadcastMessage, type AuthChangeEvent, type AuthOptions, type AuthSession, type AuthSignUpCredentials, type AuthUpdateUserAttributes, type AuthUserMetadata, type BrowserAuthSession, type BrowserAuthTokens, BrowserCollectionApi, type BrowserCollectionDefinition, type BrowserCollectionFactory, type BrowserCollectionFindParams, type BrowserCollectionRecord, type BrowserCollections, type BrowserDataAuthMode, type BrowserRealtimeNotification, type BrowserRealtimeStatus, type BrowserRealtimeSubscribeParams, type BrowserRealtimeSubscription, type BrowserSqlExecParams, type BrowserSqlExecResult, type BrowserSqlQueryParams, type BrowserSqlQueryResult, BrowserStorageBucketClient, type BrowserStorageBulkDeleteResult, type BrowserStorageDownloadResult, type BrowserStorageItem, type BrowserStorageListResult, type BrowserStorageSignedUrlResult, type BrowserStorageUploadResult, type CollectionReturnMode, type CollectionRowData, type CollectionRowWithMeta, type CollectionWhere, type ColumnName, type ColumnValue, CookieStorageAdapter, DEFAULT_RAGABLE_API_BASE, type DefaultAuthUser, type DefaultRagableDatabase, type DefaultRagableFunctions, type FinishReason, type FunctionInvoker, type GenerateObjectResult, type GenerateTextResult, type HttpMethod, type Json, type JsonSchema, LocalStorageAdapter, type MailMessageDetail, type MailMessagePreview, type MailSearchParams, type MailSendParams, type MailSendResult, MemoryStorageAdapter, type Message, type PostgRESTFetch, type PostgRESTFetchParams, PostgrestDeleteReturningBuilder, PostgrestDeleteRootBuilder, PostgrestInsertReturningBuilder, PostgrestInsertRootBuilder, PostgrestInsertSdkErrorReturning, PostgrestInsertSdkErrorRoot, type PostgrestResult, PostgrestSelectBuilder, PostgrestTableApi, PostgrestUpdateReturningBuilder, PostgrestUpdateRootBuilder, type PostgrestUpsertOptions, PostgrestUpsertReturningBuilder, PostgrestUpsertRootBuilder, RagableAbortError, RagableAuth, type RagableAuthConfig, RagableBrowser, RagableBrowserAgentsClient, RagableBrowserAiClient, RagableBrowserAuthClient, type RagableBrowserClientOptions, RagableBrowserDatabaseClient, RagableBrowserFunctionsClient, RagableBrowserMailClient, RagableBrowserStorageClient, type RagableDatabase, RagableError, type RagableFunctionCall, type RagableFunctionContext, type RagableFunctionHandler, type RagableFunctionInvokeOptions, type RagableFunctions, RagableNetworkError, type RagableResult, RagableSdkError, type RagableTableDefinition, type RagableTableNames, RagableTimeoutError, type RequestOptions, type RetryOptions, type RunAgentChatStreamOptions, type RunQuery, type SessionStorage, SessionStorageAdapter, type SseJsonEvent, type StreamObjectParams, type StreamObjectResult, type StreamPart, type StreamTextParams, type StreamTextResult, type SupabaseCompatSession, type TableInsertRow, type TableRow, type TableUpdatePatch, type Tables, type TablesInsert, type TablesUpdate, type TokenUsage, type ToolCallRecord, Transport, type TransportOptions, type TransportRequest, type WhereInput, type WhereOperatorObject, asPostgrestResponse, assertPostgrestSuccess, bindFetch, buildInferenceRequestBody, buildResponseFormat, collectAssistantTextFromUiSegments, collectionRecordToRowWithMeta, collectionRecordsToRowWithMeta, createBrowserClient, createClient, createRagableBrowserClient, createStreamResultFromParts, detectStorage, effectiveDataAuth, extractErrorMessage, finalizeAgentChatUiTurn, foldAgentStreamIntoUiSegments, formatPostgrestError, formatSdkError, generateIdempotencyKey, isIncompleteAgentStreamError, mapAgentEvent, mapFireworksChunk, normalizeBrowserApiBase, parseAgentStreamAgentInfo, parseAgentStreamDone, parseSseDataLine, parseTransportResponse, readSseStream, runAgentChatStream, runAgentChatStreamForUi, runAgentChatStreamLenient, streamObjectFromContext, toRagableResult, tryParsePartialJson, unwrapPostgrest, wrapStreamTextAsObject };
2808
+ export { type AgentChatMessage, type AgentChatParams, type AgentChatStreamDonePayload, type AgentChatStreamHandlers, type AgentChatStreamResult, type AgentChatStreamUiHandlers, type AgentChatUiAssistantMessage, type AgentChatUiSegment, type AgentChatUiStreamResult, type AgentConversation, type AgentConversationMessage, type AgentConversationSubscription, type AgentPublicChatParams, type AgentStreamAgentInfoEvent, type AgentStreamEvent, AuthBroadcastChannel, type AuthBroadcastMessage, type AuthChangeEvent, type AuthOptions, type AuthOtpType, type AuthSession, type AuthSignUpCredentials, type AuthUpdateUserAttributes, type AuthUserMetadata, type BrowserAuthSession, type BrowserAuthTokens, BrowserCollectionApi, type BrowserCollectionDefinition, type BrowserCollectionFactory, type BrowserCollectionFindParams, type BrowserCollectionRecord, type BrowserCollections, type BrowserDataAuthMode, type BrowserRealtimeNotification, type BrowserRealtimeStatus, type BrowserRealtimeSubscribeParams, type BrowserRealtimeSubscription, type BrowserSqlExecParams, type BrowserSqlExecResult, type BrowserSqlQueryParams, type BrowserSqlQueryResult, BrowserStorageBucketClient, type BrowserStorageBulkDeleteResult, type BrowserStorageDownloadResult, type BrowserStorageItem, type BrowserStorageListResult, type BrowserStorageSignedUrlResult, type BrowserStorageUploadResult, CollectionDeleteBuilder, type CollectionField, type CollectionFilterOp, CollectionInsertChain, type CollectionListResult, CollectionMutationReturning, type CollectionRecordEnvelope, type CollectionRequestFn, type CollectionReturnMode, type CollectionRow, type CollectionRowData, type CollectionRowWithMeta, CollectionSelectBuilder, type CollectionSelectOptions, type CollectionSelectedAggregate, type CollectionSelectedEmbed, CollectionUpdateBuilder, CollectionUpsertBuilder, type CollectionUpsertOptions, type CollectionUpsertSummary, type CollectionWhere, type ColumnName, type ColumnValue, CookieStorageAdapter, DEFAULT_RAGABLE_API_BASE, type DefaultAuthUser, type DefaultRagableDatabase, type DefaultRagableFunctions, type FinishReason, type FunctionInvoker, type GenerateObjectResult, type GenerateTextResult, type HttpMethod, type Json, type JsonSchema, LocalStorageAdapter, type MailMessageDetail, type MailMessagePreview, type MailSearchParams, type MailSendParams, type MailSendResult, MemoryStorageAdapter, type Message, type ParsedSelectExpression, type PostgRESTFetch, type PostgRESTFetchParams, PostgrestDeleteReturningBuilder, PostgrestDeleteRootBuilder, PostgrestInsertReturningBuilder, PostgrestInsertRootBuilder, PostgrestInsertSdkErrorReturning, PostgrestInsertSdkErrorRoot, type PostgrestResult, PostgrestSelectBuilder, PostgrestTableApi, PostgrestUpdateReturningBuilder, PostgrestUpdateRootBuilder, type PostgrestUpsertOptions, PostgrestUpsertReturningBuilder, PostgrestUpsertRootBuilder, RagableAbortError, RagableAuth, type RagableAuthConfig, RagableBrowser, RagableBrowserAgentsClient, RagableBrowserAiClient, RagableBrowserAuthClient, type RagableBrowserClientOptions, RagableBrowserDatabaseClient, RagableBrowserFunctionsClient, RagableBrowserMailClient, RagableBrowserStorageClient, type RagableDatabase, RagableError, type RagableFunctionCall, type RagableFunctionContext, type RagableFunctionHandler, type RagableFunctionInvokeOptions, type RagableFunctions, RagableNetworkError, type RagableResult, RagableSdkError, RagableServerClient, type RagableServerClientConfig, type RagableTableDefinition, type RagableTableNames, RagableTimeoutError, type RequestOptions, type RetryOptions, type RunAgentChatStreamOptions, type RunQuery, type ServerPrivilege, type SessionStorage, SessionStorageAdapter, type SseJsonEvent, type StreamObjectParams, type StreamObjectResult, type StreamPart, type StreamTextParams, type StreamTextResult, type SupabaseCompatSession, type TableInsertRow, type TableRow, type TableUpdatePatch, type Tables, type TablesInsert, type TablesUpdate, type TokenUsage, type ToolCallRecord, Transport, type TransportOptions, type TransportRequest, type WhereInput, type WhereOperatorObject, asPostgrestResponse, assertPostgrestSuccess, bindFetch, buildInferenceRequestBody, buildResponseFormat, collectAssistantTextFromUiSegments, collectionRecordToRowWithMeta, collectionRecordsToRowWithMeta, createBrowserClient, createClient, createRagableBrowserClient, createServerClient, createStreamResultFromParts, detectStorage, effectiveDataAuth, extractErrorMessage, finalizeAgentChatUiTurn, foldAgentStreamIntoUiSegments, formatPostgrestError, formatSdkError, generateIdempotencyKey, isIncompleteAgentStreamError, mapAgentEvent, mapFireworksChunk, normalizeBrowserApiBase, parseAgentStreamAgentInfo, parseAgentStreamDone, parseOrString, parseSelectExpression, parseSseDataLine, parseTransportResponse, readSseStream, runAgentChatStream, runAgentChatStreamForUi, runAgentChatStreamLenient, streamObjectFromContext, toRagableResult, tryParsePartialJson, unwrapPostgrest, wrapStreamTextAsObject };