@insforge/sdk 1.4.1 → 1.4.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/ssr.mjs CHANGED
@@ -833,19 +833,32 @@ var HttpClient = class {
833
833
 
834
834
  // src/modules/auth/helpers.ts
835
835
  var PKCE_VERIFIER_KEY = "insforge_pkce_verifier";
836
+ async function getWebCrypto() {
837
+ const webCrypto = globalThis.crypto;
838
+ if (typeof webCrypto?.getRandomValues === "function" && webCrypto.subtle) {
839
+ return webCrypto;
840
+ }
841
+ if (typeof process !== "undefined" && process.versions?.node) {
842
+ const { webcrypto } = await import("crypto");
843
+ return webcrypto;
844
+ }
845
+ throw new Error("Web Crypto API is not available in this environment");
846
+ }
836
847
  function base64UrlEncode(buffer) {
837
848
  const base64 = btoa(String.fromCharCode(...buffer));
838
849
  return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
839
850
  }
840
- function generateCodeVerifier() {
851
+ async function generateCodeVerifier() {
852
+ const webCrypto = await getWebCrypto();
841
853
  const array = new Uint8Array(32);
842
- crypto.getRandomValues(array);
854
+ webCrypto.getRandomValues(array);
843
855
  return base64UrlEncode(array);
844
856
  }
845
857
  async function generateCodeChallenge(verifier) {
858
+ const webCrypto = await getWebCrypto();
846
859
  const encoder = new TextEncoder();
847
860
  const data = encoder.encode(verifier);
848
- const hash = await crypto.subtle.digest("SHA-256", data);
861
+ const hash = await webCrypto.subtle.digest("SHA-256", data);
849
862
  return base64UrlEncode(new Uint8Array(hash));
850
863
  }
851
864
  function storePkceVerifier(verifier) {
@@ -892,7 +905,7 @@ var Auth = class {
892
905
  this.http = http;
893
906
  this.tokenManager = tokenManager;
894
907
  this.options = options;
895
- this.authCallbackHandled = this.detectAuthCallback();
908
+ this.authCallbackHandled = options.detectOAuthCallback === false ? Promise.resolve() : this.detectAuthCallback();
896
909
  }
897
910
  isServerMode() {
898
911
  return !!this.options.isServerMode;
@@ -989,10 +1002,16 @@ var Auth = class {
989
1002
  async signOut() {
990
1003
  try {
991
1004
  try {
1005
+ const serverMode = this.isServerMode();
1006
+ const csrfToken = !serverMode ? getCsrfToken() : null;
992
1007
  await this.http.post(
993
- this.isServerMode() ? "/api/auth/logout?client_type=mobile" : "/api/auth/logout",
1008
+ serverMode ? "/api/auth/logout?client_type=mobile" : "/api/auth/logout",
994
1009
  void 0,
995
- { credentials: "include", skipAuthRefresh: true }
1010
+ {
1011
+ credentials: "include",
1012
+ skipAuthRefresh: true,
1013
+ ...csrfToken ? { headers: { "X-CSRF-Token": csrfToken } } : {}
1014
+ }
996
1015
  );
997
1016
  } catch {
998
1017
  }
@@ -1038,7 +1057,7 @@ var Auth = class {
1038
1057
  }
1039
1058
  const { provider } = signInOptions;
1040
1059
  const providerKey = encodeURIComponent(provider.toLowerCase());
1041
- const codeVerifier = generateCodeVerifier();
1060
+ const codeVerifier = await generateCodeVerifier();
1042
1061
  const codeChallenge = await generateCodeChallenge(codeVerifier);
1043
1062
  storePkceVerifier(codeVerifier);
1044
1063
  const params = {
@@ -1398,12 +1417,30 @@ function createInsForgePostgrestFetch(httpClient) {
1398
1417
  };
1399
1418
  }
1400
1419
  var Database = class {
1401
- constructor(httpClient) {
1420
+ constructor(httpClient, defaultSchema) {
1402
1421
  this.postgrest = new PostgrestClient("http://dummy", {
1403
1422
  fetch: createInsForgePostgrestFetch(httpClient),
1404
- headers: {}
1423
+ headers: {},
1424
+ ...defaultSchema ? { schema: defaultSchema } : {}
1405
1425
  });
1406
1426
  }
1427
+ /**
1428
+ * Select a non-default Postgres schema for the chained query. Maps to
1429
+ * PostgREST's `Accept-Profile` (reads) / `Content-Profile` (writes) header.
1430
+ * The schema must be exposed by the backend.
1431
+ *
1432
+ * @example
1433
+ * const { data } = await client.database
1434
+ * .schema('analytics')
1435
+ * .from('events')
1436
+ * .select('*');
1437
+ *
1438
+ * @example
1439
+ * await client.database.schema('analytics').rpc('rollup', { day: '2026-01-01' });
1440
+ */
1441
+ schema(schemaName) {
1442
+ return this.postgrest.schema(schemaName);
1443
+ }
1407
1444
  /**
1408
1445
  * Create a query builder for a table
1409
1446
  *
@@ -2760,9 +2797,10 @@ var InsForgeClient = class {
2760
2797
  this.tokenManager.setAccessToken(accessToken);
2761
2798
  }
2762
2799
  this.auth = new Auth(this.http, this.tokenManager, {
2763
- isServerMode: config.isServerMode ?? !!accessToken
2800
+ isServerMode: config.isServerMode ?? !!accessToken,
2801
+ detectOAuthCallback: config.auth?.detectOAuthCallback
2764
2802
  });
2765
- this.database = new Database(this.http);
2803
+ this.database = new Database(this.http, config.db?.schema);
2766
2804
  this.storage = new Storage(this.http);
2767
2805
  this.ai = new AI(this.http);
2768
2806
  this.functions = new Functions(this.http, config.functionsUrl);
@@ -3169,7 +3207,10 @@ function createBrowserClient(options = {}) {
3169
3207
  fetch: ssrFetch,
3170
3208
  // Browser clients manage tokens via the refresh route, not a static
3171
3209
  // config token; shadow any untyped accessToken in the options spread.
3172
- accessToken: void 0
3210
+ accessToken: void 0,
3211
+ auth: {
3212
+ detectOAuthCallback: false
3213
+ }
3173
3214
  });
3174
3215
  const setAccessToken = client.setAccessToken.bind(client);
3175
3216
  client.setAccessToken = (token) => {
@@ -3374,6 +3415,109 @@ function createRefreshAuthRouter(options = {}) {
3374
3415
  };
3375
3416
  }
3376
3417
 
3418
+ // src/ssr/auth-actions.ts
3419
+ function persistSessionCookies(cookies, data, settings) {
3420
+ if (!data?.accessToken) return;
3421
+ setAuthCookies(
3422
+ cookies,
3423
+ {
3424
+ accessToken: data.accessToken,
3425
+ refreshToken: data.refreshToken
3426
+ },
3427
+ settings
3428
+ );
3429
+ }
3430
+ function sanitizeAuthData(data) {
3431
+ if (!data) return null;
3432
+ const {
3433
+ accessToken: _accessToken,
3434
+ refreshToken: _refreshToken,
3435
+ csrfToken: _csrfToken,
3436
+ ...safeData
3437
+ } = data;
3438
+ return safeData;
3439
+ }
3440
+ function toSafeAuthResult(result) {
3441
+ return {
3442
+ data: sanitizeAuthData(result.data),
3443
+ error: result.error
3444
+ };
3445
+ }
3446
+ function createAuthActions(options = {}) {
3447
+ const {
3448
+ cookies,
3449
+ requestCookies,
3450
+ responseCookies,
3451
+ names,
3452
+ options: cookieOptions,
3453
+ ...clientOptions
3454
+ } = options;
3455
+ const readCookies = requestCookies ?? cookies;
3456
+ const writeCookies = responseCookies ?? cookies;
3457
+ if (!writeCookies?.set) {
3458
+ throw new Error(
3459
+ "createAuthActions() requires a writable cookie store. Pass cookies in Server Actions or responseCookies in Route Handlers."
3460
+ );
3461
+ }
3462
+ const cookieSettings = {
3463
+ names,
3464
+ options: cookieOptions
3465
+ };
3466
+ const createClient = () => createServerClient({
3467
+ ...clientOptions,
3468
+ names,
3469
+ options: cookieOptions,
3470
+ cookies: readCookies
3471
+ });
3472
+ return {
3473
+ signUp: async (request) => {
3474
+ const result = await createClient().auth.signUp(request);
3475
+ persistSessionCookies(writeCookies, result.data, cookieSettings);
3476
+ return toSafeAuthResult(result);
3477
+ },
3478
+ signInWithPassword: async (request) => {
3479
+ const result = await createClient().auth.signInWithPassword(request);
3480
+ persistSessionCookies(writeCookies, result.data, cookieSettings);
3481
+ return toSafeAuthResult(
3482
+ result
3483
+ );
3484
+ },
3485
+ signInWithOAuth: async (providerOrOptions, signInOptions) => {
3486
+ return createClient().auth.signInWithOAuth(
3487
+ providerOrOptions,
3488
+ signInOptions
3489
+ );
3490
+ },
3491
+ signInWithIdToken: async (credentials) => {
3492
+ const result = await createClient().auth.signInWithIdToken(credentials);
3493
+ persistSessionCookies(writeCookies, result.data, cookieSettings);
3494
+ return toSafeAuthResult(
3495
+ result
3496
+ );
3497
+ },
3498
+ exchangeOAuthCode: async (code, codeVerifier) => {
3499
+ const result = await createClient().auth.exchangeOAuthCode(
3500
+ code,
3501
+ codeVerifier
3502
+ );
3503
+ persistSessionCookies(writeCookies, result.data, cookieSettings);
3504
+ return toSafeAuthResult(
3505
+ result
3506
+ );
3507
+ },
3508
+ verifyEmail: async (request) => {
3509
+ const result = await createClient().auth.verifyEmail(request);
3510
+ persistSessionCookies(writeCookies, result.data, cookieSettings);
3511
+ return toSafeAuthResult(result);
3512
+ },
3513
+ signOut: async () => {
3514
+ const result = await createClient().auth.signOut();
3515
+ clearAuthCookies(writeCookies, cookieSettings);
3516
+ return result;
3517
+ }
3518
+ };
3519
+ }
3520
+
3377
3521
  // src/ssr/update-session.ts
3378
3522
  async function updateSession(options) {
3379
3523
  const accessCookieName = getAccessTokenCookieName(options.names);
@@ -3434,6 +3578,7 @@ export {
3434
3578
  DEFAULT_REFRESH_TOKEN_COOKIE,
3435
3579
  accessTokenCookieOptions,
3436
3580
  clearAuthCookies,
3581
+ createAuthActions,
3437
3582
  createBrowserClient,
3438
3583
  createRefreshAuthRouter,
3439
3584
  createServerClient,