@insforge/sdk 1.4.0 → 1.4.2
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/README.md +139 -10
- package/SDK-REFERENCE.md +34 -20
- package/dist/{client-CqfpCc8Z.d.mts → client-BR9o-WUm.d.ts} +53 -112
- package/dist/{client-CqfpCc8Z.d.ts → client-C-qBRoea.d.mts} +53 -112
- package/dist/index.d.mts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +124 -19
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +121 -16
- package/dist/index.mjs.map +1 -1
- package/dist/middleware-K59XjpUX.d.mts +67 -0
- package/dist/middleware-Tu_RlUAt.d.ts +67 -0
- package/dist/ssr/middleware.d.mts +3 -0
- package/dist/ssr/middleware.d.ts +3 -0
- package/dist/ssr/middleware.js +461 -0
- package/dist/ssr/middleware.js.map +1 -0
- package/dist/ssr/middleware.mjs +428 -0
- package/dist/ssr/middleware.mjs.map +1 -0
- package/dist/ssr.d.mts +45 -66
- package/dist/ssr.d.ts +45 -66
- package/dist/ssr.js +234 -15
- package/dist/ssr.js.map +1 -1
- package/dist/ssr.mjs +233 -15
- package/dist/ssr.mjs.map +1 -1
- package/dist/types-Dk-44JJf.d.mts +130 -0
- package/dist/types-Dk-44JJf.d.ts +130 -0
- package/package.json +6 -1
package/dist/ssr.mjs
CHANGED
|
@@ -397,7 +397,7 @@ var HttpClient = class {
|
|
|
397
397
|
return Math.round(jitter);
|
|
398
398
|
}
|
|
399
399
|
shouldRefreshAccessToken(statusCode, errorCode, authToken, options = {}) {
|
|
400
|
-
return statusCode === 401 && REFRESHABLE_AUTH_ERROR_CODES.has(errorCode ?? "") && !this.config.isServerMode && !this.config.edgeFunctionToken && !options.skipAuthRefresh && authToken !== null;
|
|
400
|
+
return statusCode === 401 && REFRESHABLE_AUTH_ERROR_CODES.has(errorCode ?? "") && !this.config.isServerMode && !this.config.accessToken && !this.config.edgeFunctionToken && !options.skipAuthRefresh && authToken !== null;
|
|
401
401
|
}
|
|
402
402
|
async fetchWithRetry(args) {
|
|
403
403
|
const {
|
|
@@ -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
|
-
|
|
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
|
|
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;
|
|
@@ -1038,7 +1051,7 @@ var Auth = class {
|
|
|
1038
1051
|
}
|
|
1039
1052
|
const { provider } = signInOptions;
|
|
1040
1053
|
const providerKey = encodeURIComponent(provider.toLowerCase());
|
|
1041
|
-
const codeVerifier = generateCodeVerifier();
|
|
1054
|
+
const codeVerifier = await generateCodeVerifier();
|
|
1042
1055
|
const codeChallenge = await generateCodeChallenge(codeVerifier);
|
|
1043
1056
|
storePkceVerifier(codeVerifier);
|
|
1044
1057
|
const params = {
|
|
@@ -1609,7 +1622,7 @@ var StorageBucket = class {
|
|
|
1609
1622
|
size: file.size,
|
|
1610
1623
|
mimeType: file.type || "application/octet-stream",
|
|
1611
1624
|
uploadedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1612
|
-
url: this.getPublicUrl(strategy.key)
|
|
1625
|
+
url: this.getPublicUrl(strategy.key).data.publicUrl
|
|
1613
1626
|
},
|
|
1614
1627
|
error: null
|
|
1615
1628
|
};
|
|
@@ -1681,11 +1694,101 @@ var StorageBucket = class {
|
|
|
1681
1694
|
}
|
|
1682
1695
|
}
|
|
1683
1696
|
/**
|
|
1684
|
-
* Get public URL for a
|
|
1697
|
+
* Get the public URL for an object in a public bucket.
|
|
1698
|
+
*
|
|
1699
|
+
* Pure string construction — no network call, no auth. The URL only resolves
|
|
1700
|
+
* if the bucket is public; for private objects use {@link createSignedUrl}.
|
|
1701
|
+
*
|
|
1685
1702
|
* @param path - The object key/path
|
|
1703
|
+
* @returns `{ data: { publicUrl }, error }` — matches the external SDK pattern,
|
|
1704
|
+
* so `const { data } = getPublicUrl(path)` then `data.publicUrl`.
|
|
1686
1705
|
*/
|
|
1687
1706
|
getPublicUrl(path) {
|
|
1688
|
-
|
|
1707
|
+
const publicUrl = `${this.http.baseUrl}/api/storage/buckets/${this.bucketName}/objects/${encodeURIComponent(path)}`;
|
|
1708
|
+
return { data: { publicUrl }, error: null };
|
|
1709
|
+
}
|
|
1710
|
+
/**
|
|
1711
|
+
* Resolve a download strategy (signed or direct URL) for an object with a
|
|
1712
|
+
* caller-supplied TTL. Prefers the canonical GET route and falls back to the
|
|
1713
|
+
* legacy POST alias so signed-URL creation still works against older backends
|
|
1714
|
+
* that predate the GET route (they return 404/405 for it). A genuine
|
|
1715
|
+
* "object not found" (STORAGE_NOT_FOUND) is not retried.
|
|
1716
|
+
*/
|
|
1717
|
+
async requestDownloadStrategy(path, expiresIn) {
|
|
1718
|
+
const encoded = encodeURIComponent(path);
|
|
1719
|
+
try {
|
|
1720
|
+
return await this.http.get(
|
|
1721
|
+
`/api/storage/buckets/${this.bucketName}/download-strategy/objects/${encoded}`,
|
|
1722
|
+
{ params: { expiresIn: expiresIn.toString() } }
|
|
1723
|
+
);
|
|
1724
|
+
} catch (error) {
|
|
1725
|
+
const status = error instanceof InsForgeError ? error.statusCode : void 0;
|
|
1726
|
+
const isMissingRoute = (status === 404 || status === 405) && !(error instanceof InsForgeError && error.error === "STORAGE_NOT_FOUND");
|
|
1727
|
+
if (!isMissingRoute) throw error;
|
|
1728
|
+
return await this.http.post(
|
|
1729
|
+
`/api/storage/buckets/${this.bucketName}/objects/${encoded}/download-strategy`,
|
|
1730
|
+
{ expiresIn }
|
|
1731
|
+
);
|
|
1732
|
+
}
|
|
1733
|
+
}
|
|
1734
|
+
/**
|
|
1735
|
+
* Create a signed URL for an object.
|
|
1736
|
+
*
|
|
1737
|
+
* Returns a time-limited, credential-free URL that can be handed directly to
|
|
1738
|
+
* a browser (`<img src>`), an email, or a third party — no SDK or session is
|
|
1739
|
+
* needed to fetch it. Authorization is enforced when the URL is minted (the
|
|
1740
|
+
* caller must be allowed to read the object), so the resulting link is a
|
|
1741
|
+
* pre-authorized capability scoped to this one object until it expires.
|
|
1742
|
+
*
|
|
1743
|
+
* @param path - The object key/path
|
|
1744
|
+
* @param expiresIn - Lifetime in seconds (default 3600 = 1h, max 604800 = 7d).
|
|
1745
|
+
* Honored for private buckets; public buckets return their long-lived URL.
|
|
1746
|
+
*/
|
|
1747
|
+
async createSignedUrl(path, expiresIn = 3600) {
|
|
1748
|
+
try {
|
|
1749
|
+
const strategy = await this.requestDownloadStrategy(path, expiresIn);
|
|
1750
|
+
return {
|
|
1751
|
+
data: {
|
|
1752
|
+
signedUrl: strategy.url,
|
|
1753
|
+
expiresAt: strategy.expiresAt ? new Date(strategy.expiresAt).toISOString() : null
|
|
1754
|
+
},
|
|
1755
|
+
error: null
|
|
1756
|
+
};
|
|
1757
|
+
} catch (error) {
|
|
1758
|
+
return {
|
|
1759
|
+
data: null,
|
|
1760
|
+
error: error instanceof InsForgeError ? error : new InsForgeError("Failed to create signed URL", 500, "STORAGE_ERROR")
|
|
1761
|
+
};
|
|
1762
|
+
}
|
|
1763
|
+
}
|
|
1764
|
+
/**
|
|
1765
|
+
* Create signed URLs for multiple objects in a single call.
|
|
1766
|
+
*
|
|
1767
|
+
* Each entry resolves independently: a failure on one key (not found / not
|
|
1768
|
+
* permitted) is reported on that entry's `error` without failing the rest.
|
|
1769
|
+
*
|
|
1770
|
+
* @param paths - The object keys/paths
|
|
1771
|
+
* @param expiresIn - Lifetime in seconds (default 3600 = 1h, max 604800 = 7d)
|
|
1772
|
+
*/
|
|
1773
|
+
async createSignedUrls(paths, expiresIn = 3600) {
|
|
1774
|
+
try {
|
|
1775
|
+
const data = await Promise.all(
|
|
1776
|
+
paths.map(async (path) => {
|
|
1777
|
+
const { data: signed, error } = await this.createSignedUrl(path, expiresIn);
|
|
1778
|
+
return {
|
|
1779
|
+
path,
|
|
1780
|
+
signedUrl: signed?.signedUrl ?? null,
|
|
1781
|
+
error: error ? error.message : null
|
|
1782
|
+
};
|
|
1783
|
+
})
|
|
1784
|
+
);
|
|
1785
|
+
return { data, error: null };
|
|
1786
|
+
} catch (error) {
|
|
1787
|
+
return {
|
|
1788
|
+
data: null,
|
|
1789
|
+
error: error instanceof InsForgeError ? error : new InsForgeError("Failed to create signed URLs", 500, "STORAGE_ERROR")
|
|
1790
|
+
};
|
|
1791
|
+
}
|
|
1689
1792
|
}
|
|
1690
1793
|
/**
|
|
1691
1794
|
* List objects in the bucket
|
|
@@ -2664,12 +2767,14 @@ var InsForgeClient = class {
|
|
|
2664
2767
|
const logger = new Logger(config.debug);
|
|
2665
2768
|
this.tokenManager = new TokenManager();
|
|
2666
2769
|
this.http = new HttpClient(config, this.tokenManager, logger);
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
this.
|
|
2770
|
+
const accessToken = config.accessToken ?? config.edgeFunctionToken;
|
|
2771
|
+
if (accessToken) {
|
|
2772
|
+
this.http.setAuthToken(accessToken);
|
|
2773
|
+
this.tokenManager.setAccessToken(accessToken);
|
|
2670
2774
|
}
|
|
2671
2775
|
this.auth = new Auth(this.http, this.tokenManager, {
|
|
2672
|
-
isServerMode: config.isServerMode ?? !!
|
|
2776
|
+
isServerMode: config.isServerMode ?? !!accessToken,
|
|
2777
|
+
detectOAuthCallback: config.auth?.detectOAuthCallback
|
|
2673
2778
|
});
|
|
2674
2779
|
this.database = new Database(this.http);
|
|
2675
2780
|
this.storage = new Storage(this.http);
|
|
@@ -3075,7 +3180,13 @@ function createBrowserClient(options = {}) {
|
|
|
3075
3180
|
...options,
|
|
3076
3181
|
baseUrl,
|
|
3077
3182
|
anonKey,
|
|
3078
|
-
fetch: ssrFetch
|
|
3183
|
+
fetch: ssrFetch,
|
|
3184
|
+
// Browser clients manage tokens via the refresh route, not a static
|
|
3185
|
+
// config token; shadow any untyped accessToken in the options spread.
|
|
3186
|
+
accessToken: void 0,
|
|
3187
|
+
auth: {
|
|
3188
|
+
detectOAuthCallback: false
|
|
3189
|
+
}
|
|
3079
3190
|
});
|
|
3080
3191
|
const setAccessToken = client.setAccessToken.bind(client);
|
|
3081
3192
|
client.setAccessToken = (token) => {
|
|
@@ -3113,7 +3224,10 @@ function createServerClient(options = {}) {
|
|
|
3113
3224
|
baseUrl,
|
|
3114
3225
|
anonKey,
|
|
3115
3226
|
isServerMode: true,
|
|
3116
|
-
|
|
3227
|
+
accessToken: accessToken ?? void 0,
|
|
3228
|
+
// The cookie/option token is the only credential source here; shadow any
|
|
3229
|
+
// untyped edgeFunctionToken smuggled through the options spread.
|
|
3230
|
+
edgeFunctionToken: void 0
|
|
3117
3231
|
});
|
|
3118
3232
|
}
|
|
3119
3233
|
|
|
@@ -3277,6 +3391,109 @@ function createRefreshAuthRouter(options = {}) {
|
|
|
3277
3391
|
};
|
|
3278
3392
|
}
|
|
3279
3393
|
|
|
3394
|
+
// src/ssr/auth-actions.ts
|
|
3395
|
+
function persistSessionCookies(cookies, data, settings) {
|
|
3396
|
+
if (!data?.accessToken) return;
|
|
3397
|
+
setAuthCookies(
|
|
3398
|
+
cookies,
|
|
3399
|
+
{
|
|
3400
|
+
accessToken: data.accessToken,
|
|
3401
|
+
refreshToken: data.refreshToken
|
|
3402
|
+
},
|
|
3403
|
+
settings
|
|
3404
|
+
);
|
|
3405
|
+
}
|
|
3406
|
+
function sanitizeAuthData(data) {
|
|
3407
|
+
if (!data) return null;
|
|
3408
|
+
const {
|
|
3409
|
+
accessToken: _accessToken,
|
|
3410
|
+
refreshToken: _refreshToken,
|
|
3411
|
+
csrfToken: _csrfToken,
|
|
3412
|
+
...safeData
|
|
3413
|
+
} = data;
|
|
3414
|
+
return safeData;
|
|
3415
|
+
}
|
|
3416
|
+
function toSafeAuthResult(result) {
|
|
3417
|
+
return {
|
|
3418
|
+
data: sanitizeAuthData(result.data),
|
|
3419
|
+
error: result.error
|
|
3420
|
+
};
|
|
3421
|
+
}
|
|
3422
|
+
function createAuthActions(options = {}) {
|
|
3423
|
+
const {
|
|
3424
|
+
cookies,
|
|
3425
|
+
requestCookies,
|
|
3426
|
+
responseCookies,
|
|
3427
|
+
names,
|
|
3428
|
+
options: cookieOptions,
|
|
3429
|
+
...clientOptions
|
|
3430
|
+
} = options;
|
|
3431
|
+
const readCookies = requestCookies ?? cookies;
|
|
3432
|
+
const writeCookies = responseCookies ?? cookies;
|
|
3433
|
+
if (!writeCookies?.set) {
|
|
3434
|
+
throw new Error(
|
|
3435
|
+
"createAuthActions() requires a writable cookie store. Pass cookies in Server Actions or responseCookies in Route Handlers."
|
|
3436
|
+
);
|
|
3437
|
+
}
|
|
3438
|
+
const cookieSettings = {
|
|
3439
|
+
names,
|
|
3440
|
+
options: cookieOptions
|
|
3441
|
+
};
|
|
3442
|
+
const createClient = () => createServerClient({
|
|
3443
|
+
...clientOptions,
|
|
3444
|
+
names,
|
|
3445
|
+
options: cookieOptions,
|
|
3446
|
+
cookies: readCookies
|
|
3447
|
+
});
|
|
3448
|
+
return {
|
|
3449
|
+
signUp: async (request) => {
|
|
3450
|
+
const result = await createClient().auth.signUp(request);
|
|
3451
|
+
persistSessionCookies(writeCookies, result.data, cookieSettings);
|
|
3452
|
+
return toSafeAuthResult(result);
|
|
3453
|
+
},
|
|
3454
|
+
signInWithPassword: async (request) => {
|
|
3455
|
+
const result = await createClient().auth.signInWithPassword(request);
|
|
3456
|
+
persistSessionCookies(writeCookies, result.data, cookieSettings);
|
|
3457
|
+
return toSafeAuthResult(
|
|
3458
|
+
result
|
|
3459
|
+
);
|
|
3460
|
+
},
|
|
3461
|
+
signInWithOAuth: async (providerOrOptions, signInOptions) => {
|
|
3462
|
+
return createClient().auth.signInWithOAuth(
|
|
3463
|
+
providerOrOptions,
|
|
3464
|
+
signInOptions
|
|
3465
|
+
);
|
|
3466
|
+
},
|
|
3467
|
+
signInWithIdToken: async (credentials) => {
|
|
3468
|
+
const result = await createClient().auth.signInWithIdToken(credentials);
|
|
3469
|
+
persistSessionCookies(writeCookies, result.data, cookieSettings);
|
|
3470
|
+
return toSafeAuthResult(
|
|
3471
|
+
result
|
|
3472
|
+
);
|
|
3473
|
+
},
|
|
3474
|
+
exchangeOAuthCode: async (code, codeVerifier) => {
|
|
3475
|
+
const result = await createClient().auth.exchangeOAuthCode(
|
|
3476
|
+
code,
|
|
3477
|
+
codeVerifier
|
|
3478
|
+
);
|
|
3479
|
+
persistSessionCookies(writeCookies, result.data, cookieSettings);
|
|
3480
|
+
return toSafeAuthResult(
|
|
3481
|
+
result
|
|
3482
|
+
);
|
|
3483
|
+
},
|
|
3484
|
+
verifyEmail: async (request) => {
|
|
3485
|
+
const result = await createClient().auth.verifyEmail(request);
|
|
3486
|
+
persistSessionCookies(writeCookies, result.data, cookieSettings);
|
|
3487
|
+
return toSafeAuthResult(result);
|
|
3488
|
+
},
|
|
3489
|
+
signOut: async () => {
|
|
3490
|
+
const result = await createClient().auth.signOut();
|
|
3491
|
+
clearAuthCookies(writeCookies, cookieSettings);
|
|
3492
|
+
return result;
|
|
3493
|
+
}
|
|
3494
|
+
};
|
|
3495
|
+
}
|
|
3496
|
+
|
|
3280
3497
|
// src/ssr/update-session.ts
|
|
3281
3498
|
async function updateSession(options) {
|
|
3282
3499
|
const accessCookieName = getAccessTokenCookieName(options.names);
|
|
@@ -3337,6 +3554,7 @@ export {
|
|
|
3337
3554
|
DEFAULT_REFRESH_TOKEN_COOKIE,
|
|
3338
3555
|
accessTokenCookieOptions,
|
|
3339
3556
|
clearAuthCookies,
|
|
3557
|
+
createAuthActions,
|
|
3340
3558
|
createBrowserClient,
|
|
3341
3559
|
createRefreshAuthRouter,
|
|
3342
3560
|
createServerClient,
|