@motherbase/client 2.2.1 → 2.2.4
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/COMPATIBILITY.md +157 -0
- package/LICENSE +21 -21
- package/README.md +52 -4
- package/dist/admin/auth-admin-client.d.ts +43 -0
- package/dist/admin/auth-admin-client.d.ts.map +1 -0
- package/dist/admin/auth-admin-client.js +62 -0
- package/dist/admin/auth-admin-client.js.map +1 -0
- package/dist/admin/auth-admin-mfa-client.d.ts +22 -0
- package/dist/admin/auth-admin-mfa-client.d.ts.map +1 -0
- package/dist/admin/auth-admin-mfa-client.js +17 -0
- package/dist/admin/auth-admin-mfa-client.js.map +1 -0
- package/dist/admin/types.d.ts +85 -0
- package/dist/admin/types.d.ts.map +1 -0
- package/dist/admin/types.js +3 -0
- package/dist/admin/types.js.map +1 -0
- package/dist/auth/constants.d.ts +21 -0
- package/dist/auth/constants.d.ts.map +1 -0
- package/dist/auth/constants.js +34 -0
- package/dist/auth/constants.js.map +1 -0
- package/dist/auth/index.d.ts +5 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +34 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/motherbase-plugin.d.ts +6 -0
- package/dist/auth/motherbase-plugin.d.ts.map +1 -0
- package/dist/auth/motherbase-plugin.js +80 -0
- package/dist/auth/motherbase-plugin.js.map +1 -0
- package/dist/auth/pkce.d.ts +19 -0
- package/dist/auth/pkce.d.ts.map +1 -0
- package/dist/auth/pkce.js +89 -0
- package/dist/auth/pkce.js.map +1 -0
- package/dist/auth/session-utils.d.ts +29 -0
- package/dist/auth/session-utils.d.ts.map +1 -0
- package/dist/auth/session-utils.js +123 -0
- package/dist/auth/session-utils.js.map +1 -0
- package/dist/auth/session.d.ts +51 -0
- package/dist/auth/session.d.ts.map +1 -0
- package/dist/auth/session.js +161 -0
- package/dist/auth/session.js.map +1 -0
- package/dist/auth/types.d.ts +341 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +2 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/auth/utils.d.ts +28 -0
- package/dist/auth/utils.d.ts.map +1 -0
- package/dist/auth/utils.js +70 -0
- package/dist/auth/utils.js.map +1 -0
- package/dist/auth.d.ts +3 -2
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +27 -11
- package/dist/auth.js.map +1 -1
- package/dist/channel.d.ts +11 -0
- package/dist/channel.d.ts.map +1 -1
- package/dist/channel.js +26 -2
- package/dist/channel.js.map +1 -1
- package/dist/cookies/cookie-storage.d.ts +12 -0
- package/dist/cookies/cookie-storage.d.ts.map +1 -0
- package/dist/cookies/cookie-storage.js +35 -0
- package/dist/cookies/cookie-storage.js.map +1 -0
- package/dist/cookies/index.d.ts +5 -0
- package/dist/cookies/index.d.ts.map +1 -0
- package/dist/cookies/index.js +5 -0
- package/dist/cookies/index.js.map +1 -0
- package/dist/cookies/server-cookie-storage.d.ts +20 -0
- package/dist/cookies/server-cookie-storage.d.ts.map +1 -0
- package/dist/cookies/server-cookie-storage.js +60 -0
- package/dist/cookies/server-cookie-storage.js.map +1 -0
- package/dist/cookies/types.d.ts +33 -0
- package/dist/cookies/types.d.ts.map +1 -0
- package/dist/cookies/types.js +8 -0
- package/dist/cookies/types.js.map +1 -0
- package/dist/cookies/utils.d.ts +23 -0
- package/dist/cookies/utils.d.ts.map +1 -0
- package/dist/cookies/utils.js +67 -0
- package/dist/cookies/utils.js.map +1 -0
- package/dist/database/database.d.ts +197 -0
- package/dist/database/database.d.ts.map +1 -0
- package/dist/database/database.js +2 -0
- package/dist/database/database.js.map +1 -0
- package/dist/database/facade.d.ts +218 -0
- package/dist/database/facade.d.ts.map +1 -0
- package/dist/database/facade.js +198 -0
- package/dist/database/facade.js.map +1 -0
- package/dist/database/query.d.ts +97 -0
- package/dist/database/query.d.ts.map +1 -0
- package/dist/database/query.js +94 -0
- package/dist/database/query.js.map +1 -0
- package/dist/database/types.d.ts +314 -0
- package/dist/database/types.d.ts.map +1 -0
- package/dist/database/types.js +2 -0
- package/dist/database/types.js.map +1 -0
- package/dist/functions/errors.d.ts +28 -0
- package/dist/functions/errors.d.ts.map +1 -0
- package/dist/functions/errors.js +37 -0
- package/dist/functions/errors.js.map +1 -0
- package/dist/functions/index.d.ts +9 -0
- package/dist/functions/index.d.ts.map +1 -0
- package/dist/functions/index.js +40 -0
- package/dist/functions/index.js.map +1 -0
- package/dist/functions/types.d.ts +25 -0
- package/dist/functions/types.d.ts.map +1 -0
- package/dist/functions/types.js +2 -0
- package/dist/functions/types.js.map +1 -0
- package/dist/http/backend-error.d.ts +17 -0
- package/dist/http/backend-error.d.ts.map +1 -0
- package/dist/http/backend-error.js +11 -0
- package/dist/http/backend-error.js.map +1 -0
- package/dist/http/index.d.ts +59 -0
- package/dist/http/index.d.ts.map +1 -0
- package/dist/http/index.js +175 -0
- package/dist/http/index.js.map +1 -0
- package/dist/http/types.d.ts +45 -0
- package/dist/http/types.d.ts.map +1 -0
- package/dist/http/types.js +2 -0
- package/dist/http/types.js.map +1 -0
- package/dist/http/utils.d.ts +14 -0
- package/dist/http/utils.d.ts.map +1 -0
- package/dist/http/utils.js +37 -0
- package/dist/http/utils.js.map +1 -0
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +2 -1
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +47 -77
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +58 -73
- package/dist/index.js.map +1 -1
- package/dist/pkce.js +4 -4
- package/dist/postgrest/index.d.ts +4 -0
- package/dist/postgrest/index.d.ts.map +1 -0
- package/dist/postgrest/index.js +4 -0
- package/dist/postgrest/index.js.map +1 -0
- package/dist/postgrest/query-builder.d.ts +224 -0
- package/dist/postgrest/query-builder.d.ts.map +1 -0
- package/dist/postgrest/query-builder.js +544 -0
- package/dist/postgrest/query-builder.js.map +1 -0
- package/dist/postgrest/rpc.d.ts +12 -0
- package/dist/postgrest/rpc.d.ts.map +1 -0
- package/dist/postgrest/rpc.js +42 -0
- package/dist/postgrest/rpc.js.map +1 -0
- package/dist/postgrest/types.d.ts +88 -0
- package/dist/postgrest/types.d.ts.map +1 -0
- package/dist/postgrest/types.js +2 -0
- package/dist/postgrest/types.js.map +1 -0
- package/dist/postgrest/utils.d.ts +23 -0
- package/dist/postgrest/utils.d.ts.map +1 -0
- package/dist/postgrest/utils.js +87 -0
- package/dist/postgrest/utils.js.map +1 -0
- package/dist/postgrest.d.ts +5 -1
- package/dist/postgrest.d.ts.map +1 -1
- package/dist/postgrest.js +17 -10
- package/dist/postgrest.js.map +1 -1
- package/dist/realtime/channel.d.ts +83 -0
- package/dist/realtime/channel.d.ts.map +1 -0
- package/dist/realtime/channel.js +240 -0
- package/dist/realtime/channel.js.map +1 -0
- package/dist/realtime/index.d.ts +94 -0
- package/dist/realtime/index.d.ts.map +1 -0
- package/dist/realtime/index.js +455 -0
- package/dist/realtime/index.js.map +1 -0
- package/dist/realtime/types.d.ts +120 -0
- package/dist/realtime/types.d.ts.map +1 -0
- package/dist/realtime/types.js +2 -0
- package/dist/realtime/types.js.map +1 -0
- package/dist/realtime.d.ts +1 -0
- package/dist/realtime.d.ts.map +1 -1
- package/dist/realtime.js +26 -1
- package/dist/realtime.js.map +1 -1
- package/dist/runtime.d.ts +13 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +15 -0
- package/dist/runtime.js.map +1 -0
- package/dist/session.d.ts +2 -0
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +11 -2
- package/dist/session.js.map +1 -1
- package/dist/storage/bucket.d.ts +166 -0
- package/dist/storage/bucket.d.ts.map +1 -0
- package/dist/storage/bucket.js +294 -0
- package/dist/storage/bucket.js.map +1 -0
- package/dist/storage/index.d.ts +45 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +55 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/types.d.ts +131 -0
- package/dist/storage/types.d.ts.map +1 -0
- package/dist/storage/types.js +2 -0
- package/dist/storage/types.js.map +1 -0
- package/dist/storage/utils.d.ts +27 -0
- package/dist/storage/utils.d.ts.map +1 -0
- package/dist/storage/utils.js +43 -0
- package/dist/storage/utils.js.map +1 -0
- package/dist/test.d.ts +2 -0
- package/dist/test.d.ts.map +1 -0
- package/dist/test.js +3 -0
- package/dist/test.js.map +1 -0
- package/dist/types.d.ts +14 -249
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/compat.d.ts +40 -0
- package/dist/utils/compat.d.ts.map +1 -0
- package/dist/utils/compat.js +100 -0
- package/dist/utils/compat.js.map +1 -0
- package/dist/utils/runtime.d.ts +13 -0
- package/dist/utils/runtime.d.ts.map +1 -0
- package/dist/utils/runtime.js +15 -0
- package/dist/utils/runtime.js.map +1 -0
- package/dist/utils/testing.d.ts +38 -0
- package/dist/utils/testing.d.ts.map +1 -0
- package/dist/utils/testing.js +50 -0
- package/dist/utils/testing.js.map +1 -0
- package/dist/utils/warn.d.ts +2 -0
- package/dist/utils/warn.d.ts.map +1 -0
- package/dist/utils/warn.js +23 -0
- package/dist/utils/warn.js.map +1 -0
- package/package.json +13 -11
- package/dist/devices.d.ts +0 -13
- package/dist/devices.d.ts.map +0 -1
- package/dist/devices.js +0 -13
- package/dist/devices.js.map +0 -1
- package/dist/profile.d.ts +0 -16
- package/dist/profile.d.ts.map +0 -1
- package/dist/profile.js +0 -26
- package/dist/profile.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/storage/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGpD,gFAAgF;AAChF,MAAM,UAAU,UAAU,CAAC,OAAsB;IAC7C,OAAO;QACH,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,eAAe,EAAE,OAAO,CAAC,aAAa;QACtC,kBAAkB,EAAE,OAAO,CAAC,gBAAgB;KAC/C,CAAC;AACN,CAAC;AAED,qEAAqE;AACrE,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,WAAW,CAAC,KAAK,SAAS,CAAC;AAE1D,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,WAAW,CAAC,SAAS,eAAe,CAAC;AAEpE,qEAAqE;AACrE,MAAM,UAAU,cAAc,CAAC,SAA2B;IACtD,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,CAAC;IACpC,KAAK,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAU,EAAE,CAAC;QAC5E,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,SAAS;YAAE,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE7F;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,iEAAiE,CAAC;AAEtF,+EAA+E;AAC/E,MAAM,UAAU,UAAU,CAAC,IAAiB,EAAE,WAAoB;IAC9D,IAAI,OAAO,IAAI,KAAK,WAAW,IAAI,IAAI,YAAY,IAAI,EAAE,CAAC;QACtD,OAAO,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACtE,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,YAAY,WAAW,CAAC,CAAC,CAAC,IAAI;QAC5C,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACnH,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,WAAW,IAAI,0BAA0B,EAAE,CAAC,CAAC;AACpH,CAAC"}
|
package/dist/test.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../src/test.ts"],"names":[],"mappings":""}
|
package/dist/test.js
ADDED
package/dist/test.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.js","sourceRoot":"","sources":["../src/test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI1C,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,EAAE,CAAC,CAAA"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,224 +1,16 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Types shared by every module of the SDK: the result envelope and the client
|
|
3
|
+
* options. A type owned by one module lives in that module's `types.ts`.
|
|
4
|
+
*/
|
|
5
|
+
import type { ApiEnvelopeContract } from '@motherbase/contracts';
|
|
6
|
+
import type { AuthFlowType, KeyValueStorageAdapter, SessionStorageAdapter } from './auth/types.js';
|
|
7
|
+
import type { SocketLike } from './realtime/types.js';
|
|
3
8
|
/** The envelope non-REST API endpoints (auth, storage, edge) wrap their payload in. */
|
|
4
|
-
export interface ApiEnvelope<T = unknown> {
|
|
5
|
-
status: 0 | 1;
|
|
6
|
-
message: string;
|
|
9
|
+
export interface ApiEnvelope<T = unknown> extends ApiEnvelopeContract<T> {
|
|
7
10
|
code?: string;
|
|
8
11
|
requestId?: string;
|
|
9
|
-
data?: T;
|
|
10
12
|
pager?: Record<string, unknown>;
|
|
11
13
|
}
|
|
12
|
-
/**
|
|
13
|
-
* A timestamp as it can reach the client: ISO string over HTTP, `Date` when a
|
|
14
|
-
* server-side caller passes a Better Auth row straight in.
|
|
15
|
-
*/
|
|
16
|
-
export type Timestamp = string | Date;
|
|
17
|
-
/**
|
|
18
|
-
* The open bag of profile fields.
|
|
19
|
-
*
|
|
20
|
-
* `User` itself is closed: every field the platform sets is declared, and a
|
|
21
|
-
* typo like `user.emailVerifed` is a compile error. Project-specific columns
|
|
22
|
-
* (anything added to `user.additionalFields` on the server) cannot be known
|
|
23
|
-
* here, so they live in this bag, which is the one place with an index
|
|
24
|
-
* signature. `compat.ts` copies every non-platform field into it, so a custom
|
|
25
|
-
* `plan` column is readable as `user.user_metadata.plan`.
|
|
26
|
-
*
|
|
27
|
-
* Declare your own shape for it when you know the columns:
|
|
28
|
-
* `const meta = user.user_metadata as { plan?: string }`.
|
|
29
|
-
*/
|
|
30
|
-
export interface UserMetadata {
|
|
31
|
-
name?: string | null;
|
|
32
|
-
image?: string | null;
|
|
33
|
-
[key: string]: unknown;
|
|
34
|
-
}
|
|
35
|
-
/** Fields Better Auth itself owns on a user row. */
|
|
36
|
-
export interface BetterAuthUserFields {
|
|
37
|
-
/** Display name. Better Auth's own column, mirrored into `user_metadata`. */
|
|
38
|
-
name?: string | null;
|
|
39
|
-
/** Avatar URL. Better Auth's own column, mirrored into `user_metadata`. */
|
|
40
|
-
image?: string | null;
|
|
41
|
-
/** Better Auth stores verification as a boolean, not a timestamp. */
|
|
42
|
-
emailVerified?: boolean;
|
|
43
|
-
createdAt?: Timestamp | null;
|
|
44
|
-
updatedAt?: Timestamp | null;
|
|
45
|
-
/** Set by the `phoneNumber` plugin; aliased to `phone`. */
|
|
46
|
-
phoneNumber?: string | null;
|
|
47
|
-
phoneNumberVerified?: boolean | null;
|
|
48
|
-
/** Set by the `admin` plugin. */
|
|
49
|
-
banned?: boolean | null;
|
|
50
|
-
banReason?: string | null;
|
|
51
|
-
banExpires?: Timestamp | null;
|
|
52
|
-
/** Set by the `twoFactor` plugin. */
|
|
53
|
-
twoFactorEnabled?: boolean | null;
|
|
54
|
-
/** Set by the `anonymous` plugin; aliased to `is_anonymous`. */
|
|
55
|
-
isAnonymous?: boolean | null;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* The `additionalFields` Motherbase configures on every project's auth
|
|
59
|
-
* instance (see `apps/server/auth/instance.ts`). The first four are
|
|
60
|
-
* client-writable through `updateUser`; the rest are server-set.
|
|
61
|
-
*/
|
|
62
|
-
export interface MotherbaseUserFields {
|
|
63
|
-
username?: string | null;
|
|
64
|
-
firstName?: string | null;
|
|
65
|
-
lastName?: string | null;
|
|
66
|
-
imageUrl?: string | null;
|
|
67
|
-
/** `'USER'` by default on the server, `'authenticated'` after `compat.ts`. */
|
|
68
|
-
role?: string;
|
|
69
|
-
status?: string | null;
|
|
70
|
-
classicEmail?: string | null;
|
|
71
|
-
appleId?: string | null;
|
|
72
|
-
appleEmail?: string | null;
|
|
73
|
-
googleId?: string | null;
|
|
74
|
-
googleEmail?: string | null;
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* The snake_case aliases `compat.ts` adds on the way out, so code ported from
|
|
78
|
-
* supabase-js reads `user.created_at` and `user.user_metadata.full_name` on a
|
|
79
|
-
* user that came out of Better Auth.
|
|
80
|
-
*
|
|
81
|
-
* They are optional because a `User` you construct yourself (a test fixture, a
|
|
82
|
-
* value on its way *in*) has not been through `compat.ts` yet. Everything the
|
|
83
|
-
* SDK hands back has them.
|
|
84
|
-
*/
|
|
85
|
-
export interface SupabaseUserAliases {
|
|
86
|
-
/** Always `'authenticated'`. Present for supabase-js parity. */
|
|
87
|
-
aud?: string;
|
|
88
|
-
created_at?: string | null;
|
|
89
|
-
updated_at?: string | null;
|
|
90
|
-
/** Non-null once the email is verified. Better Auth stores a boolean, so the
|
|
91
|
-
* value is the last-update timestamp rather than the true verification time. */
|
|
92
|
-
email_confirmed_at?: string | null;
|
|
93
|
-
confirmed_at?: string | null;
|
|
94
|
-
/** Alias of `phoneNumber`, `''` when the user has no phone. */
|
|
95
|
-
phone?: string;
|
|
96
|
-
/**
|
|
97
|
-
* Always `{}`: the client is not told which provider issued the session, and
|
|
98
|
-
* a guessed `{ provider: 'email' }` is worse than a missing one.
|
|
99
|
-
*/
|
|
100
|
-
app_metadata?: Record<string, unknown>;
|
|
101
|
-
/** Profile fields (`name`, `image`, any configured additional field). */
|
|
102
|
-
user_metadata?: UserMetadata;
|
|
103
|
-
identities?: UserIdentity[];
|
|
104
|
-
is_anonymous?: boolean;
|
|
105
|
-
}
|
|
106
|
-
/** A linked provider, in the supabase-js `UserIdentity` shape. */
|
|
107
|
-
export interface UserIdentity {
|
|
108
|
-
id: string;
|
|
109
|
-
identity_id: string;
|
|
110
|
-
user_id: string;
|
|
111
|
-
provider: string;
|
|
112
|
-
identity_data: Record<string, unknown>;
|
|
113
|
-
created_at: string | null;
|
|
114
|
-
updated_at: string | null;
|
|
115
|
-
last_sign_in_at: string | null;
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Authenticated user as returned by the API.
|
|
119
|
-
*
|
|
120
|
-
* Closed on purpose: every field the platform can set is declared above, so
|
|
121
|
-
* reading one that does not exist is a compile error instead of a silent
|
|
122
|
-
* `undefined` at runtime. Project-specific columns go through
|
|
123
|
-
* [`UserMetadata`](#UserMetadata) (`user.user_metadata.<field>`).
|
|
124
|
-
*/
|
|
125
|
-
export interface User extends BetterAuthUserFields, MotherbaseUserFields, SupabaseUserAliases {
|
|
126
|
-
id: string;
|
|
127
|
-
email: string;
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* The bearer token issued by sign-up / sign-in. With Better Auth this is the
|
|
131
|
-
* session token; there is no separate refresh token (a session is valid until
|
|
132
|
-
* it expires, after which the user re-authenticates). `refreshToken` is kept
|
|
133
|
-
* optional for backwards source-compat and is unused.
|
|
134
|
-
*/
|
|
135
|
-
export interface Tokens {
|
|
136
|
-
accessToken: string;
|
|
137
|
-
refreshToken?: string;
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* The locally-held session: the bearer token plus the user it belongs to.
|
|
141
|
-
*
|
|
142
|
-
* The snake_case fields are supabase-js aliases, added by the session store on
|
|
143
|
-
* the way out (see `compat.ts`). `access_token` always mirrors `accessToken`;
|
|
144
|
-
* `expires_at` / `expires_in` are present only when the server dated the
|
|
145
|
-
* session, because supabase-js callers schedule refreshes off them and a
|
|
146
|
-
* fabricated expiry schedules them wrong.
|
|
147
|
-
*/
|
|
148
|
-
export interface Session extends Tokens {
|
|
149
|
-
user: User;
|
|
150
|
-
/** supabase-js alias of `accessToken`. */
|
|
151
|
-
access_token?: string;
|
|
152
|
-
/** supabase-js alias of `refreshToken`. Always null on Better Auth sessions. */
|
|
153
|
-
refresh_token?: string | null;
|
|
154
|
-
token_type?: 'bearer';
|
|
155
|
-
/** Unix seconds. Absent when the backend did not date the session. */
|
|
156
|
-
expires_at?: number;
|
|
157
|
-
/** Seconds until `expires_at`. Absent for the same reason. */
|
|
158
|
-
expires_in?: number;
|
|
159
|
-
}
|
|
160
|
-
/** Session payload returned by Better Auth after sign-in or second-factor verification. */
|
|
161
|
-
export interface AuthPayload {
|
|
162
|
-
token: string;
|
|
163
|
-
user: User;
|
|
164
|
-
}
|
|
165
|
-
export type FileVisibility = 'public' | 'private';
|
|
166
|
-
/** Lifecycle of a stored object: `ready` unless a presigned upload is pending. */
|
|
167
|
-
export type FileStatus = 'pending' | 'ready' | 'expired';
|
|
168
|
-
/**
|
|
169
|
-
* A row of the storage table, as `POST /api/files/` returns it.
|
|
170
|
-
*
|
|
171
|
-
* This is the upload shape, not the `list()` shape: `list()` answers in the
|
|
172
|
-
* supabase-js `FileObject` form, which is a different set of fields under
|
|
173
|
-
* different names. Conflating the two is what the old `[key: string]: unknown`
|
|
174
|
-
* hid, and `file.filename` (a field the server never sent) type-checked.
|
|
175
|
-
*/
|
|
176
|
-
export interface StoredFile {
|
|
177
|
-
id: string;
|
|
178
|
-
/** Bucket slug. */
|
|
179
|
-
bucket: string;
|
|
180
|
-
/** Object key inside the bucket, including any prefix. */
|
|
181
|
-
key: string;
|
|
182
|
-
mime?: string | null;
|
|
183
|
-
size: number;
|
|
184
|
-
visibility: FileVisibility;
|
|
185
|
-
status: FileStatus;
|
|
186
|
-
/** Set for public objects and for drivers that store an absolute URL. */
|
|
187
|
-
url?: string | null;
|
|
188
|
-
ownerId?: string | null;
|
|
189
|
-
bucketId?: string | null;
|
|
190
|
-
/** Deadline of a presigned upload that has not been finalised. */
|
|
191
|
-
uploadExpiresAt?: string | null;
|
|
192
|
-
createdAt: string;
|
|
193
|
-
updatedAt: string;
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* One object as `list()` returns it: the supabase-js `FileObject` shape, which
|
|
197
|
-
* is what code ported from Supabase reads (`obj.name`, `obj.metadata.size`).
|
|
198
|
-
*/
|
|
199
|
-
export interface FileObject {
|
|
200
|
-
/** Key relative to the bucket. */
|
|
201
|
-
name: string;
|
|
202
|
-
id: string;
|
|
203
|
-
created_at: string | null;
|
|
204
|
-
updated_at: string | null;
|
|
205
|
-
last_accessed_at: string | null;
|
|
206
|
-
metadata: {
|
|
207
|
-
size: number;
|
|
208
|
-
mimetype: string | null;
|
|
209
|
-
cacheControl: string | null;
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
/** Exact payload returned by `POST /api/files/`. */
|
|
213
|
-
export type StorageUploadResponse = StorageUploadContract<StoredFile>;
|
|
214
|
-
/** Exact payload returned by `DELETE /api/files/:id`. */
|
|
215
|
-
export type StorageRemoveResponse = StorageRemoveContract;
|
|
216
|
-
/** A file-ish value accepted by multipart uploads (browser File/Blob or RN asset). */
|
|
217
|
-
export type UploadInput = Blob | ArrayBuffer | ArrayBufferView | {
|
|
218
|
-
uri: string;
|
|
219
|
-
name?: string;
|
|
220
|
-
type?: string;
|
|
221
|
-
};
|
|
222
14
|
/**
|
|
223
15
|
* The uniform result envelope every data/auth/storage call resolves to.
|
|
224
16
|
* `error` is `null` on success; `data` is `null` on failure. Never throws for
|
|
@@ -243,25 +35,6 @@ export interface MotherbaseError {
|
|
|
243
35
|
*/
|
|
244
36
|
requestId?: string;
|
|
245
37
|
}
|
|
246
|
-
/**
|
|
247
|
-
* Persists the session between runs. Implementations must be synchronous-or-async
|
|
248
|
-
* tolerant: every method may return a value or a promise of it.
|
|
249
|
-
*/
|
|
250
|
-
export interface SessionStorageAdapter {
|
|
251
|
-
get(): Session | null | Promise<Session | null>;
|
|
252
|
-
set(session: Session | null): void | Promise<void>;
|
|
253
|
-
}
|
|
254
|
-
/**
|
|
255
|
-
* A key/value store shaped like `window.localStorage` or React Native's
|
|
256
|
-
* `AsyncStorage`. supabase-js takes its session storage in this form, so an app
|
|
257
|
-
* being ported passes one of these; the client wraps it (see
|
|
258
|
-
* `keyValueStorage`) rather than failing at runtime on a missing `.get`.
|
|
259
|
-
*/
|
|
260
|
-
export interface KeyValueStorageAdapter {
|
|
261
|
-
getItem(key: string): string | null | Promise<string | null>;
|
|
262
|
-
setItem(key: string, value: string): void | Promise<void>;
|
|
263
|
-
removeItem(key: string): void | Promise<void>;
|
|
264
|
-
}
|
|
265
38
|
/**
|
|
266
39
|
* The supabase-js-shaped half of the options.
|
|
267
40
|
*
|
|
@@ -292,7 +65,8 @@ export interface SupabaseStyleOptions {
|
|
|
292
65
|
* load (or by `auth.exchangeCodeForSession(code)`) with the verifier this
|
|
293
66
|
* browser kept, so a leaked redirect URL is worth nothing on its own.
|
|
294
67
|
*/
|
|
295
|
-
flowType?:
|
|
68
|
+
flowType?: AuthFlowType;
|
|
69
|
+
/** Accepted for supabase-js compatibility; has no effect. */
|
|
296
70
|
debug?: boolean;
|
|
297
71
|
};
|
|
298
72
|
db?: {
|
|
@@ -300,9 +74,12 @@ export interface SupabaseStyleOptions {
|
|
|
300
74
|
schema?: string;
|
|
301
75
|
};
|
|
302
76
|
global?: {
|
|
77
|
+
/** Headers sent with every request. */
|
|
303
78
|
headers?: Record<string, string>;
|
|
79
|
+
/** A `fetch` to use instead of the global one. */
|
|
304
80
|
fetch?: typeof fetch;
|
|
305
81
|
};
|
|
82
|
+
/** Accepted for supabase-js compatibility; has no effect. */
|
|
306
83
|
realtime?: Record<string, unknown>;
|
|
307
84
|
}
|
|
308
85
|
export interface ClientOptions extends SupabaseStyleOptions {
|
|
@@ -336,18 +113,6 @@ export interface ClientOptions extends SupabaseStyleOptions {
|
|
|
336
113
|
* Inject a socket.io factory for realtime (tests / custom transports).
|
|
337
114
|
* When omitted, `socket.io-client` is imported lazily at connect time.
|
|
338
115
|
*/
|
|
339
|
-
realtimeIoFactory?: (url: string, opts: Record<string, unknown>) =>
|
|
116
|
+
realtimeIoFactory?: (url: string, opts: Record<string, unknown>) => SocketLike;
|
|
340
117
|
}
|
|
341
|
-
/**
|
|
342
|
-
* Supabase-compatible auth change events emitted by `onAuthStateChange`.
|
|
343
|
-
*
|
|
344
|
-
* `INITIAL_SESSION` is fired once per subscription, right after subscribing,
|
|
345
|
-
* with whatever session was already stored. supabase-js does the same, and an
|
|
346
|
-
* app that clears its loading flag on it hangs forever without it.
|
|
347
|
-
*/
|
|
348
|
-
export type AuthChangeEvent = 'INITIAL_SESSION' | 'SIGNED_IN' | 'SIGNED_OUT' | 'TOKEN_REFRESHED' | 'USER_UPDATED' | 'PASSWORD_RECOVERY' | 'MFA_CHALLENGE_VERIFIED';
|
|
349
|
-
export type AuthChangeListener = (event: AuthChangeEvent, session: Session | null) => void;
|
|
350
|
-
/** Internal event names used by the session store. */
|
|
351
|
-
export type AuthEvent = 'signIn' | 'signOut' | 'tokenRefreshed' | 'userUpdated' | 'mfaVerified';
|
|
352
|
-
export type AuthListener = (event: AuthEvent, session: Session | null) => void;
|
|
353
118
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACnG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,uFAAuF;AACvF,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,OAAO,CAAE,SAAQ,mBAAmB,CAAC,CAAC,CAAC;IACtE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB,CAAC,CAAC;IACnC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IACf,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;CAC/B;AAED,oCAAoC;AACpC,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,CAAC,EAAE;QACL,+EAA+E;QAC/E,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAC3B;;;WAGG;QACH,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,sFAAsF;QACtF,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B,6EAA6E;QAC7E,OAAO,CAAC,EAAE,sBAAsB,GAAG,qBAAqB,CAAC;QACzD,qDAAqD;QACrD,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB;;;;;WAKG;QACH,QAAQ,CAAC,EAAE,YAAY,CAAC;QACxB,6DAA6D;QAC7D,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB,CAAC;IACF,EAAE,CAAC,EAAE;QACH,+EAA+E;QAC/E,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,MAAM,CAAC,EAAE;QACP,uCAAuC;QACvC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,kDAAkD;QAClD,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;KACtB,CAAC;IACF,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,aAAc,SAAQ,oBAAoB;IACzD,sEAAsE;IACtE,OAAO,CAAC,EAAE,qBAAqB,CAAC;IAChC,sEAAsE;IACtE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4DAA4D;IAC5D,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,UAAU,CAAC;CAChF"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* supabase-js shape normalisation.
|
|
3
|
+
*
|
|
4
|
+
* Motherbase speaks Better Auth, which names things `accessToken`, `createdAt`
|
|
5
|
+
* and puts custom profile fields flat on the user. supabase-js hands
|
|
6
|
+
* applications `access_token`, `created_at` and `user_metadata`. Code ported
|
|
7
|
+
* from Supabase reads the second set, and reading a field that does not exist
|
|
8
|
+
* is not an error: it is `undefined`, rendered as a blank name or an infinite
|
|
9
|
+
* loading spinner, at runtime, in production.
|
|
10
|
+
*
|
|
11
|
+
* So every session and user that leaves the SDK carries BOTH spellings. The
|
|
12
|
+
* camelCase ones stay authoritative (nothing existing breaks); the snake_case
|
|
13
|
+
* ones are aliases added on the way out. Normalisation happens in exactly one
|
|
14
|
+
* place, the session store, so no call path can forget it.
|
|
15
|
+
*/
|
|
16
|
+
import type { Session, User } from '../auth/types.js';
|
|
17
|
+
/**
|
|
18
|
+
* Add the supabase-js user aliases without dropping anything Better Auth sent.
|
|
19
|
+
*
|
|
20
|
+
* `user_metadata` collects the profile fields (`name`, `image`, and any
|
|
21
|
+
* `additionalFields` the project configured), because that is where a Supabase
|
|
22
|
+
* app looks for them. They stay flat on the user as well.
|
|
23
|
+
*
|
|
24
|
+
* `app_metadata` is deliberately `{}` rather than a guessed `{ provider:
|
|
25
|
+
* 'email' }`: the client cannot know which provider issued the session, and a
|
|
26
|
+
* wrong provider is worse than a missing one. Reading `.provider` off it yields
|
|
27
|
+
* `undefined` instead of throwing, which is the failure mode that lets an app
|
|
28
|
+
* boot.
|
|
29
|
+
*/
|
|
30
|
+
export declare function normalizeUser(user: User | null | undefined): User | null;
|
|
31
|
+
/**
|
|
32
|
+
* Add the supabase-js session aliases.
|
|
33
|
+
*
|
|
34
|
+
* `expires_at` / `expires_in` are only emitted when the server actually told us
|
|
35
|
+
* when the session ends. Inventing a lifetime would be worse than omitting it:
|
|
36
|
+
* supabase-js callers use `expires_at` to decide when to refresh, and a made-up
|
|
37
|
+
* value schedules a refresh at the wrong time.
|
|
38
|
+
*/
|
|
39
|
+
export declare function normalizeSession(session: Session | null | undefined): Session | null;
|
|
40
|
+
//# sourceMappingURL=compat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compat.d.ts","sourceRoot":"","sources":["../../src/utils/compat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAgB,MAAM,kBAAkB,CAAC;AAkCpE;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,GAAG,IAAI,CA8BxE;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,GAAG,IAAI,CAepF"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/** Fields Better Auth owns on the user, which are not profile metadata. */
|
|
2
|
+
const RESERVED_USER_FIELDS = new Set([
|
|
3
|
+
'id',
|
|
4
|
+
'email',
|
|
5
|
+
'emailVerified',
|
|
6
|
+
'createdAt',
|
|
7
|
+
'updatedAt',
|
|
8
|
+
'role',
|
|
9
|
+
'banned',
|
|
10
|
+
'banReason',
|
|
11
|
+
'banExpires',
|
|
12
|
+
'twoFactorEnabled',
|
|
13
|
+
'isAnonymous',
|
|
14
|
+
// aliases this module itself adds, so a re-normalisation is idempotent
|
|
15
|
+
'aud',
|
|
16
|
+
'created_at',
|
|
17
|
+
'updated_at',
|
|
18
|
+
'email_confirmed_at',
|
|
19
|
+
'confirmed_at',
|
|
20
|
+
'phone',
|
|
21
|
+
'app_metadata',
|
|
22
|
+
'user_metadata',
|
|
23
|
+
'identities',
|
|
24
|
+
'is_anonymous',
|
|
25
|
+
]);
|
|
26
|
+
function asIso(value) {
|
|
27
|
+
if (typeof value === 'string')
|
|
28
|
+
return value;
|
|
29
|
+
if (value instanceof Date)
|
|
30
|
+
return value.toISOString();
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Add the supabase-js user aliases without dropping anything Better Auth sent.
|
|
35
|
+
*
|
|
36
|
+
* `user_metadata` collects the profile fields (`name`, `image`, and any
|
|
37
|
+
* `additionalFields` the project configured), because that is where a Supabase
|
|
38
|
+
* app looks for them. They stay flat on the user as well.
|
|
39
|
+
*
|
|
40
|
+
* `app_metadata` is deliberately `{}` rather than a guessed `{ provider:
|
|
41
|
+
* 'email' }`: the client cannot know which provider issued the session, and a
|
|
42
|
+
* wrong provider is worse than a missing one. Reading `.provider` off it yields
|
|
43
|
+
* `undefined` instead of throwing, which is the failure mode that lets an app
|
|
44
|
+
* boot.
|
|
45
|
+
*/
|
|
46
|
+
export function normalizeUser(user) {
|
|
47
|
+
if (!user)
|
|
48
|
+
return null;
|
|
49
|
+
const metadata = { ...user.user_metadata };
|
|
50
|
+
for (const [key, value] of Object.entries(user)) {
|
|
51
|
+
if (!RESERVED_USER_FIELDS.has(key))
|
|
52
|
+
metadata[key] = value;
|
|
53
|
+
}
|
|
54
|
+
const createdAt = asIso(user.createdAt) ?? asIso(user.created_at);
|
|
55
|
+
const updatedAt = asIso(user.updatedAt) ?? asIso(user.updated_at);
|
|
56
|
+
// Better Auth stores email verification as a boolean, not a timestamp. The
|
|
57
|
+
// honest mapping is "verified at some point at or before the last update":
|
|
58
|
+
// apps branch on truthiness of this field, not on its exact value.
|
|
59
|
+
const emailConfirmedAt = user.emailVerified ? (updatedAt ?? createdAt ?? null) : null;
|
|
60
|
+
return {
|
|
61
|
+
...user,
|
|
62
|
+
aud: user.aud ?? 'authenticated',
|
|
63
|
+
role: user.role ?? 'authenticated',
|
|
64
|
+
created_at: createdAt ?? null,
|
|
65
|
+
updated_at: updatedAt ?? null,
|
|
66
|
+
email_confirmed_at: emailConfirmedAt,
|
|
67
|
+
confirmed_at: emailConfirmedAt,
|
|
68
|
+
phone: user.phone ?? user.phoneNumber ?? '',
|
|
69
|
+
app_metadata: user.app_metadata ?? {},
|
|
70
|
+
user_metadata: metadata,
|
|
71
|
+
identities: user.identities ?? [],
|
|
72
|
+
// Better Auth's anonymous plugin names it `isAnonymous`.
|
|
73
|
+
is_anonymous: user.is_anonymous ?? Boolean(user.isAnonymous),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Add the supabase-js session aliases.
|
|
78
|
+
*
|
|
79
|
+
* `expires_at` / `expires_in` are only emitted when the server actually told us
|
|
80
|
+
* when the session ends. Inventing a lifetime would be worse than omitting it:
|
|
81
|
+
* supabase-js callers use `expires_at` to decide when to refresh, and a made-up
|
|
82
|
+
* value schedules a refresh at the wrong time.
|
|
83
|
+
*/
|
|
84
|
+
export function normalizeSession(session) {
|
|
85
|
+
if (!session)
|
|
86
|
+
return null;
|
|
87
|
+
const user = normalizeUser(session.user);
|
|
88
|
+
const expiresAt = typeof session.expires_at === 'number' ? session.expires_at : undefined;
|
|
89
|
+
return {
|
|
90
|
+
...session,
|
|
91
|
+
user: user ?? session.user,
|
|
92
|
+
access_token: session.accessToken,
|
|
93
|
+
refresh_token: session.refreshToken ?? null,
|
|
94
|
+
token_type: 'bearer',
|
|
95
|
+
...(expiresAt === undefined
|
|
96
|
+
? {}
|
|
97
|
+
: { expires_at: expiresAt, expires_in: Math.max(0, expiresAt - Math.floor(Date.now() / 1000)) }),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=compat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compat.js","sourceRoot":"","sources":["../../src/utils/compat.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether this runs in a browser page.
|
|
3
|
+
*
|
|
4
|
+
* `window` alone is not the test: React Native defines it too, with no
|
|
5
|
+
* `location` or `history`, and a fetch that sends no Origin while still
|
|
6
|
+
* replaying the session cookie from its native jar. Taking it for a browser
|
|
7
|
+
* meant no Origin on a cookie-carrying mutation (`403 Missing or null Origin`
|
|
8
|
+
* on sign-out) and a crash reading `window.location.href`. A page has a
|
|
9
|
+
* `document`; React Native, Node and Deno do not.
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export declare function isBrowser(): boolean;
|
|
13
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/utils/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAEnC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether this runs in a browser page.
|
|
3
|
+
*
|
|
4
|
+
* `window` alone is not the test: React Native defines it too, with no
|
|
5
|
+
* `location` or `history`, and a fetch that sends no Origin while still
|
|
6
|
+
* replaying the session cookie from its native jar. Taking it for a browser
|
|
7
|
+
* meant no Origin on a cookie-carrying mutation (`403 Missing or null Origin`
|
|
8
|
+
* on sign-out) and a crash reading `window.location.href`. A page has a
|
|
9
|
+
* `document`; React Native, Node and Deno do not.
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export function isBrowser() {
|
|
13
|
+
return typeof window !== 'undefined' && typeof document !== 'undefined';
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/utils/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,QAAQ,KAAK,WAAW,CAAC;AAC1E,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test-only client: run a query as a specific user, or as nobody.
|
|
3
|
+
*
|
|
4
|
+
* A row level security policy is a claim about who can see what, and the only
|
|
5
|
+
* honest way to check it is to issue the same query as several callers and
|
|
6
|
+
* compare the results. Without this, doing that in a test means creating users
|
|
7
|
+
* and signing in as each of them through the real auth flow, which is slow
|
|
8
|
+
* enough that most policies end up untested and wrong.
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* const asAlice = createTestClient(url, secretKey, { as: alice.id })
|
|
12
|
+
* const asBob = createTestClient(url, secretKey, { as: bob.id })
|
|
13
|
+
* const asAnon = createTestClient(url, secretKey, { as: 'anon' })
|
|
14
|
+
*
|
|
15
|
+
* expect((await asAlice.from('notes').select('*')).data).toHaveLength(1)
|
|
16
|
+
* expect((await asBob.from('notes').select('*')).data).toHaveLength(0)
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* This is a server-side tool. It needs the project's SECRET key, which bypasses
|
|
20
|
+
* RLS and must never reach a browser, so importing this module from application
|
|
21
|
+
* code is a mistake even though nothing here can stop you. The server refuses
|
|
22
|
+
* the impersonation header outright when the key is anything else, so the worst
|
|
23
|
+
* case is a failed request rather than a privilege escalation.
|
|
24
|
+
*/
|
|
25
|
+
import { MotherbaseClient } from '../index.js';
|
|
26
|
+
import type { ClientOptions } from '../types.js';
|
|
27
|
+
import type { GenericDatabase, GenericSchema, DefaultSchemaName, SchemaOf } from '../database/types.js';
|
|
28
|
+
/** The header the server reads. Exported so a raw fetch can do the same thing. */
|
|
29
|
+
export declare const IMPERSONATE_HEADER = "x-motherbase-impersonate";
|
|
30
|
+
export interface TestClientOptions extends ClientOptions {
|
|
31
|
+
/**
|
|
32
|
+
* Who to run as: a user id, `'anon'` for a signed-out visitor, or
|
|
33
|
+
* `'service_role'` to keep the secret key's own bypass-everything identity.
|
|
34
|
+
*/
|
|
35
|
+
as: string;
|
|
36
|
+
}
|
|
37
|
+
export declare function createTestClient<Database = GenericDatabase, SchemaName = DefaultSchemaName<Database>, Schema extends GenericSchema = SchemaOf<Database, SchemaName>>(url: string, secretKey: string, options: TestClientOptions): MotherbaseClient<Database, SchemaName, Schema>;
|
|
38
|
+
//# sourceMappingURL=testing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../src/utils/testing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,EAAgB,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAExG,kFAAkF;AAClF,eAAO,MAAM,kBAAkB,6BAA6B,CAAC;AAE7D,MAAM,WAAW,iBAAkB,SAAQ,aAAa;IACtD;;;OAGG;IACH,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,wBAAgB,gBAAgB,CAC9B,QAAQ,GAAG,eAAe,EAC1B,UAAU,GAAG,iBAAiB,CAAC,QAAQ,CAAC,EACxC,MAAM,SAAS,aAAa,GAAG,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC,EAE7D,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,iBAAiB,GACzB,gBAAgB,CAAC,QAAQ,EAAE,UAAU,EAAE,MAAM,CAAC,CAuBhD"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test-only client: run a query as a specific user, or as nobody.
|
|
3
|
+
*
|
|
4
|
+
* A row level security policy is a claim about who can see what, and the only
|
|
5
|
+
* honest way to check it is to issue the same query as several callers and
|
|
6
|
+
* compare the results. Without this, doing that in a test means creating users
|
|
7
|
+
* and signing in as each of them through the real auth flow, which is slow
|
|
8
|
+
* enough that most policies end up untested and wrong.
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* const asAlice = createTestClient(url, secretKey, { as: alice.id })
|
|
12
|
+
* const asBob = createTestClient(url, secretKey, { as: bob.id })
|
|
13
|
+
* const asAnon = createTestClient(url, secretKey, { as: 'anon' })
|
|
14
|
+
*
|
|
15
|
+
* expect((await asAlice.from('notes').select('*')).data).toHaveLength(1)
|
|
16
|
+
* expect((await asBob.from('notes').select('*')).data).toHaveLength(0)
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* This is a server-side tool. It needs the project's SECRET key, which bypasses
|
|
20
|
+
* RLS and must never reach a browser, so importing this module from application
|
|
21
|
+
* code is a mistake even though nothing here can stop you. The server refuses
|
|
22
|
+
* the impersonation header outright when the key is anything else, so the worst
|
|
23
|
+
* case is a failed request rather than a privilege escalation.
|
|
24
|
+
*/
|
|
25
|
+
import { createClient } from '../index.js';
|
|
26
|
+
import { memoryStorage } from '../auth/session.js';
|
|
27
|
+
/** The header the server reads. Exported so a raw fetch can do the same thing. */
|
|
28
|
+
export const IMPERSONATE_HEADER = 'x-motherbase-impersonate';
|
|
29
|
+
export function createTestClient(url, secretKey, options) {
|
|
30
|
+
if (!secretKey?.startsWith('mb_secret_')) {
|
|
31
|
+
// Fail here rather than at the first query: a test that ran as the wrong
|
|
32
|
+
// caller and passed is the failure this whole module exists to prevent.
|
|
33
|
+
throw new Error('createTestClient needs the project secret key (mb_secret_…). A publishable key cannot impersonate, '
|
|
34
|
+
+ 'and the server refuses the header with a 403.');
|
|
35
|
+
}
|
|
36
|
+
const { as, ...rest } = options;
|
|
37
|
+
return createClient(url, secretKey, {
|
|
38
|
+
// A fresh in-memory session per client, so two clients in one test file
|
|
39
|
+
// cannot share (or clobber) each other's stored session.
|
|
40
|
+
storage: memoryStorage(),
|
|
41
|
+
...rest,
|
|
42
|
+
headers: {
|
|
43
|
+
...rest.headers,
|
|
44
|
+
// `service_role` is the absence of impersonation: the secret key already
|
|
45
|
+
// is service_role, so sending a header would only add a lookup.
|
|
46
|
+
...(as === 'service_role' ? {} : { [IMPERSONATE_HEADER]: as }),
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=testing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing.js","sourceRoot":"","sources":["../../src/utils/testing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,EAAE,YAAY,EAAoB,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAInD,kFAAkF;AAClF,MAAM,CAAC,MAAM,kBAAkB,GAAG,0BAA0B,CAAC;AAU7D,MAAM,UAAU,gBAAgB,CAK9B,GAAW,EACX,SAAiB,EACjB,OAA0B;IAE1B,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACzC,yEAAyE;QACzE,wEAAwE;QACxE,MAAM,IAAI,KAAK,CACb,qGAAqG;cACjG,+CAA+C,CACpD,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IAChC,OAAO,YAAY,CAA+B,GAAG,EAAE,SAAS,EAAE;QAChE,wEAAwE;QACxE,yDAAyD;QACzD,OAAO,EAAE,aAAa,EAAE;QACxB,GAAG,IAAI;QACP,OAAO,EAAE;YACP,GAAG,IAAI,CAAC,OAAO;YACf,yEAAyE;YACzE,gEAAgE;YAChE,GAAG,CAAC,EAAE,KAAK,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,kBAAkB,CAAC,EAAE,EAAE,EAAE,CAAC;SAC/D;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"warn.d.ts","sourceRoot":"","sources":["../../src/utils/warn.ts"],"names":[],"mappings":"AAiBA,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAKzF"}
|