@insforge/sdk 1.2.7 → 1.2.8-dev.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.
- package/dist/index.d.mts +17 -9
- package/dist/index.d.ts +17 -9
- package/dist/index.js +303 -122
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +303 -122
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -284,6 +284,7 @@ var TokenManager = class {
|
|
|
284
284
|
// src/lib/http-client.ts
|
|
285
285
|
var RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([500, 502, 503, 504]);
|
|
286
286
|
var IDEMPOTENT_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD", "PUT", "DELETE", "OPTIONS"]);
|
|
287
|
+
var REFRESHABLE_AUTH_ERROR_CODE = "AUTH_UNAUTHORIZED";
|
|
287
288
|
function serializeBody(method, body, headers) {
|
|
288
289
|
if (body === void 0) return void 0;
|
|
289
290
|
if (method === "GET" || method === "HEAD") return void 0;
|
|
@@ -338,12 +339,11 @@ var HttpClient = class {
|
|
|
338
339
|
*/
|
|
339
340
|
constructor(config, tokenManager, logger) {
|
|
340
341
|
this.userToken = null;
|
|
341
|
-
this.autoRefreshToken = true;
|
|
342
342
|
this.isRefreshing = false;
|
|
343
343
|
this.refreshPromise = null;
|
|
344
344
|
this.refreshToken = null;
|
|
345
|
+
this.config = config;
|
|
345
346
|
this.baseUrl = config.baseUrl || "http://localhost:7130";
|
|
346
|
-
this.autoRefreshToken = config.autoRefreshToken ?? true;
|
|
347
347
|
this.fetch = config.fetch || (globalThis.fetch ? globalThis.fetch.bind(globalThis) : void 0);
|
|
348
348
|
this.anonKey = config.anonKey;
|
|
349
349
|
this.defaultHeaders = {
|
|
@@ -393,48 +393,19 @@ var HttpClient = class {
|
|
|
393
393
|
const jitter = base * (0.85 + Math.random() * 0.3);
|
|
394
394
|
return Math.round(jitter);
|
|
395
395
|
}
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
* @param method - HTTP method (GET, POST, PUT, PATCH, DELETE).
|
|
401
|
-
* @param path - API path relative to the base URL.
|
|
402
|
-
* @param options - Optional request configuration including headers, body, and query params.
|
|
403
|
-
* @returns Parsed response data.
|
|
404
|
-
* @throws {InsForgeError} On timeout, network failure, or HTTP error responses.
|
|
405
|
-
*/
|
|
406
|
-
async handleRequest(method, path, options = {}) {
|
|
396
|
+
shouldRefreshAccessToken(statusCode, errorCode, authToken, options = {}) {
|
|
397
|
+
return statusCode === 401 && errorCode === REFRESHABLE_AUTH_ERROR_CODE && !this.config.isServerMode && !this.config.edgeFunctionToken && !options.skipAuthRefresh && authToken !== null;
|
|
398
|
+
}
|
|
399
|
+
async fetchWithRetry(args) {
|
|
407
400
|
const {
|
|
408
|
-
|
|
409
|
-
|
|
401
|
+
method,
|
|
402
|
+
url,
|
|
403
|
+
headers,
|
|
410
404
|
body,
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
const startTime = Date.now();
|
|
416
|
-
const canRetry = IDEMPOTENT_METHODS.has(method.toUpperCase()) || options.idempotent === true;
|
|
417
|
-
const maxAttempts = canRetry ? this.retryCount : 0;
|
|
418
|
-
const requestHeaders = {
|
|
419
|
-
...this.defaultHeaders
|
|
420
|
-
};
|
|
421
|
-
const authToken = this.userToken || this.anonKey;
|
|
422
|
-
if (authToken) {
|
|
423
|
-
requestHeaders["Authorization"] = `Bearer ${authToken}`;
|
|
424
|
-
}
|
|
425
|
-
const processedBody = serializeBody(method, body, requestHeaders);
|
|
426
|
-
if (headers instanceof Headers) {
|
|
427
|
-
headers.forEach((value, key) => {
|
|
428
|
-
requestHeaders[key] = value;
|
|
429
|
-
});
|
|
430
|
-
} else if (Array.isArray(headers)) {
|
|
431
|
-
headers.forEach(([key, value]) => {
|
|
432
|
-
requestHeaders[key] = value;
|
|
433
|
-
});
|
|
434
|
-
} else {
|
|
435
|
-
Object.assign(requestHeaders, headers);
|
|
436
|
-
}
|
|
437
|
-
this.logger.logRequest(method, url, requestHeaders, processedBody);
|
|
405
|
+
fetchOptions,
|
|
406
|
+
callerSignal,
|
|
407
|
+
maxAttempts
|
|
408
|
+
} = args;
|
|
438
409
|
let lastError;
|
|
439
410
|
for (let attempt = 0; attempt <= maxAttempts; attempt++) {
|
|
440
411
|
if (attempt > 0) {
|
|
@@ -486,8 +457,8 @@ var HttpClient = class {
|
|
|
486
457
|
try {
|
|
487
458
|
const response = await this.fetch(url, {
|
|
488
459
|
method,
|
|
489
|
-
headers
|
|
490
|
-
body
|
|
460
|
+
headers,
|
|
461
|
+
body,
|
|
491
462
|
...fetchOptions,
|
|
492
463
|
...controller ? { signal: controller.signal } : {}
|
|
493
464
|
});
|
|
@@ -501,31 +472,8 @@ var HttpClient = class {
|
|
|
501
472
|
);
|
|
502
473
|
continue;
|
|
503
474
|
}
|
|
504
|
-
let data;
|
|
505
|
-
try {
|
|
506
|
-
data = await parseResponse(response);
|
|
507
|
-
} catch (err) {
|
|
508
|
-
if (timer !== void 0) clearTimeout(timer);
|
|
509
|
-
if (err instanceof InsForgeError) {
|
|
510
|
-
this.logger.logResponse(
|
|
511
|
-
method,
|
|
512
|
-
url,
|
|
513
|
-
err.statusCode || response.status,
|
|
514
|
-
Date.now() - startTime,
|
|
515
|
-
err
|
|
516
|
-
);
|
|
517
|
-
}
|
|
518
|
-
throw err;
|
|
519
|
-
}
|
|
520
475
|
if (timer !== void 0) clearTimeout(timer);
|
|
521
|
-
|
|
522
|
-
method,
|
|
523
|
-
url,
|
|
524
|
-
response.status,
|
|
525
|
-
Date.now() - startTime,
|
|
526
|
-
data
|
|
527
|
-
);
|
|
528
|
-
return data;
|
|
476
|
+
return response;
|
|
529
477
|
} catch (err) {
|
|
530
478
|
if (timer !== void 0) clearTimeout(timer);
|
|
531
479
|
if (err?.name === "AbortError") {
|
|
@@ -538,9 +486,6 @@ var HttpClient = class {
|
|
|
538
486
|
}
|
|
539
487
|
throw err;
|
|
540
488
|
}
|
|
541
|
-
if (err instanceof InsForgeError) {
|
|
542
|
-
throw err;
|
|
543
|
-
}
|
|
544
489
|
if (attempt < maxAttempts) {
|
|
545
490
|
lastError = err;
|
|
546
491
|
continue;
|
|
@@ -558,32 +503,244 @@ var HttpClient = class {
|
|
|
558
503
|
"NETWORK_ERROR"
|
|
559
504
|
);
|
|
560
505
|
}
|
|
506
|
+
/**
|
|
507
|
+
* Performs an HTTP request with automatic retry and timeout handling.
|
|
508
|
+
* Retries on network errors and 5xx server errors with exponential backoff.
|
|
509
|
+
* Client errors (4xx) and timeouts are thrown immediately without retry.
|
|
510
|
+
* @param method - HTTP method (GET, POST, PUT, PATCH, DELETE).
|
|
511
|
+
* @param path - API path relative to the base URL.
|
|
512
|
+
* @param options - Optional request configuration including headers, body, and query params.
|
|
513
|
+
* @returns Parsed response data.
|
|
514
|
+
* @throws {InsForgeError} On timeout, network failure, or HTTP error responses.
|
|
515
|
+
*/
|
|
516
|
+
async handleRequest(method, path, options = {}, tokenOverride) {
|
|
517
|
+
const {
|
|
518
|
+
params,
|
|
519
|
+
headers = {},
|
|
520
|
+
body,
|
|
521
|
+
skipAuthRefresh: _skipAuthRefresh,
|
|
522
|
+
signal: callerSignal,
|
|
523
|
+
...fetchOptions
|
|
524
|
+
} = options;
|
|
525
|
+
const url = this.buildUrl(path, params);
|
|
526
|
+
const startTime = Date.now();
|
|
527
|
+
const canRetry = IDEMPOTENT_METHODS.has(method.toUpperCase()) || options.idempotent === true;
|
|
528
|
+
const maxAttempts = canRetry ? this.retryCount : 0;
|
|
529
|
+
const requestHeaders = {
|
|
530
|
+
...this.defaultHeaders
|
|
531
|
+
};
|
|
532
|
+
const authToken = tokenOverride ?? this.userToken ?? this.anonKey;
|
|
533
|
+
if (authToken) {
|
|
534
|
+
requestHeaders["Authorization"] = `Bearer ${authToken}`;
|
|
535
|
+
}
|
|
536
|
+
const processedBody = serializeBody(method, body, requestHeaders);
|
|
537
|
+
const setRequestHeader = (key, value) => {
|
|
538
|
+
if (key.toLowerCase() === "authorization") {
|
|
539
|
+
delete requestHeaders["Authorization"];
|
|
540
|
+
delete requestHeaders["authorization"];
|
|
541
|
+
requestHeaders["Authorization"] = value;
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
544
|
+
requestHeaders[key] = value;
|
|
545
|
+
};
|
|
546
|
+
if (headers instanceof Headers) {
|
|
547
|
+
headers.forEach((value, key) => {
|
|
548
|
+
setRequestHeader(key, value);
|
|
549
|
+
});
|
|
550
|
+
} else if (Array.isArray(headers)) {
|
|
551
|
+
headers.forEach(([key, value]) => {
|
|
552
|
+
setRequestHeader(key, value);
|
|
553
|
+
});
|
|
554
|
+
} else {
|
|
555
|
+
Object.entries(headers).forEach(([key, value]) => {
|
|
556
|
+
setRequestHeader(key, value);
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
this.logger.logRequest(method, url, requestHeaders, processedBody);
|
|
560
|
+
const response = await this.fetchWithRetry({
|
|
561
|
+
method,
|
|
562
|
+
url,
|
|
563
|
+
headers: requestHeaders,
|
|
564
|
+
body: processedBody,
|
|
565
|
+
fetchOptions,
|
|
566
|
+
callerSignal,
|
|
567
|
+
maxAttempts
|
|
568
|
+
});
|
|
569
|
+
let data;
|
|
570
|
+
try {
|
|
571
|
+
data = await parseResponse(response);
|
|
572
|
+
} catch (err) {
|
|
573
|
+
if (err instanceof InsForgeError) {
|
|
574
|
+
this.logger.logResponse(
|
|
575
|
+
method,
|
|
576
|
+
url,
|
|
577
|
+
err.statusCode || response.status,
|
|
578
|
+
Date.now() - startTime,
|
|
579
|
+
err
|
|
580
|
+
);
|
|
581
|
+
}
|
|
582
|
+
throw err;
|
|
583
|
+
}
|
|
584
|
+
this.logger.logResponse(
|
|
585
|
+
method,
|
|
586
|
+
url,
|
|
587
|
+
response.status,
|
|
588
|
+
Date.now() - startTime,
|
|
589
|
+
data
|
|
590
|
+
);
|
|
591
|
+
return data;
|
|
592
|
+
}
|
|
561
593
|
async request(method, path, options = {}) {
|
|
594
|
+
const tokenUsed = this.userToken;
|
|
562
595
|
try {
|
|
563
|
-
return await this.handleRequest(
|
|
596
|
+
return await this.handleRequest(
|
|
597
|
+
method,
|
|
598
|
+
path,
|
|
599
|
+
{ ...options },
|
|
600
|
+
tokenUsed
|
|
601
|
+
);
|
|
564
602
|
} catch (error) {
|
|
565
|
-
if (error instanceof InsForgeError
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
603
|
+
if (!(error instanceof InsForgeError) || !this.shouldRefreshAccessToken(
|
|
604
|
+
error.statusCode,
|
|
605
|
+
error.error,
|
|
606
|
+
tokenUsed,
|
|
607
|
+
options
|
|
608
|
+
)) {
|
|
609
|
+
throw error;
|
|
610
|
+
}
|
|
611
|
+
if (tokenUsed !== this.userToken) {
|
|
612
|
+
if (this.userToken === null) {
|
|
613
|
+
throw error;
|
|
614
|
+
}
|
|
615
|
+
return await this.handleRequest(
|
|
616
|
+
method,
|
|
617
|
+
path,
|
|
618
|
+
{
|
|
619
|
+
...options,
|
|
620
|
+
skipAuthRefresh: true
|
|
621
|
+
},
|
|
622
|
+
this.userToken
|
|
623
|
+
);
|
|
624
|
+
}
|
|
625
|
+
try {
|
|
626
|
+
await this.refreshAndSaveSession();
|
|
627
|
+
} catch (error2) {
|
|
628
|
+
this.clearAuthSession();
|
|
629
|
+
throw error2;
|
|
630
|
+
}
|
|
631
|
+
return await this.handleRequest(method, path, {
|
|
632
|
+
...options,
|
|
633
|
+
skipAuthRefresh: true
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
/**
|
|
638
|
+
* Performs an SDK-configured fetch and returns the raw Response.
|
|
639
|
+
* This is used by clients such as postgrest-js that need to own response
|
|
640
|
+
* parsing while still sharing SDK auth and refresh behavior.
|
|
641
|
+
*/
|
|
642
|
+
async rawFetch(input, init, options = {}) {
|
|
643
|
+
const request = typeof Request !== "undefined" && input instanceof Request ? input : void 0;
|
|
644
|
+
const {
|
|
645
|
+
method: initMethod,
|
|
646
|
+
headers: initHeaders,
|
|
647
|
+
body: initBody,
|
|
648
|
+
signal: initSignal,
|
|
649
|
+
...fetchOptions
|
|
650
|
+
} = init ?? {};
|
|
651
|
+
const method = initMethod ?? request?.method ?? "GET";
|
|
652
|
+
const url = request?.url ?? input.toString();
|
|
653
|
+
const startTime = Date.now();
|
|
654
|
+
const tokenUsed = this.userToken;
|
|
655
|
+
const headers = new Headers({
|
|
656
|
+
...this.defaultHeaders
|
|
657
|
+
});
|
|
658
|
+
const authToken = tokenUsed ?? this.anonKey;
|
|
659
|
+
if (authToken) {
|
|
660
|
+
headers.set("Authorization", `Bearer ${authToken}`);
|
|
661
|
+
}
|
|
662
|
+
request?.headers.forEach((value, key) => {
|
|
663
|
+
headers.set(key, value);
|
|
664
|
+
});
|
|
665
|
+
new Headers(initHeaders).forEach((value, key) => {
|
|
666
|
+
headers.set(key, value);
|
|
667
|
+
});
|
|
668
|
+
const requestHeaders = {};
|
|
669
|
+
headers.forEach((value, key) => {
|
|
670
|
+
requestHeaders[key] = value;
|
|
671
|
+
});
|
|
672
|
+
const sourceBody = initBody ?? request?.body ?? void 0;
|
|
673
|
+
let body = sourceBody;
|
|
674
|
+
let retryInit = init;
|
|
675
|
+
if (typeof ReadableStream !== "undefined" && sourceBody instanceof ReadableStream) {
|
|
676
|
+
body = await new Response(sourceBody).arrayBuffer();
|
|
677
|
+
retryInit = { ...init ?? {}, body };
|
|
678
|
+
}
|
|
679
|
+
const callerSignal = initSignal ?? request?.signal;
|
|
680
|
+
const maxAttempts = IDEMPOTENT_METHODS.has(method.toUpperCase()) ? this.retryCount : 0;
|
|
681
|
+
this.logger.logRequest(method, url, requestHeaders, body);
|
|
682
|
+
const response = await this.fetchWithRetry({
|
|
683
|
+
method,
|
|
684
|
+
url,
|
|
685
|
+
headers: requestHeaders,
|
|
686
|
+
body,
|
|
687
|
+
fetchOptions,
|
|
688
|
+
callerSignal,
|
|
689
|
+
maxAttempts
|
|
690
|
+
});
|
|
691
|
+
this.logger.logResponse(
|
|
692
|
+
method,
|
|
693
|
+
url,
|
|
694
|
+
response.status,
|
|
695
|
+
Date.now() - startTime
|
|
696
|
+
);
|
|
697
|
+
let errorCode = null;
|
|
698
|
+
if (response.status === 401) {
|
|
699
|
+
try {
|
|
700
|
+
const data = await response.clone().json();
|
|
701
|
+
if (data && typeof data === "object") {
|
|
702
|
+
const candidate = data.error ?? data.code;
|
|
703
|
+
if (typeof candidate === "string") {
|
|
704
|
+
errorCode = candidate;
|
|
575
705
|
}
|
|
576
|
-
return await this.handleRequest(method, path, { ...options });
|
|
577
|
-
} catch (error2) {
|
|
578
|
-
this.tokenManager.clearSession();
|
|
579
|
-
this.userToken = null;
|
|
580
|
-
this.refreshToken = null;
|
|
581
|
-
clearCsrfToken();
|
|
582
|
-
throw error2;
|
|
583
706
|
}
|
|
707
|
+
} catch {
|
|
584
708
|
}
|
|
709
|
+
}
|
|
710
|
+
if (!this.shouldRefreshAccessToken(
|
|
711
|
+
response.status,
|
|
712
|
+
errorCode,
|
|
713
|
+
tokenUsed,
|
|
714
|
+
options
|
|
715
|
+
)) {
|
|
716
|
+
return response;
|
|
717
|
+
}
|
|
718
|
+
if (tokenUsed !== this.userToken) {
|
|
719
|
+
if (this.userToken === null) {
|
|
720
|
+
return response;
|
|
721
|
+
}
|
|
722
|
+
const retryHeaders2 = new Headers(initHeaders);
|
|
723
|
+
retryHeaders2.set("Authorization", `Bearer ${this.userToken}`);
|
|
724
|
+
return await this.rawFetch(
|
|
725
|
+
input,
|
|
726
|
+
{ ...retryInit, headers: retryHeaders2 },
|
|
727
|
+
{ skipAuthRefresh: true }
|
|
728
|
+
);
|
|
729
|
+
}
|
|
730
|
+
let newTokenData;
|
|
731
|
+
try {
|
|
732
|
+
newTokenData = await this.refreshAndSaveSession();
|
|
733
|
+
} catch (error) {
|
|
734
|
+
this.clearAuthSession();
|
|
585
735
|
throw error;
|
|
586
736
|
}
|
|
737
|
+
const retryHeaders = new Headers(initHeaders);
|
|
738
|
+
retryHeaders.set("Authorization", `Bearer ${newTokenData.accessToken}`);
|
|
739
|
+
return await this.rawFetch(
|
|
740
|
+
input,
|
|
741
|
+
{ ...retryInit, headers: retryHeaders },
|
|
742
|
+
{ skipAuthRefresh: true }
|
|
743
|
+
);
|
|
587
744
|
}
|
|
588
745
|
/** Performs a GET request. */
|
|
589
746
|
get(path, options) {
|
|
@@ -621,7 +778,7 @@ var HttpClient = class {
|
|
|
621
778
|
}
|
|
622
779
|
return headers;
|
|
623
780
|
}
|
|
624
|
-
async
|
|
781
|
+
async refreshAccessToken() {
|
|
625
782
|
if (this.isRefreshing) {
|
|
626
783
|
return this.refreshPromise;
|
|
627
784
|
}
|
|
@@ -632,7 +789,7 @@ var HttpClient = class {
|
|
|
632
789
|
const body = this.refreshToken ? { refreshToken: this.refreshToken } : void 0;
|
|
633
790
|
const response = await this.handleRequest(
|
|
634
791
|
"POST",
|
|
635
|
-
"/api/auth/
|
|
792
|
+
this.refreshToken ? "/api/auth/refresh?client_type=mobile" : "/api/auth/refresh",
|
|
636
793
|
{
|
|
637
794
|
body,
|
|
638
795
|
headers: csrfToken ? { "X-CSRF-Token": csrfToken } : {},
|
|
@@ -647,6 +804,24 @@ var HttpClient = class {
|
|
|
647
804
|
})();
|
|
648
805
|
return this.refreshPromise;
|
|
649
806
|
}
|
|
807
|
+
async refreshAndSaveSession() {
|
|
808
|
+
const newTokenData = await this.refreshAccessToken();
|
|
809
|
+
this.setAuthToken(newTokenData.accessToken);
|
|
810
|
+
this.tokenManager.saveSession(newTokenData);
|
|
811
|
+
if (newTokenData.csrfToken) {
|
|
812
|
+
setCsrfToken(newTokenData.csrfToken);
|
|
813
|
+
}
|
|
814
|
+
if (newTokenData.refreshToken) {
|
|
815
|
+
this.setRefreshToken(newTokenData.refreshToken);
|
|
816
|
+
}
|
|
817
|
+
return newTokenData;
|
|
818
|
+
}
|
|
819
|
+
clearAuthSession() {
|
|
820
|
+
this.tokenManager.clearSession();
|
|
821
|
+
this.userToken = null;
|
|
822
|
+
this.refreshToken = null;
|
|
823
|
+
clearCsrfToken();
|
|
824
|
+
}
|
|
650
825
|
};
|
|
651
826
|
|
|
652
827
|
// src/modules/auth/helpers.ts
|
|
@@ -775,7 +950,7 @@ var Auth = class {
|
|
|
775
950
|
const response = await this.http.post(
|
|
776
951
|
this.isServerMode() ? "/api/auth/users?client_type=mobile" : "/api/auth/users",
|
|
777
952
|
request,
|
|
778
|
-
{ credentials: "include" }
|
|
953
|
+
{ credentials: "include", skipAuthRefresh: true }
|
|
779
954
|
);
|
|
780
955
|
if (response.accessToken && response.user) {
|
|
781
956
|
this.saveSessionFromResponse(response);
|
|
@@ -793,7 +968,7 @@ var Auth = class {
|
|
|
793
968
|
const response = await this.http.post(
|
|
794
969
|
this.isServerMode() ? "/api/auth/sessions?client_type=mobile" : "/api/auth/sessions",
|
|
795
970
|
request,
|
|
796
|
-
{ credentials: "include" }
|
|
971
|
+
{ credentials: "include", skipAuthRefresh: true }
|
|
797
972
|
);
|
|
798
973
|
this.saveSessionFromResponse(response);
|
|
799
974
|
if (response.refreshToken) {
|
|
@@ -810,7 +985,7 @@ var Auth = class {
|
|
|
810
985
|
await this.http.post(
|
|
811
986
|
this.isServerMode() ? "/api/auth/logout?client_type=mobile" : "/api/auth/logout",
|
|
812
987
|
void 0,
|
|
813
|
-
{ credentials: "include" }
|
|
988
|
+
{ credentials: "include", skipAuthRefresh: true }
|
|
814
989
|
);
|
|
815
990
|
} catch {
|
|
816
991
|
}
|
|
@@ -847,7 +1022,8 @@ var Auth = class {
|
|
|
847
1022
|
);
|
|
848
1023
|
const oauthPath = isBuiltInProvider ? `/api/auth/oauth/${providerKey}` : `/api/auth/oauth/custom/${providerKey}`;
|
|
849
1024
|
const response = await this.http.get(oauthPath, {
|
|
850
|
-
params
|
|
1025
|
+
params,
|
|
1026
|
+
skipAuthRefresh: true
|
|
851
1027
|
});
|
|
852
1028
|
if (!this.isServerMode() && typeof window !== "undefined" && !skipBrowserRedirect) {
|
|
853
1029
|
window.location.href = response.authUrl;
|
|
@@ -895,7 +1071,7 @@ var Auth = class {
|
|
|
895
1071
|
const response = await this.http.post(
|
|
896
1072
|
this.isServerMode() ? "/api/auth/oauth/exchange?client_type=mobile" : "/api/auth/oauth/exchange",
|
|
897
1073
|
request,
|
|
898
|
-
{ credentials: "include" }
|
|
1074
|
+
{ credentials: "include", skipAuthRefresh: true }
|
|
899
1075
|
);
|
|
900
1076
|
this.saveSessionFromResponse(response);
|
|
901
1077
|
return {
|
|
@@ -922,7 +1098,7 @@ var Auth = class {
|
|
|
922
1098
|
const response = await this.http.post(
|
|
923
1099
|
"/api/auth/id-token?client_type=mobile",
|
|
924
1100
|
{ provider, token },
|
|
925
|
-
{ credentials: "include" }
|
|
1101
|
+
{ credentials: "include", skipAuthRefresh: true }
|
|
926
1102
|
);
|
|
927
1103
|
this.saveSessionFromResponse(response);
|
|
928
1104
|
if (response.refreshToken) {
|
|
@@ -969,7 +1145,8 @@ var Auth = class {
|
|
|
969
1145
|
this.isServerMode() ? { refresh_token: options?.refreshToken } : void 0,
|
|
970
1146
|
{
|
|
971
1147
|
headers: csrfToken ? { "X-CSRF-Token": csrfToken } : {},
|
|
972
|
-
credentials: "include"
|
|
1148
|
+
credentials: "include",
|
|
1149
|
+
skipAuthRefresh: true
|
|
973
1150
|
}
|
|
974
1151
|
);
|
|
975
1152
|
if (response.accessToken) {
|
|
@@ -1072,7 +1249,9 @@ var Auth = class {
|
|
|
1072
1249
|
// ============================================================================
|
|
1073
1250
|
async resendVerificationEmail(request) {
|
|
1074
1251
|
try {
|
|
1075
|
-
const response = await this.http.post("/api/auth/email/send-verification", request
|
|
1252
|
+
const response = await this.http.post("/api/auth/email/send-verification", request, {
|
|
1253
|
+
skipAuthRefresh: true
|
|
1254
|
+
});
|
|
1076
1255
|
return { data: response, error: null };
|
|
1077
1256
|
} catch (error) {
|
|
1078
1257
|
return wrapError(
|
|
@@ -1086,7 +1265,7 @@ var Auth = class {
|
|
|
1086
1265
|
const response = await this.http.post(
|
|
1087
1266
|
this.isServerMode() ? "/api/auth/email/verify?client_type=mobile" : "/api/auth/email/verify",
|
|
1088
1267
|
request,
|
|
1089
|
-
{ credentials: "include" }
|
|
1268
|
+
{ credentials: "include", skipAuthRefresh: true }
|
|
1090
1269
|
);
|
|
1091
1270
|
this.saveSessionFromResponse(response);
|
|
1092
1271
|
if (response.refreshToken) {
|
|
@@ -1105,7 +1284,9 @@ var Auth = class {
|
|
|
1105
1284
|
// ============================================================================
|
|
1106
1285
|
async sendResetPasswordEmail(request) {
|
|
1107
1286
|
try {
|
|
1108
|
-
const response = await this.http.post("/api/auth/email/send-reset-password", request
|
|
1287
|
+
const response = await this.http.post("/api/auth/email/send-reset-password", request, {
|
|
1288
|
+
skipAuthRefresh: true
|
|
1289
|
+
});
|
|
1109
1290
|
return { data: response, error: null };
|
|
1110
1291
|
} catch (error) {
|
|
1111
1292
|
return wrapError(
|
|
@@ -1118,7 +1299,8 @@ var Auth = class {
|
|
|
1118
1299
|
try {
|
|
1119
1300
|
const response = await this.http.post(
|
|
1120
1301
|
"/api/auth/email/exchange-reset-password-token",
|
|
1121
|
-
request
|
|
1302
|
+
request,
|
|
1303
|
+
{ skipAuthRefresh: true }
|
|
1122
1304
|
);
|
|
1123
1305
|
return { data: response, error: null };
|
|
1124
1306
|
} catch (error) {
|
|
@@ -1132,7 +1314,8 @@ var Auth = class {
|
|
|
1132
1314
|
try {
|
|
1133
1315
|
const response = await this.http.post(
|
|
1134
1316
|
"/api/auth/email/reset-password",
|
|
1135
|
-
request
|
|
1317
|
+
request,
|
|
1318
|
+
{ skipAuthRefresh: true }
|
|
1136
1319
|
);
|
|
1137
1320
|
return { data: response, error: null };
|
|
1138
1321
|
} catch (error) {
|
|
@@ -1148,7 +1331,8 @@ var Auth = class {
|
|
|
1148
1331
|
async getPublicAuthConfig() {
|
|
1149
1332
|
try {
|
|
1150
1333
|
const response = await this.http.get(
|
|
1151
|
-
"/api/auth/public-config"
|
|
1334
|
+
"/api/auth/public-config",
|
|
1335
|
+
{ skipAuthRefresh: true }
|
|
1152
1336
|
);
|
|
1153
1337
|
return { data: response, error: null };
|
|
1154
1338
|
} catch (error) {
|
|
@@ -1162,7 +1346,7 @@ var Auth = class {
|
|
|
1162
1346
|
|
|
1163
1347
|
// src/modules/database-postgrest.ts
|
|
1164
1348
|
import { PostgrestClient } from "@supabase/postgrest-js";
|
|
1165
|
-
function createInsForgePostgrestFetch(httpClient
|
|
1349
|
+
function createInsForgePostgrestFetch(httpClient) {
|
|
1166
1350
|
return async (input, init) => {
|
|
1167
1351
|
const url = typeof input === "string" ? input : input.toString();
|
|
1168
1352
|
const urlObj = new URL(url);
|
|
@@ -1170,14 +1354,11 @@ function createInsForgePostgrestFetch(httpClient, tokenManager) {
|
|
|
1170
1354
|
const rpcMatch = pathname.match(/^rpc\/(.+)$/);
|
|
1171
1355
|
const endpoint = rpcMatch ? `/api/database/rpc/${rpcMatch[1]}` : `/api/database/records/${pathname}`;
|
|
1172
1356
|
const insforgeUrl = `${httpClient.baseUrl}${endpoint}${urlObj.search}`;
|
|
1173
|
-
const
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
headers.set("Authorization", `Bearer ${authToken}`);
|
|
1179
|
-
}
|
|
1180
|
-
const response = await fetch(insforgeUrl, {
|
|
1357
|
+
const headers = new Headers(httpClient.getHeaders());
|
|
1358
|
+
new Headers(init?.headers).forEach((value, key) => {
|
|
1359
|
+
headers.set(key, value);
|
|
1360
|
+
});
|
|
1361
|
+
const response = await httpClient.rawFetch(insforgeUrl, {
|
|
1181
1362
|
...init,
|
|
1182
1363
|
headers
|
|
1183
1364
|
});
|
|
@@ -1185,42 +1366,42 @@ function createInsForgePostgrestFetch(httpClient, tokenManager) {
|
|
|
1185
1366
|
};
|
|
1186
1367
|
}
|
|
1187
1368
|
var Database = class {
|
|
1188
|
-
constructor(httpClient
|
|
1369
|
+
constructor(httpClient) {
|
|
1189
1370
|
this.postgrest = new PostgrestClient("http://dummy", {
|
|
1190
|
-
fetch: createInsForgePostgrestFetch(httpClient
|
|
1371
|
+
fetch: createInsForgePostgrestFetch(httpClient),
|
|
1191
1372
|
headers: {}
|
|
1192
1373
|
});
|
|
1193
1374
|
}
|
|
1194
1375
|
/**
|
|
1195
1376
|
* Create a query builder for a table
|
|
1196
|
-
*
|
|
1377
|
+
*
|
|
1197
1378
|
* @example
|
|
1198
1379
|
* // Basic query
|
|
1199
1380
|
* const { data, error } = await client.database
|
|
1200
1381
|
* .from('posts')
|
|
1201
1382
|
* .select('*')
|
|
1202
1383
|
* .eq('user_id', userId);
|
|
1203
|
-
*
|
|
1384
|
+
*
|
|
1204
1385
|
* // With count (Supabase style!)
|
|
1205
1386
|
* const { data, error, count } = await client.database
|
|
1206
1387
|
* .from('posts')
|
|
1207
1388
|
* .select('*', { count: 'exact' })
|
|
1208
1389
|
* .range(0, 9);
|
|
1209
|
-
*
|
|
1390
|
+
*
|
|
1210
1391
|
* // Just get count, no data
|
|
1211
1392
|
* const { count } = await client.database
|
|
1212
1393
|
* .from('posts')
|
|
1213
1394
|
* .select('*', { count: 'exact', head: true });
|
|
1214
|
-
*
|
|
1395
|
+
*
|
|
1215
1396
|
* // Complex queries with OR
|
|
1216
1397
|
* const { data } = await client.database
|
|
1217
1398
|
* .from('posts')
|
|
1218
1399
|
* .select('*, users!inner(*)')
|
|
1219
1400
|
* .or('status.eq.active,status.eq.pending');
|
|
1220
|
-
*
|
|
1401
|
+
*
|
|
1221
1402
|
* // All features work:
|
|
1222
1403
|
* - Nested selects
|
|
1223
|
-
* - Foreign key expansion
|
|
1404
|
+
* - Foreign key expansion
|
|
1224
1405
|
* - OR/AND/NOT conditions
|
|
1225
1406
|
* - Count with head
|
|
1226
1407
|
* - Range pagination
|
|
@@ -2320,7 +2501,7 @@ var InsForgeClient = class {
|
|
|
2320
2501
|
this.auth = new Auth(this.http, this.tokenManager, {
|
|
2321
2502
|
isServerMode: config.isServerMode ?? !!config.edgeFunctionToken
|
|
2322
2503
|
});
|
|
2323
|
-
this.database = new Database(this.http
|
|
2504
|
+
this.database = new Database(this.http);
|
|
2324
2505
|
this.storage = new Storage(this.http);
|
|
2325
2506
|
this.ai = new AI(this.http);
|
|
2326
2507
|
this.functions = new Functions(this.http, config.functionsUrl);
|