@kaiz11/stack-client 0.0.14
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/LICENSE +32 -0
- package/README.md +586 -0
- package/dist/accounts/accounts-client.d.ts +188 -0
- package/dist/accounts/accounts-client.d.ts.map +1 -0
- package/dist/accounts/accounts-client.js +264 -0
- package/dist/accounts/accounts-client.js.map +1 -0
- package/dist/accounts/index.d.ts +8 -0
- package/dist/accounts/index.d.ts.map +1 -0
- package/dist/accounts/index.js +8 -0
- package/dist/accounts/index.js.map +1 -0
- package/dist/accounts/mock-accounts.d.ts +90 -0
- package/dist/accounts/mock-accounts.d.ts.map +1 -0
- package/dist/accounts/mock-accounts.js +434 -0
- package/dist/accounts/mock-accounts.js.map +1 -0
- package/dist/accounts/types.d.ts +180 -0
- package/dist/accounts/types.d.ts.map +1 -0
- package/dist/accounts/types.js +59 -0
- package/dist/accounts/types.js.map +1 -0
- package/dist/auth/auth-client.d.ts +224 -0
- package/dist/auth/auth-client.d.ts.map +1 -0
- package/dist/auth/auth-client.js +230 -0
- package/dist/auth/auth-client.js.map +1 -0
- package/dist/auth/base-auth.d.ts +44 -0
- package/dist/auth/base-auth.d.ts.map +1 -0
- package/dist/auth/base-auth.js +55 -0
- package/dist/auth/base-auth.js.map +1 -0
- package/dist/auth/index.d.ts +11 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +11 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/methods/admin.d.ts +59 -0
- package/dist/auth/methods/admin.d.ts.map +1 -0
- package/dist/auth/methods/admin.js +55 -0
- package/dist/auth/methods/admin.js.map +1 -0
- package/dist/auth/methods/index.d.ts +9 -0
- package/dist/auth/methods/index.d.ts.map +1 -0
- package/dist/auth/methods/index.js +8 -0
- package/dist/auth/methods/index.js.map +1 -0
- package/dist/auth/methods/magic-link.d.ts +27 -0
- package/dist/auth/methods/magic-link.d.ts.map +1 -0
- package/dist/auth/methods/magic-link.js +37 -0
- package/dist/auth/methods/magic-link.js.map +1 -0
- package/dist/auth/methods/mfa.d.ts +92 -0
- package/dist/auth/methods/mfa.d.ts.map +1 -0
- package/dist/auth/methods/mfa.js +153 -0
- package/dist/auth/methods/mfa.js.map +1 -0
- package/dist/auth/methods/oauth.d.ts +62 -0
- package/dist/auth/methods/oauth.d.ts.map +1 -0
- package/dist/auth/methods/oauth.js +165 -0
- package/dist/auth/methods/oauth.js.map +1 -0
- package/dist/auth/methods/otp.d.ts +43 -0
- package/dist/auth/methods/otp.d.ts.map +1 -0
- package/dist/auth/methods/otp.js +66 -0
- package/dist/auth/methods/otp.js.map +1 -0
- package/dist/auth/methods/password.d.ts +64 -0
- package/dist/auth/methods/password.d.ts.map +1 -0
- package/dist/auth/methods/password.js +116 -0
- package/dist/auth/methods/password.js.map +1 -0
- package/dist/auth/methods/recovery.d.ts +62 -0
- package/dist/auth/methods/recovery.d.ts.map +1 -0
- package/dist/auth/methods/recovery.js +100 -0
- package/dist/auth/methods/recovery.js.map +1 -0
- package/dist/auth/mock-auth.d.ts +135 -0
- package/dist/auth/mock-auth.d.ts.map +1 -0
- package/dist/auth/mock-auth.js +417 -0
- package/dist/auth/mock-auth.js.map +1 -0
- package/dist/auth/server/helpers.d.ts +215 -0
- package/dist/auth/server/helpers.d.ts.map +1 -0
- package/dist/auth/server/helpers.js +241 -0
- package/dist/auth/server/helpers.js.map +1 -0
- package/dist/auth/server/index.d.ts +24 -0
- package/dist/auth/server/index.d.ts.map +1 -0
- package/dist/auth/server/index.js +40 -0
- package/dist/auth/server/index.js.map +1 -0
- package/dist/auth/server/middleware.d.ts +305 -0
- package/dist/auth/server/middleware.d.ts.map +1 -0
- package/dist/auth/server/middleware.js +405 -0
- package/dist/auth/server/middleware.js.map +1 -0
- package/dist/auth/server/verify.d.ts +184 -0
- package/dist/auth/server/verify.d.ts.map +1 -0
- package/dist/auth/server/verify.js +222 -0
- package/dist/auth/server/verify.js.map +1 -0
- package/dist/auth/token-manager.d.ts +94 -0
- package/dist/auth/token-manager.d.ts.map +1 -0
- package/dist/auth/token-manager.js +231 -0
- package/dist/auth/token-manager.js.map +1 -0
- package/dist/auth/types.d.ts +412 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +66 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/auth/user/identities.d.ts +62 -0
- package/dist/auth/user/identities.d.ts.map +1 -0
- package/dist/auth/user/identities.js +88 -0
- package/dist/auth/user/identities.js.map +1 -0
- package/dist/auth/user/index.d.ts +4 -0
- package/dist/auth/user/index.d.ts.map +1 -0
- package/dist/auth/user/index.js +4 -0
- package/dist/auth/user/index.js.map +1 -0
- package/dist/auth/user/user.d.ts +64 -0
- package/dist/auth/user/user.d.ts.map +1 -0
- package/dist/auth/user/user.js +105 -0
- package/dist/auth/user/user.js.map +1 -0
- package/dist/auth/user/verification.d.ts +49 -0
- package/dist/auth/user/verification.d.ts.map +1 -0
- package/dist/auth/user/verification.js +71 -0
- package/dist/auth/user/verification.js.map +1 -0
- package/dist/cli/browser.d.ts +11 -0
- package/dist/cli/browser.d.ts.map +1 -0
- package/dist/cli/browser.js +35 -0
- package/dist/cli/browser.js.map +1 -0
- package/dist/cli/callback-server.d.ts +30 -0
- package/dist/cli/callback-server.d.ts.map +1 -0
- package/dist/cli/callback-server.js +100 -0
- package/dist/cli/callback-server.js.map +1 -0
- package/dist/cli/file-token-store.d.ts +79 -0
- package/dist/cli/file-token-store.d.ts.map +1 -0
- package/dist/cli/file-token-store.js +138 -0
- package/dist/cli/file-token-store.js.map +1 -0
- package/dist/cli/index.d.ts +33 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +38 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/oauth.d.ts +67 -0
- package/dist/cli/oauth.d.ts.map +1 -0
- package/dist/cli/oauth.js +101 -0
- package/dist/cli/oauth.js.map +1 -0
- package/dist/cli/pkce.d.ts +35 -0
- package/dist/cli/pkce.d.ts.map +1 -0
- package/dist/cli/pkce.js +43 -0
- package/dist/cli/pkce.js.map +1 -0
- package/dist/client.d.ts +22 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +99 -0
- package/dist/client.js.map +1 -0
- package/dist/db/client.d.ts +9 -0
- package/dist/db/client.d.ts.map +1 -0
- package/dist/db/client.js +19 -0
- package/dist/db/client.js.map +1 -0
- package/dist/db/errors.d.ts +19 -0
- package/dist/db/errors.d.ts.map +1 -0
- package/dist/db/errors.js +57 -0
- package/dist/db/errors.js.map +1 -0
- package/dist/db/index.d.ts +7 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +5 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/mock.d.ts +28 -0
- package/dist/db/mock.d.ts.map +1 -0
- package/dist/db/mock.js +459 -0
- package/dist/db/mock.js.map +1 -0
- package/dist/db/types.d.ts +73 -0
- package/dist/db/types.d.ts.map +1 -0
- package/dist/db/types.js +2 -0
- package/dist/db/types.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/errors.d.ts +33 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +76 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/http.d.ts +81 -0
- package/dist/lib/http.d.ts.map +1 -0
- package/dist/lib/http.js +163 -0
- package/dist/lib/http.js.map +1 -0
- package/dist/lib/keys.d.ts +87 -0
- package/dist/lib/keys.d.ts.map +1 -0
- package/dist/lib/keys.js +147 -0
- package/dist/lib/keys.js.map +1 -0
- package/dist/lib/paths.d.ts +37 -0
- package/dist/lib/paths.d.ts.map +1 -0
- package/dist/lib/paths.js +49 -0
- package/dist/lib/paths.js.map +1 -0
- package/dist/lib/token-store.d.ts +42 -0
- package/dist/lib/token-store.d.ts.map +1 -0
- package/dist/lib/token-store.js +75 -0
- package/dist/lib/token-store.js.map +1 -0
- package/dist/mocks/handlers.d.ts +29 -0
- package/dist/mocks/handlers.d.ts.map +1 -0
- package/dist/mocks/handlers.js +79 -0
- package/dist/mocks/handlers.js.map +1 -0
- package/dist/mocks/index.d.ts +5 -0
- package/dist/mocks/index.d.ts.map +1 -0
- package/dist/mocks/index.js +9 -0
- package/dist/mocks/index.js.map +1 -0
- package/dist/mocks/responses.d.ts +76 -0
- package/dist/mocks/responses.d.ts.map +1 -0
- package/dist/mocks/responses.js +91 -0
- package/dist/mocks/responses.js.map +1 -0
- package/dist/mocks/server.d.ts +7 -0
- package/dist/mocks/server.d.ts.map +1 -0
- package/dist/mocks/server.js +9 -0
- package/dist/mocks/server.js.map +1 -0
- package/dist/mocks/state.d.ts +86 -0
- package/dist/mocks/state.d.ts.map +1 -0
- package/dist/mocks/state.js +77 -0
- package/dist/mocks/state.js.map +1 -0
- package/dist/storage/bucket-ref.d.ts +183 -0
- package/dist/storage/bucket-ref.d.ts.map +1 -0
- package/dist/storage/bucket-ref.js +529 -0
- package/dist/storage/bucket-ref.js.map +1 -0
- package/dist/storage/errors.d.ts +27 -0
- package/dist/storage/errors.d.ts.map +1 -0
- package/dist/storage/errors.js +89 -0
- package/dist/storage/errors.js.map +1 -0
- package/dist/storage/index.d.ts +13 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +11 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/interface.d.ts +245 -0
- package/dist/storage/interface.d.ts.map +1 -0
- package/dist/storage/interface.js +2 -0
- package/dist/storage/interface.js.map +1 -0
- package/dist/storage/mock-storage.d.ts +67 -0
- package/dist/storage/mock-storage.d.ts.map +1 -0
- package/dist/storage/mock-storage.js +478 -0
- package/dist/storage/mock-storage.js.map +1 -0
- package/dist/storage/policies-client.d.ts +77 -0
- package/dist/storage/policies-client.d.ts.map +1 -0
- package/dist/storage/policies-client.js +115 -0
- package/dist/storage/policies-client.js.map +1 -0
- package/dist/storage/policy-templates.d.ts +6 -0
- package/dist/storage/policy-templates.d.ts.map +1 -0
- package/dist/storage/policy-templates.js +290 -0
- package/dist/storage/policy-templates.js.map +1 -0
- package/dist/storage/policy-types.d.ts +98 -0
- package/dist/storage/policy-types.d.ts.map +1 -0
- package/dist/storage/policy-types.js +20 -0
- package/dist/storage/policy-types.js.map +1 -0
- package/dist/storage/storage-client.d.ts +32 -0
- package/dist/storage/storage-client.d.ts.map +1 -0
- package/dist/storage/storage-client.js +94 -0
- package/dist/storage/storage-client.js.map +1 -0
- package/dist/storage/tus-upload.d.ts +56 -0
- package/dist/storage/tus-upload.d.ts.map +1 -0
- package/dist/storage/tus-upload.js +236 -0
- package/dist/storage/tus-upload.js.map +1 -0
- package/dist/storage/types.d.ts +335 -0
- package/dist/storage/types.d.ts.map +1 -0
- package/dist/storage/types.js +39 -0
- package/dist/storage/types.js.map +1 -0
- package/dist/test/auth/helpers.d.ts +33 -0
- package/dist/test/auth/helpers.d.ts.map +1 -0
- package/dist/test/auth/helpers.js +80 -0
- package/dist/test/auth/helpers.js.map +1 -0
- package/dist/test/helpers/jwt.d.ts +61 -0
- package/dist/test/helpers/jwt.d.ts.map +1 -0
- package/dist/test/helpers/jwt.js +132 -0
- package/dist/test/helpers/jwt.js.map +1 -0
- package/dist/test/helpers/mailpit.d.ts +61 -0
- package/dist/test/helpers/mailpit.d.ts.map +1 -0
- package/dist/test/helpers/mailpit.js +107 -0
- package/dist/test/helpers/mailpit.js.map +1 -0
- package/dist/test/setup.d.ts +2 -0
- package/dist/test/setup.d.ts.map +1 -0
- package/dist/test/setup.js +17 -0
- package/dist/test/setup.js.map +1 -0
- package/dist/types.d.ts +96 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +78 -0
package/dist/lib/keys.js
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { PLATFORM_TENANT_ID } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Error thrown when fetching the anon key fails
|
|
4
|
+
*/
|
|
5
|
+
export class AnonKeyError extends Error {
|
|
6
|
+
statusCode;
|
|
7
|
+
constructor(message, statusCode) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.statusCode = statusCode;
|
|
10
|
+
this.name = "AnonKeyError";
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Build the public key URL for a tenant
|
|
15
|
+
*
|
|
16
|
+
* @param baseUrl - Base URL of the stack (e.g., "https://stack.zenku.app")
|
|
17
|
+
* @param tenantId - Tenant identifier (default: "_platform")
|
|
18
|
+
* @returns The full URL to fetch the public key
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* const url = buildPublicKeyUrl("https://stack.zenku.app", "acme");
|
|
23
|
+
* // => "https://stack.zenku.app/tenants/acme/public_key"
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export function buildPublicKeyUrl(baseUrl, tenantId = PLATFORM_TENANT_ID) {
|
|
27
|
+
const base = baseUrl.replace(/\/$/, "");
|
|
28
|
+
return `${base}/tenants/${tenantId}/public_key`;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Fetch the anon key for a tenant
|
|
32
|
+
*
|
|
33
|
+
* The anon key is a pre-signed JWT with `role = "anon"` that can be used
|
|
34
|
+
* for unauthenticated requests. It's designed to be public - security
|
|
35
|
+
* comes from RLS policies, not from the key being secret.
|
|
36
|
+
*
|
|
37
|
+
* The response is cached by the server (Cache-Control: public, max-age=3600).
|
|
38
|
+
*
|
|
39
|
+
* @param baseUrl - Base URL of the stack (e.g., "https://stack.zenku.app")
|
|
40
|
+
* @param tenantId - Tenant identifier (default: "_platform")
|
|
41
|
+
* @returns The anon key (JWT string)
|
|
42
|
+
* @throws AnonKeyError if the fetch fails
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```typescript
|
|
46
|
+
* import { fetchAnonKey } from "@kaiz11/stack-client";
|
|
47
|
+
*
|
|
48
|
+
* // Fetch anon key for a tenant
|
|
49
|
+
* const anonKey = await fetchAnonKey("https://stack.zenku.app", "acme");
|
|
50
|
+
*
|
|
51
|
+
* // Use it for unauthenticated requests
|
|
52
|
+
* const response = await fetch("https://stack.zenku.app/rest/acme/items", {
|
|
53
|
+
* headers: { Authorization: `Bearer ${anonKey}` },
|
|
54
|
+
* });
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export async function fetchAnonKey(baseUrl, tenantId = PLATFORM_TENANT_ID) {
|
|
58
|
+
const url = buildPublicKeyUrl(baseUrl, tenantId);
|
|
59
|
+
const response = await fetch(url);
|
|
60
|
+
if (!response.ok) {
|
|
61
|
+
if (response.status === 404) {
|
|
62
|
+
throw new AnonKeyError(`Tenant "${tenantId}" not found`, 404);
|
|
63
|
+
}
|
|
64
|
+
throw new AnonKeyError(`Failed to fetch anon key: ${response.status} ${response.statusText}`, response.status);
|
|
65
|
+
}
|
|
66
|
+
const key = await response.text();
|
|
67
|
+
if (!key || !key.startsWith("eyJ")) {
|
|
68
|
+
throw new AnonKeyError("Invalid anon key format");
|
|
69
|
+
}
|
|
70
|
+
return key;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Anon key cache for avoiding repeated fetches
|
|
74
|
+
*/
|
|
75
|
+
const anonKeyCache = new Map();
|
|
76
|
+
/**
|
|
77
|
+
* Default cache TTL (1 hour, matching server Cache-Control)
|
|
78
|
+
*/
|
|
79
|
+
const DEFAULT_CACHE_TTL = 3600 * 1000;
|
|
80
|
+
/**
|
|
81
|
+
* Fetch the anon key with caching
|
|
82
|
+
*
|
|
83
|
+
* Same as `fetchAnonKey` but caches the result in memory to avoid
|
|
84
|
+
* repeated network requests. The cache respects the server's
|
|
85
|
+
* Cache-Control header (1 hour).
|
|
86
|
+
*
|
|
87
|
+
* @param baseUrl - Base URL of the stack
|
|
88
|
+
* @param tenantId - Tenant identifier (default: "_platform")
|
|
89
|
+
* @param options - Cache options
|
|
90
|
+
* @returns The anon key (JWT string)
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```typescript
|
|
94
|
+
* // First call fetches from network
|
|
95
|
+
* const key1 = await fetchAnonKeyCached("https://stack.zenku.app", "acme");
|
|
96
|
+
*
|
|
97
|
+
* // Second call returns cached value
|
|
98
|
+
* const key2 = await fetchAnonKeyCached("https://stack.zenku.app", "acme");
|
|
99
|
+
*
|
|
100
|
+
* // Force refresh
|
|
101
|
+
* const key3 = await fetchAnonKeyCached("https://stack.zenku.app", "acme", {
|
|
102
|
+
* forceRefresh: true,
|
|
103
|
+
* });
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
export async function fetchAnonKeyCached(baseUrl, tenantId = PLATFORM_TENANT_ID, options) {
|
|
107
|
+
const cacheKey = `${baseUrl}:${tenantId}`;
|
|
108
|
+
const now = Date.now();
|
|
109
|
+
const ttl = options?.ttl ?? DEFAULT_CACHE_TTL;
|
|
110
|
+
// Check cache unless force refresh
|
|
111
|
+
if (!options?.forceRefresh) {
|
|
112
|
+
const cached = anonKeyCache.get(cacheKey);
|
|
113
|
+
if (cached && cached.expiresAt > now) {
|
|
114
|
+
return cached.key;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Fetch fresh key
|
|
118
|
+
const key = await fetchAnonKey(baseUrl, tenantId);
|
|
119
|
+
// Cache it
|
|
120
|
+
anonKeyCache.set(cacheKey, {
|
|
121
|
+
key,
|
|
122
|
+
expiresAt: now + ttl,
|
|
123
|
+
});
|
|
124
|
+
return key;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Clear the anon key cache
|
|
128
|
+
*
|
|
129
|
+
* @param baseUrl - If provided, only clear cache for this base URL
|
|
130
|
+
* @param tenantId - If provided with baseUrl, only clear cache for this tenant
|
|
131
|
+
*/
|
|
132
|
+
export function clearAnonKeyCache(baseUrl, tenantId) {
|
|
133
|
+
if (baseUrl && tenantId) {
|
|
134
|
+
anonKeyCache.delete(`${baseUrl}:${tenantId}`);
|
|
135
|
+
}
|
|
136
|
+
else if (baseUrl) {
|
|
137
|
+
for (const key of anonKeyCache.keys()) {
|
|
138
|
+
if (key.startsWith(`${baseUrl}:`)) {
|
|
139
|
+
anonKeyCache.delete(key);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
anonKeyCache.clear();
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/lib/keys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD;;GAEG;AACH,MAAM,OAAO,YAAa,SAAQ,KAAK;IAGnB;IAFlB,YACE,OAAe,EACC,UAAmB;QAEnC,KAAK,CAAC,OAAO,CAAC,CAAC;QAFC,eAAU,GAAV,UAAU,CAAS;QAGnC,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,iBAAiB,CAC/B,OAAe,EACf,WAAmB,kBAAkB;IAErC,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACxC,OAAO,GAAG,IAAI,YAAY,QAAQ,aAAa,CAAC;AAClD,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAe,EACf,WAAmB,kBAAkB;IAErC,MAAM,GAAG,GAAG,iBAAiB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAEjD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IAElC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,MAAM,IAAI,YAAY,CAAC,WAAW,QAAQ,aAAa,EAAE,GAAG,CAAC,CAAC;QAChE,CAAC;QACD,MAAM,IAAI,YAAY,CACpB,6BAA6B,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,EACrE,QAAQ,CAAC,MAAM,CAChB,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAElC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,YAAY,CAAC,yBAAyB,CAAC,CAAC;IACpD,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;GAEG;AACH,MAAM,YAAY,GAAG,IAAI,GAAG,EAA8C,CAAC;AAE3E;;GAEG;AACH,MAAM,iBAAiB,GAAG,IAAI,GAAG,IAAI,CAAC;AAEtC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAe,EACf,WAAmB,kBAAkB,EACrC,OAAkD;IAElD,MAAM,QAAQ,GAAG,GAAG,OAAO,IAAI,QAAQ,EAAE,CAAC;IAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,GAAG,GAAG,OAAO,EAAE,GAAG,IAAI,iBAAiB,CAAC;IAE9C,mCAAmC;IACnC,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC1C,IAAI,MAAM,IAAI,MAAM,CAAC,SAAS,GAAG,GAAG,EAAE,CAAC;YACrC,OAAO,MAAM,CAAC,GAAG,CAAC;QACpB,CAAC;IACH,CAAC;IAED,kBAAkB;IAClB,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAElD,WAAW;IACX,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE;QACzB,GAAG;QACH,SAAS,EAAE,GAAG,GAAG,GAAG;KACrB,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAgB,EAAE,QAAiB;IACnE,IAAI,OAAO,IAAI,QAAQ,EAAE,CAAC;QACxB,YAAY,CAAC,MAAM,CAAC,GAAG,OAAO,IAAI,QAAQ,EAAE,CAAC,CAAC;IAChD,CAAC;SAAM,IAAI,OAAO,EAAE,CAAC;QACnB,KAAK,MAAM,GAAG,IAAI,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC;YACtC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,OAAO,GAAG,CAAC,EAAE,CAAC;gBAClC,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;IACH,CAAC;SAAM,CAAC;QACN,YAAY,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build auth endpoint path
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* authPath("_platform", "/token") → "/auth/_platform/token"
|
|
6
|
+
* authPath("acme", "/token") → "/auth/acme/token"
|
|
7
|
+
*/
|
|
8
|
+
export declare function authPath(tenantId: string, path: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Build REST (PostgREST) endpoint path
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* restPath("_platform", "/basejump/accounts") → "/rest/_platform/basejump/accounts"
|
|
14
|
+
* restPath("acme", "/todos") → "/rest/acme/todos"
|
|
15
|
+
*/
|
|
16
|
+
export declare function restPath(tenantId: string, path: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Build storage endpoint path
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* storagePath("acme", "/v1/object/public/avatars/user.png")
|
|
22
|
+
* → "/storage/acme/v1/object/public/avatars/user.png"
|
|
23
|
+
* storagePath("_platform", "/v1/bucket") → "/storage/_platform/v1/bucket"
|
|
24
|
+
*/
|
|
25
|
+
export declare function storagePath(tenantId: string, path: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* Build realtime endpoint path
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* realtimePath("/websocket") → "/realtime/v1/websocket"
|
|
31
|
+
*/
|
|
32
|
+
export declare function realtimePath(path: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* Check if tenant ID is the platform
|
|
35
|
+
*/
|
|
36
|
+
export declare function isPlatform(tenantId: string): boolean;
|
|
37
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/lib/paths.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAElE;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGjD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEpD"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { PLATFORM_TENANT_ID } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Build auth endpoint path
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* authPath("_platform", "/token") → "/auth/_platform/token"
|
|
7
|
+
* authPath("acme", "/token") → "/auth/acme/token"
|
|
8
|
+
*/
|
|
9
|
+
export function authPath(tenantId, path) {
|
|
10
|
+
return `/auth/${tenantId}${path}`;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Build REST (PostgREST) endpoint path
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* restPath("_platform", "/basejump/accounts") → "/rest/_platform/basejump/accounts"
|
|
17
|
+
* restPath("acme", "/todos") → "/rest/acme/todos"
|
|
18
|
+
*/
|
|
19
|
+
export function restPath(tenantId, path) {
|
|
20
|
+
return `/rest/${tenantId}${path}`;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Build storage endpoint path
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* storagePath("acme", "/v1/object/public/avatars/user.png")
|
|
27
|
+
* → "/storage/acme/v1/object/public/avatars/user.png"
|
|
28
|
+
* storagePath("_platform", "/v1/bucket") → "/storage/_platform/v1/bucket"
|
|
29
|
+
*/
|
|
30
|
+
export function storagePath(tenantId, path) {
|
|
31
|
+
return `/storage/${tenantId}${path}`;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Build realtime endpoint path
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* realtimePath("/websocket") → "/realtime/v1/websocket"
|
|
38
|
+
*/
|
|
39
|
+
export function realtimePath(path) {
|
|
40
|
+
// Realtime uses the same path for all tenants, tenant is identified by JWT
|
|
41
|
+
return `/realtime/v1${path}`;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Check if tenant ID is the platform
|
|
45
|
+
*/
|
|
46
|
+
export function isPlatform(tenantId) {
|
|
47
|
+
return tenantId === PLATFORM_TENANT_ID;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/lib/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD;;;;;;GAMG;AACH,MAAM,UAAU,QAAQ,CAAC,QAAgB,EAAE,IAAY;IACrD,OAAO,SAAS,QAAQ,GAAG,IAAI,EAAE,CAAC;AACpC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,QAAQ,CAAC,QAAgB,EAAE,IAAY;IACrD,OAAO,SAAS,QAAQ,GAAG,IAAI,EAAE,CAAC;AACpC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,QAAgB,EAAE,IAAY;IACxD,OAAO,YAAY,QAAQ,GAAG,IAAI,EAAE,CAAC;AACvC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,2EAA2E;IAC3E,OAAO,eAAe,IAAI,EAAE,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,OAAO,QAAQ,KAAK,kBAAkB,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token storage interface
|
|
3
|
+
*/
|
|
4
|
+
export interface TokenStore {
|
|
5
|
+
getAccessToken(): string | null;
|
|
6
|
+
getRefreshToken(): string | null;
|
|
7
|
+
setTokens(accessToken: string, refreshToken: string): void;
|
|
8
|
+
clearTokens(): void;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* In-memory token storage (for SSR, Workers, testing)
|
|
12
|
+
*/
|
|
13
|
+
export declare class MemoryTokenStore implements TokenStore {
|
|
14
|
+
private accessToken;
|
|
15
|
+
private refreshToken;
|
|
16
|
+
getAccessToken(): string | null;
|
|
17
|
+
getRefreshToken(): string | null;
|
|
18
|
+
setTokens(accessToken: string, refreshToken: string): void;
|
|
19
|
+
clearTokens(): void;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* LocalStorage token storage (for browser)
|
|
23
|
+
*/
|
|
24
|
+
export declare class LocalStorageTokenStore implements TokenStore {
|
|
25
|
+
private prefix;
|
|
26
|
+
constructor(prefix?: string);
|
|
27
|
+
private get accessKey();
|
|
28
|
+
private get refreshKey();
|
|
29
|
+
getAccessToken(): string | null;
|
|
30
|
+
getRefreshToken(): string | null;
|
|
31
|
+
setTokens(accessToken: string, refreshToken: string): void;
|
|
32
|
+
clearTokens(): void;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Token store type for configuration
|
|
36
|
+
*/
|
|
37
|
+
export type TokenStoreType = "memory" | "localStorage" | TokenStore;
|
|
38
|
+
/**
|
|
39
|
+
* Create a token store from configuration
|
|
40
|
+
*/
|
|
41
|
+
export declare function createTokenStore(type: TokenStoreType, prefix?: string): TokenStore;
|
|
42
|
+
//# sourceMappingURL=token-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-store.d.ts","sourceRoot":"","sources":["../../src/lib/token-store.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,cAAc,IAAI,MAAM,GAAG,IAAI,CAAC;IAChC,eAAe,IAAI,MAAM,GAAG,IAAI,CAAC;IACjC,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3D,WAAW,IAAI,IAAI,CAAC;CACrB;AAED;;GAEG;AACH,qBAAa,gBAAiB,YAAW,UAAU;IACjD,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,YAAY,CAAuB;IAE3C,cAAc,IAAI,MAAM,GAAG,IAAI;IAI/B,eAAe,IAAI,MAAM,GAAG,IAAI;IAIhC,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI;IAK1D,WAAW,IAAI,IAAI;CAIpB;AAED;;GAEG;AACH,qBAAa,sBAAuB,YAAW,UAAU;IAC3C,OAAO,CAAC,MAAM;gBAAN,MAAM,GAAE,MAAgB;IAE5C,OAAO,KAAK,SAAS,GAEpB;IAED,OAAO,KAAK,UAAU,GAErB;IAED,cAAc,IAAI,MAAM,GAAG,IAAI;IAK/B,eAAe,IAAI,MAAM,GAAG,IAAI;IAKhC,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI;IAM1D,WAAW,IAAI,IAAI;CAKpB;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,cAAc,GAAG,UAAU,CAAC;AAEpE;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,cAAc,EACpB,MAAM,CAAC,EAAE,MAAM,GACd,UAAU,CAaZ"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory token storage (for SSR, Workers, testing)
|
|
3
|
+
*/
|
|
4
|
+
export class MemoryTokenStore {
|
|
5
|
+
accessToken = null;
|
|
6
|
+
refreshToken = null;
|
|
7
|
+
getAccessToken() {
|
|
8
|
+
return this.accessToken;
|
|
9
|
+
}
|
|
10
|
+
getRefreshToken() {
|
|
11
|
+
return this.refreshToken;
|
|
12
|
+
}
|
|
13
|
+
setTokens(accessToken, refreshToken) {
|
|
14
|
+
this.accessToken = accessToken;
|
|
15
|
+
this.refreshToken = refreshToken;
|
|
16
|
+
}
|
|
17
|
+
clearTokens() {
|
|
18
|
+
this.accessToken = null;
|
|
19
|
+
this.refreshToken = null;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* LocalStorage token storage (for browser)
|
|
24
|
+
*/
|
|
25
|
+
export class LocalStorageTokenStore {
|
|
26
|
+
prefix;
|
|
27
|
+
constructor(prefix = "stack") {
|
|
28
|
+
this.prefix = prefix;
|
|
29
|
+
}
|
|
30
|
+
get accessKey() {
|
|
31
|
+
return `${this.prefix}_access_token`;
|
|
32
|
+
}
|
|
33
|
+
get refreshKey() {
|
|
34
|
+
return `${this.prefix}_refresh_token`;
|
|
35
|
+
}
|
|
36
|
+
getAccessToken() {
|
|
37
|
+
if (typeof localStorage === "undefined")
|
|
38
|
+
return null;
|
|
39
|
+
return localStorage.getItem(this.accessKey);
|
|
40
|
+
}
|
|
41
|
+
getRefreshToken() {
|
|
42
|
+
if (typeof localStorage === "undefined")
|
|
43
|
+
return null;
|
|
44
|
+
return localStorage.getItem(this.refreshKey);
|
|
45
|
+
}
|
|
46
|
+
setTokens(accessToken, refreshToken) {
|
|
47
|
+
if (typeof localStorage === "undefined")
|
|
48
|
+
return;
|
|
49
|
+
localStorage.setItem(this.accessKey, accessToken);
|
|
50
|
+
localStorage.setItem(this.refreshKey, refreshToken);
|
|
51
|
+
}
|
|
52
|
+
clearTokens() {
|
|
53
|
+
if (typeof localStorage === "undefined")
|
|
54
|
+
return;
|
|
55
|
+
localStorage.removeItem(this.accessKey);
|
|
56
|
+
localStorage.removeItem(this.refreshKey);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Create a token store from configuration
|
|
61
|
+
*/
|
|
62
|
+
export function createTokenStore(type, prefix) {
|
|
63
|
+
if (typeof type === "object") {
|
|
64
|
+
return type;
|
|
65
|
+
}
|
|
66
|
+
switch (type) {
|
|
67
|
+
case "memory":
|
|
68
|
+
return new MemoryTokenStore();
|
|
69
|
+
case "localStorage":
|
|
70
|
+
return new LocalStorageTokenStore(prefix);
|
|
71
|
+
default:
|
|
72
|
+
throw new Error(`Unknown token store type: ${type}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=token-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-store.js","sourceRoot":"","sources":["../../src/lib/token-store.ts"],"names":[],"mappings":"AAUA;;GAEG;AACH,MAAM,OAAO,gBAAgB;IACnB,WAAW,GAAkB,IAAI,CAAC;IAClC,YAAY,GAAkB,IAAI,CAAC;IAE3C,cAAc;QACZ,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED,eAAe;QACb,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,SAAS,CAAC,WAAmB,EAAE,YAAoB;QACjD,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACnC,CAAC;IAED,WAAW;QACT,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;IAC3B,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,sBAAsB;IACb;IAApB,YAAoB,SAAiB,OAAO;QAAxB,WAAM,GAAN,MAAM,CAAkB;IAAG,CAAC;IAEhD,IAAY,SAAS;QACnB,OAAO,GAAG,IAAI,CAAC,MAAM,eAAe,CAAC;IACvC,CAAC;IAED,IAAY,UAAU;QACpB,OAAO,GAAG,IAAI,CAAC,MAAM,gBAAgB,CAAC;IACxC,CAAC;IAED,cAAc;QACZ,IAAI,OAAO,YAAY,KAAK,WAAW;YAAE,OAAO,IAAI,CAAC;QACrD,OAAO,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC9C,CAAC;IAED,eAAe;QACb,IAAI,OAAO,YAAY,KAAK,WAAW;YAAE,OAAO,IAAI,CAAC;QACrD,OAAO,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC/C,CAAC;IAED,SAAS,CAAC,WAAmB,EAAE,YAAoB;QACjD,IAAI,OAAO,YAAY,KAAK,WAAW;YAAE,OAAO;QAChD,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QAClD,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IACtD,CAAC;IAED,WAAW;QACT,IAAI,OAAO,YAAY,KAAK,WAAW;YAAE,OAAO;QAChD,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACxC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC3C,CAAC;CACF;AAOD;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAC9B,IAAoB,EACpB,MAAe;IAEf,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ;YACX,OAAO,IAAI,gBAAgB,EAAE,CAAC;QAChC,KAAK,cAAc;YACjB,OAAO,IAAI,sBAAsB,CAAC,MAAM,CAAC,CAAC;QAC5C;YACE,MAAM,IAAI,KAAK,CAAC,6BAA6B,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for creating auth handlers
|
|
3
|
+
*/
|
|
4
|
+
export interface AuthHandlersOptions {
|
|
5
|
+
/** Base URL of the stack server */
|
|
6
|
+
baseUrl: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Create MSW handlers for GoTrue auth endpoints
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { setupServer } from "msw/node";
|
|
14
|
+
* import { createAuthHandlers } from "@kaiz11/stack-client/mocks";
|
|
15
|
+
*
|
|
16
|
+
* const handlers = createAuthHandlers({ baseUrl: "https://stack.test" });
|
|
17
|
+
* const server = setupServer(...handlers);
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare function createAuthHandlers(options: AuthHandlersOptions): import("msw").HttpHandler[];
|
|
21
|
+
/**
|
|
22
|
+
* Default handlers with standard test URL
|
|
23
|
+
*
|
|
24
|
+
* For SDK internal tests only. Developers should use createAuthHandlers
|
|
25
|
+
* with their own base URL.
|
|
26
|
+
*/
|
|
27
|
+
export declare const DEFAULT_BASE_URL = "https://stack.test";
|
|
28
|
+
export declare const handlers: import("msw").HttpHandler[];
|
|
29
|
+
//# sourceMappingURL=handlers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/mocks/handlers.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,+BAgF9D;AAED;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,uBAAuB,CAAC;AACrD,eAAO,MAAM,QAAQ,6BAAoD,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { http, HttpResponse } from "msw";
|
|
2
|
+
import { createTokenResponse, errors } from "./responses.js";
|
|
3
|
+
import { mockState, requestCounts, delay } from "./state.js";
|
|
4
|
+
/**
|
|
5
|
+
* Create MSW handlers for GoTrue auth endpoints
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { setupServer } from "msw/node";
|
|
10
|
+
* import { createAuthHandlers } from "@kaiz11/stack-client/mocks";
|
|
11
|
+
*
|
|
12
|
+
* const handlers = createAuthHandlers({ baseUrl: "https://stack.test" });
|
|
13
|
+
* const server = setupServer(...handlers);
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export function createAuthHandlers(options) {
|
|
17
|
+
const { baseUrl } = options;
|
|
18
|
+
return [
|
|
19
|
+
// Sign in (password grant) and token refresh
|
|
20
|
+
http.post(`${baseUrl}/auth/:target/token`, async ({ request }) => {
|
|
21
|
+
await delay(mockState.latency);
|
|
22
|
+
const url = new URL(request.url);
|
|
23
|
+
const grantType = url.searchParams.get("grant_type");
|
|
24
|
+
if (grantType === "password") {
|
|
25
|
+
requestCounts.signIn++;
|
|
26
|
+
if (mockState.shouldFailSignIn) {
|
|
27
|
+
return HttpResponse.json(mockState.signInError, { status: 401 });
|
|
28
|
+
}
|
|
29
|
+
const body = (await request.json());
|
|
30
|
+
return HttpResponse.json(createTokenResponse({ email: body.email }));
|
|
31
|
+
}
|
|
32
|
+
if (grantType === "refresh_token") {
|
|
33
|
+
requestCounts.refresh++;
|
|
34
|
+
if (mockState.shouldFailRefresh) {
|
|
35
|
+
return HttpResponse.json(mockState.refreshError, { status: 401 });
|
|
36
|
+
}
|
|
37
|
+
// Generate new tokens (simulating rotation)
|
|
38
|
+
return HttpResponse.json(createTokenResponse({
|
|
39
|
+
email: "user@example.com",
|
|
40
|
+
refreshToken: `new-refresh-${Date.now()}`,
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
43
|
+
return HttpResponse.json(errors.unsupportedGrantType, { status: 400 });
|
|
44
|
+
}),
|
|
45
|
+
// Sign up
|
|
46
|
+
http.post(`${baseUrl}/auth/:target/signup`, async ({ request }) => {
|
|
47
|
+
await delay(mockState.latency);
|
|
48
|
+
requestCounts.signUp++;
|
|
49
|
+
if (mockState.shouldFailSignUp) {
|
|
50
|
+
return HttpResponse.json(mockState.signUpError, { status: 422 });
|
|
51
|
+
}
|
|
52
|
+
const body = (await request.json());
|
|
53
|
+
return HttpResponse.json(createTokenResponse({
|
|
54
|
+
email: body.email,
|
|
55
|
+
userMetadata: body.data,
|
|
56
|
+
}));
|
|
57
|
+
}),
|
|
58
|
+
// Sign out
|
|
59
|
+
http.post(`${baseUrl}/auth/:target/logout`, async ({ request }) => {
|
|
60
|
+
await delay(mockState.latency);
|
|
61
|
+
requestCounts.signOut++;
|
|
62
|
+
// Check for Authorization header
|
|
63
|
+
const authHeader = request.headers.get("Authorization");
|
|
64
|
+
if (!authHeader) {
|
|
65
|
+
return HttpResponse.json(errors.unauthorized, { status: 401 });
|
|
66
|
+
}
|
|
67
|
+
return new HttpResponse(null, { status: 204 });
|
|
68
|
+
}),
|
|
69
|
+
];
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Default handlers with standard test URL
|
|
73
|
+
*
|
|
74
|
+
* For SDK internal tests only. Developers should use createAuthHandlers
|
|
75
|
+
* with their own base URL.
|
|
76
|
+
*/
|
|
77
|
+
export const DEFAULT_BASE_URL = "https://stack.test";
|
|
78
|
+
export const handlers = createAuthHandlers({ baseUrl: DEFAULT_BASE_URL });
|
|
79
|
+
//# sourceMappingURL=handlers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../src/mocks/handlers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { generateTestJwt, generateUserId, createTokenResponse, errors, type TestJwtOptions, type TokenResponseOptions, type MockErrorResponse, } from "./responses.js";
|
|
2
|
+
export { mockState, requestCounts, delay, type MockState, type MockOptions, type RequestCounts, } from "./state.js";
|
|
3
|
+
export { createAuthHandlers, handlers, DEFAULT_BASE_URL, type AuthHandlersOptions, } from "./handlers.js";
|
|
4
|
+
export { server } from "./server.js";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mocks/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,MAAM,EACN,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,GACvB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,SAAS,EACT,aAAa,EACb,KAAK,EACL,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,aAAa,GACnB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,kBAAkB,EAClB,QAAQ,EACR,gBAAgB,EAChB,KAAK,mBAAmB,GACzB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Responses - single source of truth
|
|
2
|
+
export { generateTestJwt, generateUserId, createTokenResponse, errors, } from "./responses.js";
|
|
3
|
+
// State - mock behavior control
|
|
4
|
+
export { mockState, requestCounts, delay, } from "./state.js";
|
|
5
|
+
// MSW handlers - for SDK internal tests
|
|
6
|
+
export { createAuthHandlers, handlers, DEFAULT_BASE_URL, } from "./handlers.js";
|
|
7
|
+
// MSW server - for SDK internal tests
|
|
8
|
+
export { server } from "./server.js";
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mocks/index.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,OAAO,EACL,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,MAAM,GAIP,MAAM,gBAAgB,CAAC;AAExB,gCAAgC;AAChC,OAAO,EACL,SAAS,EACT,aAAa,EACb,KAAK,GAIN,MAAM,YAAY,CAAC;AAEpB,wCAAwC;AACxC,OAAO,EACL,kBAAkB,EAClB,QAAQ,EACR,gBAAgB,GAEjB,MAAM,eAAe,CAAC;AAEvB,sCAAsC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { GoTrueTokenResponse } from "../auth/types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Options for generating a test JWT
|
|
4
|
+
*/
|
|
5
|
+
export interface TestJwtOptions {
|
|
6
|
+
sub: string;
|
|
7
|
+
email: string;
|
|
8
|
+
exp?: number;
|
|
9
|
+
iat?: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Options for creating a token response
|
|
13
|
+
*/
|
|
14
|
+
export interface TokenResponseOptions {
|
|
15
|
+
email: string;
|
|
16
|
+
refreshToken?: string;
|
|
17
|
+
expiresIn?: number;
|
|
18
|
+
userMetadata?: Record<string, unknown>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Generate a valid JWT for testing
|
|
22
|
+
*
|
|
23
|
+
* Creates a properly structured JWT that can be decoded by the SDK.
|
|
24
|
+
* The signature is fake but the payload is valid.
|
|
25
|
+
*/
|
|
26
|
+
export declare function generateTestJwt(options: TestJwtOptions): string;
|
|
27
|
+
/**
|
|
28
|
+
* Generate a user ID from an email address
|
|
29
|
+
*/
|
|
30
|
+
export declare function generateUserId(email: string): string;
|
|
31
|
+
/**
|
|
32
|
+
* Create a GoTrue token response
|
|
33
|
+
*
|
|
34
|
+
* This is the single source of truth for mock token responses.
|
|
35
|
+
* Used by both MSW handlers (for SDK tests) and mock auth client (for developer tests).
|
|
36
|
+
*/
|
|
37
|
+
export declare function createTokenResponse(options: TokenResponseOptions): GoTrueTokenResponse;
|
|
38
|
+
/**
|
|
39
|
+
* Standard error responses (GoTrue format)
|
|
40
|
+
*/
|
|
41
|
+
export declare const errors: {
|
|
42
|
+
readonly invalidCredentials: {
|
|
43
|
+
readonly code: 401;
|
|
44
|
+
readonly error_code: "invalid_credentials";
|
|
45
|
+
readonly msg: "Invalid email or password";
|
|
46
|
+
};
|
|
47
|
+
readonly userAlreadyExists: {
|
|
48
|
+
readonly code: 422;
|
|
49
|
+
readonly error_code: "user_already_exists";
|
|
50
|
+
readonly msg: "User already registered";
|
|
51
|
+
};
|
|
52
|
+
readonly invalidRefreshToken: {
|
|
53
|
+
readonly code: 401;
|
|
54
|
+
readonly error_code: "invalid_grant";
|
|
55
|
+
readonly msg: "Invalid refresh token";
|
|
56
|
+
};
|
|
57
|
+
readonly unauthorized: {
|
|
58
|
+
readonly code: 401;
|
|
59
|
+
readonly error_code: "unauthorized";
|
|
60
|
+
readonly msg: "Missing or invalid authorization";
|
|
61
|
+
};
|
|
62
|
+
readonly unsupportedGrantType: {
|
|
63
|
+
readonly code: 400;
|
|
64
|
+
readonly error_code: "unsupported_grant_type";
|
|
65
|
+
readonly msg: "Unsupported grant type";
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Error response type (GoTrue format)
|
|
70
|
+
*/
|
|
71
|
+
export type MockErrorResponse = {
|
|
72
|
+
code: number;
|
|
73
|
+
error_code: string;
|
|
74
|
+
msg: string;
|
|
75
|
+
};
|
|
76
|
+
//# sourceMappingURL=responses.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"responses.d.ts","sourceRoot":"","sources":["../../src/mocks/responses.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAE5D;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxC;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAsB/D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,oBAAoB,GAC5B,mBAAmB,CAsBrB;AAED;;GAEG;AACH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;CA0BT,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;CACb,CAAC"}
|