@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
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JWT generation helpers for tests (ES256)
|
|
3
|
+
*
|
|
4
|
+
* Uses ES256 (ECDSA P-256) to match production GoTrue configuration.
|
|
5
|
+
*/
|
|
6
|
+
import * as jose from "jose";
|
|
7
|
+
/**
|
|
8
|
+
* Test keypair for ES256 signing
|
|
9
|
+
* Generated once and reused across tests
|
|
10
|
+
*/
|
|
11
|
+
let testKeyPair = null;
|
|
12
|
+
let testJWKS = null;
|
|
13
|
+
/**
|
|
14
|
+
* Generate or retrieve the test ES256 keypair
|
|
15
|
+
*/
|
|
16
|
+
export async function getTestKeyPair() {
|
|
17
|
+
if (!testKeyPair) {
|
|
18
|
+
const { privateKey, publicKey } = await jose.generateKeyPair("ES256");
|
|
19
|
+
testKeyPair = { privateKey, publicKey };
|
|
20
|
+
}
|
|
21
|
+
return testKeyPair;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Get the test JWKS (for createLocalJWKS)
|
|
25
|
+
*/
|
|
26
|
+
export async function getTestJWKS() {
|
|
27
|
+
if (!testJWKS) {
|
|
28
|
+
const { publicKey } = await getTestKeyPair();
|
|
29
|
+
const jwk = await jose.exportJWK(publicKey);
|
|
30
|
+
jwk.kid = "test-key-1";
|
|
31
|
+
jwk.alg = "ES256";
|
|
32
|
+
jwk.use = "sig";
|
|
33
|
+
testJWKS = { keys: [jwk] };
|
|
34
|
+
}
|
|
35
|
+
return testJWKS;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Reset test keys (for isolation between test suites if needed)
|
|
39
|
+
*/
|
|
40
|
+
export function resetTestKeys() {
|
|
41
|
+
testKeyPair = null;
|
|
42
|
+
testJWKS = null;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Generate an ES256 JWT token for testing
|
|
46
|
+
*
|
|
47
|
+
* @param role - The role (anon, authenticated, service_role)
|
|
48
|
+
* @param sub - Optional user ID for the sub claim
|
|
49
|
+
* @param options - Additional options (email, phone, aal)
|
|
50
|
+
* @returns Signed JWT token
|
|
51
|
+
*/
|
|
52
|
+
export async function generateJwt(role, sub, options) {
|
|
53
|
+
const { privateKey } = await getTestKeyPair();
|
|
54
|
+
const builder = new jose.SignJWT({
|
|
55
|
+
role,
|
|
56
|
+
...(sub && { sub }),
|
|
57
|
+
...(options?.email && { email: options.email }),
|
|
58
|
+
...(options?.phone && { phone: options.phone }),
|
|
59
|
+
...(options?.aal && { aal: options.aal }),
|
|
60
|
+
})
|
|
61
|
+
.setProtectedHeader({ alg: "ES256", kid: "test-key-1" })
|
|
62
|
+
.setIssuedAt()
|
|
63
|
+
.setExpirationTime("1h")
|
|
64
|
+
.setIssuer("supabase");
|
|
65
|
+
if (sub) {
|
|
66
|
+
builder.setSubject(sub);
|
|
67
|
+
}
|
|
68
|
+
return builder.sign(privateKey);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Generate an expired ES256 JWT for testing expiration handling
|
|
72
|
+
*/
|
|
73
|
+
export async function generateExpiredJwt(role, sub) {
|
|
74
|
+
const { privateKey } = await getTestKeyPair();
|
|
75
|
+
const builder = new jose.SignJWT({
|
|
76
|
+
role,
|
|
77
|
+
...(sub && { sub }),
|
|
78
|
+
})
|
|
79
|
+
.setProtectedHeader({ alg: "ES256", kid: "test-key-1" })
|
|
80
|
+
.setIssuedAt(Math.floor(Date.now() / 1000) - 7200) // 2 hours ago
|
|
81
|
+
.setExpirationTime("-1h") // Expired 1 hour ago
|
|
82
|
+
.setIssuer("supabase");
|
|
83
|
+
if (sub) {
|
|
84
|
+
builder.setSubject(sub);
|
|
85
|
+
}
|
|
86
|
+
return builder.sign(privateKey);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Generate a JWT with custom audience
|
|
90
|
+
*/
|
|
91
|
+
export async function generateJwtWithAudience(role, sub, audience) {
|
|
92
|
+
const { privateKey } = await getTestKeyPair();
|
|
93
|
+
return new jose.SignJWT({ role })
|
|
94
|
+
.setProtectedHeader({ alg: "ES256", kid: "test-key-1" })
|
|
95
|
+
.setSubject(sub)
|
|
96
|
+
.setIssuedAt()
|
|
97
|
+
.setExpirationTime("1h")
|
|
98
|
+
.setIssuer("supabase")
|
|
99
|
+
.setAudience(audience)
|
|
100
|
+
.sign(privateKey);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Generate a JWT missing the sub claim (for testing validation)
|
|
104
|
+
*/
|
|
105
|
+
export async function generateJwtWithoutSub(role) {
|
|
106
|
+
const { privateKey } = await getTestKeyPair();
|
|
107
|
+
return new jose.SignJWT({ role })
|
|
108
|
+
.setProtectedHeader({ alg: "ES256", kid: "test-key-1" })
|
|
109
|
+
.setIssuedAt()
|
|
110
|
+
.setExpirationTime("1h")
|
|
111
|
+
.setIssuer("supabase")
|
|
112
|
+
.sign(privateKey);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Generate an anon JWT
|
|
116
|
+
*/
|
|
117
|
+
export async function generateAnonJwt() {
|
|
118
|
+
return generateJwt("anon");
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Generate a service_role JWT (bypasses RLS)
|
|
122
|
+
*/
|
|
123
|
+
export async function generateServiceRoleJwt() {
|
|
124
|
+
return generateJwt("service_role", "service");
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Generate an authenticated JWT for a specific user
|
|
128
|
+
*/
|
|
129
|
+
export async function generateAuthenticatedJwt(userId, options) {
|
|
130
|
+
return generateJwt("authenticated", userId, options);
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=jwt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../../src/test/helpers/jwt.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAI7B;;;GAGG;AACH,IAAI,WAAW,GAAsC,IAAI,CAAC;AAC1D,IAAI,QAAQ,GAA8B,IAAI,CAAC;AAE/C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QACtE,WAAW,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;IAC1C,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,cAAc,EAAE,CAAC;QAC7C,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAC5C,GAAG,CAAC,GAAG,GAAG,YAAY,CAAC;QACvB,GAAG,CAAC,GAAG,GAAG,OAAO,CAAC;QAClB,GAAG,CAAC,GAAG,GAAG,KAAK,CAAC;QAChB,QAAQ,GAAG,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;IAC7B,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,WAAW,GAAG,IAAI,CAAC;IACnB,QAAQ,GAAG,IAAI,CAAC;AAClB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,IAAa,EACb,GAAY,EACZ,OAAmE;IAEnE,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,cAAc,EAAE,CAAC;IAE9C,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC;QAC/B,IAAI;QACJ,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,CAAC;QACnB,GAAG,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;QAC/C,GAAG,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;QAC/C,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;KAC1C,CAAC;SACC,kBAAkB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,CAAC;SACvD,WAAW,EAAE;SACb,iBAAiB,CAAC,IAAI,CAAC;SACvB,SAAS,CAAC,UAAU,CAAC,CAAC;IAEzB,IAAI,GAAG,EAAE,CAAC;QACR,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED,OAAO,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,IAAa,EACb,GAAY;IAEZ,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,cAAc,EAAE,CAAC;IAE9C,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC;QAC/B,IAAI;QACJ,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,CAAC;KACpB,CAAC;SACC,kBAAkB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,CAAC;SACvD,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,cAAc;SAChE,iBAAiB,CAAC,KAAK,CAAC,CAAC,qBAAqB;SAC9C,SAAS,CAAC,UAAU,CAAC,CAAC;IAEzB,IAAI,GAAG,EAAE,CAAC;QACR,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED,OAAO,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,IAAa,EACb,GAAW,EACX,QAAgB;IAEhB,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,cAAc,EAAE,CAAC;IAE9C,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC;SAC9B,kBAAkB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,CAAC;SACvD,UAAU,CAAC,GAAG,CAAC;SACf,WAAW,EAAE;SACb,iBAAiB,CAAC,IAAI,CAAC;SACvB,SAAS,CAAC,UAAU,CAAC;SACrB,WAAW,CAAC,QAAQ,CAAC;SACrB,IAAI,CAAC,UAAU,CAAC,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,IAAa;IACvD,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,cAAc,EAAE,CAAC;IAE9C,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC;SAC9B,kBAAkB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,CAAC;SACvD,WAAW,EAAE;SACb,iBAAiB,CAAC,IAAI,CAAC;SACvB,SAAS,CAAC,UAAU,CAAC;SACrB,IAAI,CAAC,UAAU,CAAC,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB;IAC1C,OAAO,WAAW,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;AAChD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,MAAc,EACd,OAAmE;IAEnE,OAAO,WAAW,CAAC,eAAe,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AACvD,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mailpit API client for integration tests
|
|
3
|
+
*
|
|
4
|
+
* Provides helpers to fetch and parse emails captured by Mailpit
|
|
5
|
+
* during integration testing.
|
|
6
|
+
*/
|
|
7
|
+
export interface MailpitMessage {
|
|
8
|
+
ID: string;
|
|
9
|
+
Subject: string;
|
|
10
|
+
From: {
|
|
11
|
+
Name: string;
|
|
12
|
+
Address: string;
|
|
13
|
+
};
|
|
14
|
+
To: Array<{
|
|
15
|
+
Name: string;
|
|
16
|
+
Address: string;
|
|
17
|
+
}>;
|
|
18
|
+
Text: string;
|
|
19
|
+
HTML: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Check if Mailpit is available
|
|
23
|
+
*/
|
|
24
|
+
export declare function isMailpitAvailable(): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Skip condition for tests that require Mailpit
|
|
27
|
+
*/
|
|
28
|
+
export declare const skipWithoutMailpit: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Fetch emails for a recipient from Mailpit
|
|
31
|
+
*/
|
|
32
|
+
export declare function getEmailsFor(email: string, options?: {
|
|
33
|
+
limit?: number;
|
|
34
|
+
timeout?: number;
|
|
35
|
+
}): Promise<MailpitMessage[]>;
|
|
36
|
+
/**
|
|
37
|
+
* Wait for an email to arrive for a recipient
|
|
38
|
+
*/
|
|
39
|
+
export declare function waitForEmail(email: string, options?: {
|
|
40
|
+
subject?: string;
|
|
41
|
+
timeout?: number;
|
|
42
|
+
}): Promise<MailpitMessage>;
|
|
43
|
+
/**
|
|
44
|
+
* Extract OTP code from email body
|
|
45
|
+
* Looks for patterns like "enter the code: 123456" or "code: 123456"
|
|
46
|
+
*/
|
|
47
|
+
export declare function extractOtp(email: MailpitMessage): string | null;
|
|
48
|
+
/**
|
|
49
|
+
* Extract verification token from email link
|
|
50
|
+
* Looks for token parameter in verification URLs
|
|
51
|
+
*/
|
|
52
|
+
export declare function extractToken(email: MailpitMessage): string | null;
|
|
53
|
+
/**
|
|
54
|
+
* Extract magic link URL from email
|
|
55
|
+
*/
|
|
56
|
+
export declare function extractMagicLink(email: MailpitMessage): string | null;
|
|
57
|
+
/**
|
|
58
|
+
* Delete all emails for a recipient (cleanup)
|
|
59
|
+
*/
|
|
60
|
+
export declare function deleteEmailsFor(email: string): Promise<void>;
|
|
61
|
+
//# sourceMappingURL=mailpit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mailpit.d.ts","sourceRoot":"","sources":["../../../src/test/helpers/mailpit.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,EAAE,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAWD;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,SAAe,CAAC;AAE/C;;GAEG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7C,OAAO,CAAC,cAAc,EAAE,CAAC,CA8B3B;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/C,OAAO,CAAC,cAAc,CAAC,CAqBzB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAK/D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAKjE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAOrE;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWlE"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mailpit API client for integration tests
|
|
3
|
+
*
|
|
4
|
+
* Provides helpers to fetch and parse emails captured by Mailpit
|
|
5
|
+
* during integration testing.
|
|
6
|
+
*/
|
|
7
|
+
const MAILPIT_URL = process.env.MAILPIT_URL;
|
|
8
|
+
/**
|
|
9
|
+
* Check if Mailpit is available
|
|
10
|
+
*/
|
|
11
|
+
export function isMailpitAvailable() {
|
|
12
|
+
return !!MAILPIT_URL;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Skip condition for tests that require Mailpit
|
|
16
|
+
*/
|
|
17
|
+
export const skipWithoutMailpit = !MAILPIT_URL;
|
|
18
|
+
/**
|
|
19
|
+
* Fetch emails for a recipient from Mailpit
|
|
20
|
+
*/
|
|
21
|
+
export async function getEmailsFor(email, options) {
|
|
22
|
+
if (!MAILPIT_URL) {
|
|
23
|
+
throw new Error("MAILPIT_URL not set");
|
|
24
|
+
}
|
|
25
|
+
const { limit = 10, timeout = 5000 } = options ?? {};
|
|
26
|
+
const startTime = Date.now();
|
|
27
|
+
// Poll for emails with timeout
|
|
28
|
+
while (Date.now() - startTime < timeout) {
|
|
29
|
+
const searchUrl = `${MAILPIT_URL}/api/v1/search?query=to:${encodeURIComponent(email)}&limit=${limit}`;
|
|
30
|
+
const searchRes = await fetch(searchUrl);
|
|
31
|
+
const searchData = (await searchRes.json());
|
|
32
|
+
if (searchData.messages?.length > 0) {
|
|
33
|
+
// Fetch full message content for each
|
|
34
|
+
const messages = await Promise.all(searchData.messages.map(async (msg) => {
|
|
35
|
+
const msgRes = await fetch(`${MAILPIT_URL}/api/v1/message/${msg.ID}`);
|
|
36
|
+
return msgRes.json();
|
|
37
|
+
}));
|
|
38
|
+
return messages;
|
|
39
|
+
}
|
|
40
|
+
// Wait before polling again
|
|
41
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
42
|
+
}
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Wait for an email to arrive for a recipient
|
|
47
|
+
*/
|
|
48
|
+
export async function waitForEmail(email, options) {
|
|
49
|
+
const { subject, timeout = 10000 } = options ?? {};
|
|
50
|
+
const startTime = Date.now();
|
|
51
|
+
while (Date.now() - startTime < timeout) {
|
|
52
|
+
const emails = await getEmailsFor(email, { limit: 5, timeout: 1000 });
|
|
53
|
+
const match = subject
|
|
54
|
+
? emails.find((e) => e.Subject.includes(subject))
|
|
55
|
+
: emails[0];
|
|
56
|
+
if (match) {
|
|
57
|
+
return match;
|
|
58
|
+
}
|
|
59
|
+
await new Promise((r) => setTimeout(r, 300));
|
|
60
|
+
}
|
|
61
|
+
throw new Error(`Timeout waiting for email to ${email}${subject ? ` with subject "${subject}"` : ""}`);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Extract OTP code from email body
|
|
65
|
+
* Looks for patterns like "enter the code: 123456" or "code: 123456"
|
|
66
|
+
*/
|
|
67
|
+
export function extractOtp(email) {
|
|
68
|
+
const text = email.Text || email.HTML;
|
|
69
|
+
// Match 6-digit OTP code after common patterns
|
|
70
|
+
const match = text.match(/(?:code|otp|token)[:\s]+(\d{6})/i);
|
|
71
|
+
return match?.[1] ?? null;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Extract verification token from email link
|
|
75
|
+
* Looks for token parameter in verification URLs
|
|
76
|
+
*/
|
|
77
|
+
export function extractToken(email) {
|
|
78
|
+
const text = email.Text || email.HTML;
|
|
79
|
+
// Match token parameter in URL
|
|
80
|
+
const match = text.match(/[?&]token=([a-f0-9]+)/i);
|
|
81
|
+
return match?.[1] ?? null;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Extract magic link URL from email
|
|
85
|
+
*/
|
|
86
|
+
export function extractMagicLink(email) {
|
|
87
|
+
const text = email.Text || email.HTML;
|
|
88
|
+
// Match the full verification/magic link URL
|
|
89
|
+
const match = text.match(/https?:\/\/[^\s<>"]+\/auth\/[^\s<>"]+\/verify\?[^\s<>"]+/i);
|
|
90
|
+
return match?.[0] ?? null;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Delete all emails for a recipient (cleanup)
|
|
94
|
+
*/
|
|
95
|
+
export async function deleteEmailsFor(email) {
|
|
96
|
+
if (!MAILPIT_URL)
|
|
97
|
+
return;
|
|
98
|
+
const emails = await getEmailsFor(email, { timeout: 1000 });
|
|
99
|
+
for (const msg of emails) {
|
|
100
|
+
await fetch(`${MAILPIT_URL}/api/v1/messages`, {
|
|
101
|
+
method: "DELETE",
|
|
102
|
+
headers: { "Content-Type": "application/json" },
|
|
103
|
+
body: JSON.stringify({ IDs: [msg.ID] }),
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=mailpit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mailpit.js","sourceRoot":"","sources":["../../../src/test/helpers/mailpit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/test/setup.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { afterAll, afterEach, beforeAll } from "vitest";
|
|
2
|
+
import { server, mockState, requestCounts } from "../mocks/index.js";
|
|
3
|
+
// Start MSW server before all tests
|
|
4
|
+
beforeAll(() => {
|
|
5
|
+
server.listen({ onUnhandledRequest: "error" });
|
|
6
|
+
});
|
|
7
|
+
// Reset handlers and state after each test
|
|
8
|
+
afterEach(() => {
|
|
9
|
+
server.resetHandlers();
|
|
10
|
+
mockState.reset();
|
|
11
|
+
requestCounts.reset();
|
|
12
|
+
});
|
|
13
|
+
// Clean up after all tests
|
|
14
|
+
afterAll(() => {
|
|
15
|
+
server.close();
|
|
16
|
+
});
|
|
17
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/test/setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAErE,oCAAoC;AACpC,SAAS,CAAC,GAAG,EAAE;IACb,MAAM,CAAC,MAAM,CAAC,EAAE,kBAAkB,EAAE,OAAO,EAAE,CAAC,CAAC;AACjD,CAAC,CAAC,CAAC;AAEH,2CAA2C;AAC3C,SAAS,CAAC,GAAG,EAAE;IACb,MAAM,CAAC,aAAa,EAAE,CAAC;IACvB,SAAS,CAAC,KAAK,EAAE,CAAC;IAClB,aAAa,CAAC,KAAK,EAAE,CAAC;AACxB,CAAC,CAAC,CAAC;AAEH,2BAA2B;AAC3B,QAAQ,CAAC,GAAG,EAAE;IACZ,MAAM,CAAC,KAAK,EAAE,CAAC;AACjB,CAAC,CAAC,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { TokenStoreType } from "./lib/token-store.js";
|
|
2
|
+
import type { MockOptions } from "./mocks/state.js";
|
|
3
|
+
/**
|
|
4
|
+
* Default tenant ID for platform-level operations
|
|
5
|
+
*/
|
|
6
|
+
export declare const PLATFORM_TENANT_ID = "_platform";
|
|
7
|
+
/**
|
|
8
|
+
* Client configuration
|
|
9
|
+
*/
|
|
10
|
+
export interface ClientConfig {
|
|
11
|
+
/** Base URL of the stack (e.g., "https://stack.zenku.app") */
|
|
12
|
+
baseUrl: string;
|
|
13
|
+
/**
|
|
14
|
+
* Tenant identifier (default: "_platform" for platform-level operations)
|
|
15
|
+
*
|
|
16
|
+
* Use "_platform" (or omit) for platform admin operations.
|
|
17
|
+
* Use a specific tenant ID for end-user applications.
|
|
18
|
+
*/
|
|
19
|
+
tenantId?: string;
|
|
20
|
+
/** Token storage type or custom implementation */
|
|
21
|
+
tokenStore?: TokenStoreType;
|
|
22
|
+
/** Storage key prefix (default: "stack") */
|
|
23
|
+
storagePrefix?: string;
|
|
24
|
+
/** Request timeout in milliseconds (default: 30000) */
|
|
25
|
+
timeout?: number;
|
|
26
|
+
/**
|
|
27
|
+
* Static access token for service accounts or testing
|
|
28
|
+
*
|
|
29
|
+
* When provided, this token is used for all requests without going through
|
|
30
|
+
* the auth flow. Useful for:
|
|
31
|
+
* - Service role access (bypasses RLS)
|
|
32
|
+
* - Testing with pre-generated tokens
|
|
33
|
+
* - Server-side operations with admin tokens
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* const client = createClient({
|
|
38
|
+
* baseUrl: "https://stack.example.com",
|
|
39
|
+
* tenantId: "my-tenant",
|
|
40
|
+
* accessToken: process.env.SERVICE_ROLE_JWT,
|
|
41
|
+
* });
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
accessToken?: string;
|
|
45
|
+
/**
|
|
46
|
+
* Account ID for admin/control-plane operations
|
|
47
|
+
*
|
|
48
|
+
* Required for operations like managing storage policies.
|
|
49
|
+
* This is the Basejump account ID that owns the tenant.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```typescript
|
|
53
|
+
* const client = createClient({
|
|
54
|
+
* baseUrl: "https://stack.example.com",
|
|
55
|
+
* tenantId: "my-tenant",
|
|
56
|
+
* accountId: "acct_123",
|
|
57
|
+
* accessToken: process.env.ADMIN_JWT,
|
|
58
|
+
* });
|
|
59
|
+
*
|
|
60
|
+
* // Now you can manage policies
|
|
61
|
+
* await client.storage.policies.applyTemplate("avatars", "ownerOnly");
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
accountId?: string;
|
|
65
|
+
/**
|
|
66
|
+
* Enable mock mode for testing/development
|
|
67
|
+
*
|
|
68
|
+
* When true, the client returns mock responses without making HTTP requests.
|
|
69
|
+
* Uses the same mock data as MSW handlers for consistency.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```typescript
|
|
73
|
+
* const client = createClient({
|
|
74
|
+
* baseUrl: "https://stack.example.com",
|
|
75
|
+
* tenantId: "my-tenant",
|
|
76
|
+
* mock: true,
|
|
77
|
+
* });
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
mock?: boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Mock options (only used when mock: true)
|
|
83
|
+
*/
|
|
84
|
+
mockOptions?: MockOptions;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Internal client configuration with resolved tenant
|
|
88
|
+
* @internal
|
|
89
|
+
*/
|
|
90
|
+
export interface ResolvedClientConfig extends ClientConfig {
|
|
91
|
+
/** Resolved tenant identifier (never undefined) */
|
|
92
|
+
tenantId: string;
|
|
93
|
+
}
|
|
94
|
+
export type { TokenStore, TokenStoreType } from "./lib/token-store.js";
|
|
95
|
+
export type { MockOptions } from "./mocks/state.js";
|
|
96
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;GAEG;AACH,eAAO,MAAM,kBAAkB,cAAc,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,4CAA4C;IAC5C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;;;;;;;;;;OAiBG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;;;;;;;;;;;;OAkBG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;;;;;OAcG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;OAEG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAqB,SAAQ,YAAY;IACxD,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAC;CAClB;AAGD,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACvE,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,WAAW,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kaiz11/stack-client",
|
|
3
|
+
"version": "0.0.14",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/kaiz11/hikari.git",
|
|
8
|
+
"directory": "packages/stack-client"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.js"
|
|
17
|
+
},
|
|
18
|
+
"./auth": {
|
|
19
|
+
"types": "./dist/auth/index.d.ts",
|
|
20
|
+
"import": "./dist/auth/index.js"
|
|
21
|
+
},
|
|
22
|
+
"./auth/server": {
|
|
23
|
+
"types": "./dist/auth/server/index.d.ts",
|
|
24
|
+
"import": "./dist/auth/server/index.js"
|
|
25
|
+
},
|
|
26
|
+
"./storage": {
|
|
27
|
+
"types": "./dist/storage/index.d.ts",
|
|
28
|
+
"import": "./dist/storage/index.js"
|
|
29
|
+
},
|
|
30
|
+
"./accounts": {
|
|
31
|
+
"types": "./dist/accounts/index.d.ts",
|
|
32
|
+
"import": "./dist/accounts/index.js"
|
|
33
|
+
},
|
|
34
|
+
"./test/helpers/jwt": {
|
|
35
|
+
"types": "./dist/test/helpers/jwt.d.ts",
|
|
36
|
+
"import": "./dist/test/helpers/jwt.js"
|
|
37
|
+
},
|
|
38
|
+
"./cli": {
|
|
39
|
+
"types": "./dist/cli/index.d.ts",
|
|
40
|
+
"import": "./dist/cli/index.js"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "tsc",
|
|
45
|
+
"typecheck": "tsc --noEmit",
|
|
46
|
+
"lint": "pnpm typecheck && pnpm lint:eslint && pnpm lint:prettier",
|
|
47
|
+
"lint:eslint": "eslint .",
|
|
48
|
+
"lint:prettier": "prettier --check .",
|
|
49
|
+
"format": "prettier --write .",
|
|
50
|
+
"test": "vitest run",
|
|
51
|
+
"test:watch": "vitest",
|
|
52
|
+
"test:integration": "./scripts/integration-test.sh",
|
|
53
|
+
"test:integration:watch": "./scripts/integration-test.sh --watch",
|
|
54
|
+
"test:integration:remote": "./scripts/integration-test-remote.sh",
|
|
55
|
+
"test:integration:remote:watch": "./scripts/integration-test-remote.sh --watch",
|
|
56
|
+
"release": "./scripts/publish.sh"
|
|
57
|
+
},
|
|
58
|
+
"dependencies": {
|
|
59
|
+
"@supabase/postgrest-js": "catalog:",
|
|
60
|
+
"jose": "catalog:",
|
|
61
|
+
"zod": "catalog:"
|
|
62
|
+
},
|
|
63
|
+
"devDependencies": {
|
|
64
|
+
"@eslint/js": "catalog:",
|
|
65
|
+
"@types/node": "catalog:",
|
|
66
|
+
"@typescript-eslint/eslint-plugin": "catalog:",
|
|
67
|
+
"@typescript-eslint/parser": "catalog:",
|
|
68
|
+
"@vitest/coverage-v8": "^4.0.16",
|
|
69
|
+
"eslint": "catalog:",
|
|
70
|
+
"globals": "catalog:",
|
|
71
|
+
"happy-dom": "catalog:",
|
|
72
|
+
"hono": "catalog:",
|
|
73
|
+
"msw": "catalog:",
|
|
74
|
+
"prettier": "catalog:",
|
|
75
|
+
"typescript": "catalog:",
|
|
76
|
+
"vitest": "catalog:"
|
|
77
|
+
}
|
|
78
|
+
}
|