@buildbase/sdk 0.0.89 → 0.0.90
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/AGENTS.md +7 -3
- package/CHANGELOG.md +505 -0
- package/README.md +120 -3
- package/dist/cli.mjs +1 -1
- package/dist/css/styles.css +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1350 -11
- package/dist/index.mjs +1 -1
- package/dist/mcp/index.cjs +1 -1
- package/dist/mcp/index.d.ts +120 -2
- package/dist/mcp/index.mjs +1 -1
- package/dist/react/chunks/SettingsDialog-BVyV5Zfm.mjs +2 -0
- package/dist/react/chunks/SettingsDialog-Ch8X6WXy.cjs +2 -0
- package/dist/react/chunks/{SubscriptionDialog-B8FTFRtp.cjs → SubscriptionDialog-CGIvMKpT.cjs} +1 -1
- package/dist/react/chunks/SubscriptionDialog-g0LwHhbe.mjs +2 -0
- package/dist/react/chunks/ar-3aqWucom.mjs +2 -0
- package/dist/react/chunks/ar-DQVB89r8.cjs +2 -0
- package/dist/react/chunks/de-DO10bhnU.cjs +2 -0
- package/dist/react/chunks/de-HXQk5D6k.mjs +2 -0
- package/dist/react/chunks/es-BZsmhBN3.mjs +2 -0
- package/dist/react/chunks/es-Cxg-qhUh.cjs +2 -0
- package/dist/react/chunks/fr-COCMy3vW.cjs +2 -0
- package/dist/react/chunks/fr-rdnNHzxy.mjs +2 -0
- package/dist/react/chunks/hi-BB0Z-Dgn.cjs +2 -0
- package/dist/react/chunks/hi-t3RH7ITu.mjs +2 -0
- package/dist/react/chunks/ja-CDyla2g0.mjs +2 -0
- package/dist/react/chunks/ja-D92JgUlk.cjs +2 -0
- package/dist/react/chunks/react-DTq7A_PT.mjs +2 -0
- package/dist/react/chunks/react-DeapSbq6.cjs +2 -0
- package/dist/react/chunks/zh-C5HABZZV.mjs +2 -0
- package/dist/react/chunks/zh-DK2yA5wB.cjs +2 -0
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.d.ts +1517 -14
- package/dist/react/index.mjs +1 -1
- package/docs/ERROR_CODES.md +218 -0
- package/docs/THEMING.md +89 -21
- package/docs/UI-CONFIG.md +23 -4
- package/docs/USER-IMPORT.md +320 -0
- package/package.json +2 -1
- package/dist/react/chunks/SettingsDialog-CKVE1PpH.mjs +0 -2
- package/dist/react/chunks/SettingsDialog-DrDmxFEj.cjs +0 -2
- package/dist/react/chunks/SubscriptionDialog-UN7o9Hqb.mjs +0 -2
- package/dist/react/chunks/ar-B2l90OZJ.cjs +0 -2
- package/dist/react/chunks/ar-DVVNZhXD.mjs +0 -2
- package/dist/react/chunks/de-BspJtvAC.mjs +0 -2
- package/dist/react/chunks/de-dURUqbl0.cjs +0 -2
- package/dist/react/chunks/es-DArjREi5.cjs +0 -2
- package/dist/react/chunks/es-vu4BmI3g.mjs +0 -2
- package/dist/react/chunks/fr-DVm5WCvZ.mjs +0 -2
- package/dist/react/chunks/fr-DhYDaYrX.cjs +0 -2
- package/dist/react/chunks/hi-C_nv_c1T.cjs +0 -2
- package/dist/react/chunks/hi-VW8xCj_K.mjs +0 -2
- package/dist/react/chunks/ja-C-b88dvw.mjs +0 -2
- package/dist/react/chunks/ja-CqtDkLHr.cjs +0 -2
- package/dist/react/chunks/react-CHivaJhA.mjs +0 -2
- package/dist/react/chunks/react-Ch_Suxxy.cjs +0 -2
- package/dist/react/chunks/zh-D1yfhUf0.mjs +0 -2
- package/dist/react/chunks/zh-D_tMpsNt.cjs +0 -2
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
# Importing users: `buildbase import`
|
|
2
|
+
|
|
3
|
+
Move your users from Clerk, Auth0, Firebase or Supabase into BuildBase with
|
|
4
|
+
one command. It reads the vendor's own export, converts each user, and sends
|
|
5
|
+
them to your BuildBase app in batches of 500:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
BUILDBASE_SERVER_URL=https://api.console.buildbase.app \
|
|
9
|
+
BUILDBASE_API_TOKEN=$BUILDBASE_API_TOKEN \
|
|
10
|
+
npx buildbase import --from clerk users.csv --dry-run
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Run it with `--dry-run` first: it converts the whole file, prints the first
|
|
14
|
+
three users as they would be sent (hashes redacted) and every record it would
|
|
15
|
+
leave out, and sends nothing. Then run it again without the flag.
|
|
16
|
+
|
|
17
|
+
## What carries over
|
|
18
|
+
|
|
19
|
+
| From the old system | In BuildBase |
|
|
20
|
+
| ------------------------------------------------------ | -------------------------------------------------------------------------- |
|
|
21
|
+
| Email address | The user's email. A record without one is not imported |
|
|
22
|
+
| Whether the address was verified | `emailVerified` |
|
|
23
|
+
| Name | The user's name |
|
|
24
|
+
| The user's id | `externalId` on the user, and on `useSaaSAuth().user` |
|
|
25
|
+
| Phone number, and whether it was verified | The user's phone (see [Phone numbers](#phone-numbers)) |
|
|
26
|
+
| Password hash, when we can check it | Their old password keeps working (see [Password hashes](#password-hashes)) |
|
|
27
|
+
| Google, GitHub, Microsoft, Apple and LinkedIn sign-ins | Linked accounts: signing in with the same provider finds the same user |
|
|
28
|
+
|
|
29
|
+
Not carried over: two-step sign-in secrets, metadata, and sign-ins with
|
|
30
|
+
providers BuildBase does not have (Facebook, X, Discord and others), each of
|
|
31
|
+
which is reported as a warning. Imported users get no welcome or verification
|
|
32
|
+
email. Each one fires the `user.imported` webhook, not `user.registered`, with
|
|
33
|
+
`source` set to the `--from` value, and counts toward your plan's end-user
|
|
34
|
+
limit; users past the limit come back as failed rows with `limit_reached`. A
|
|
35
|
+
user imported with a phone number also fires `user.phone_added`.
|
|
36
|
+
|
|
37
|
+
Microsoft, Apple and LinkedIn give each app (Apple: each team) its own account
|
|
38
|
+
ids, so an imported Microsoft, Apple or LinkedIn sign-in matches only while
|
|
39
|
+
your BuildBase app uses the same Microsoft app registration, Apple team or
|
|
40
|
+
LinkedIn app as the old system did. The server's report says so after the
|
|
41
|
+
totals when the export has any, one sentence per provider, and `--dry-run`
|
|
42
|
+
says the same sentences before anything is sent.
|
|
43
|
+
|
|
44
|
+
## Options
|
|
45
|
+
|
|
46
|
+
| Option | What it does |
|
|
47
|
+
| --------------------------- | ------------------------------------------------------------------------------------------------------------ |
|
|
48
|
+
| `--from <source>` | `clerk`, `auth0`, `firebase` or `supabase` (required) |
|
|
49
|
+
| `<file>` | The export: CSV, JSON or NDJSON, gzipped or not |
|
|
50
|
+
| `--passwords <file>` | Auth0: the password hash export from Auth0 support. Clerk: the dashboard CSV, beside API JSON |
|
|
51
|
+
| `--overwrite` | Update users that already exist instead of skipping them |
|
|
52
|
+
| `--dry-run` | Convert and print the first users; send nothing. Needs no token |
|
|
53
|
+
| `--server-url <url>` | Overrides `BUILDBASE_SERVER_URL`, as for `content pull` |
|
|
54
|
+
| `--signer-key <base64>` | Firebase only: `base64_signer_key`. Prefer `BUILDBASE_FIREBASE_SIGNER_KEY`, which stays out of shell history |
|
|
55
|
+
| `--salt-separator <base64>` | Firebase only: `base64_salt_separator` |
|
|
56
|
+
| `--rounds <n>` | Firebase only: `rounds` |
|
|
57
|
+
| `--mem-cost <n>` | Firebase only: `mem_cost` |
|
|
58
|
+
|
|
59
|
+
| Environment | What it is |
|
|
60
|
+
| ---------------------- | ---------------------------------------------------------------------------- |
|
|
61
|
+
| `BUILDBASE_API_TOKEN` | An org API token (console, Settings, API tokens) whose role can create users |
|
|
62
|
+
| `BUILDBASE_SERVER_URL` | Your BuildBase API, for example `https://api.console.buildbase.app` |
|
|
63
|
+
|
|
64
|
+
## What it prints
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
buildbase: read 1204 records from users.json (clerk): 1201 to import
|
|
68
|
+
buildbase: batch 1 of 3 done
|
|
69
|
+
buildbase: batch 2 of 3 done
|
|
70
|
+
buildbase: batch 3 of 3 done
|
|
71
|
+
|
|
72
|
+
buildbase: 1180 created, 0 updated, 15 skipped, 6 failed (1201 users sent, 3 not sent)
|
|
73
|
+
note: Microsoft user ids are per app registration: imported Microsoft links match only if ...
|
|
74
|
+
|
|
75
|
+
Not sent:
|
|
76
|
+
record 212: invalid_email: no email address, so this user is not imported
|
|
77
|
+
...
|
|
78
|
+
|
|
79
|
+
Failed:
|
|
80
|
+
record 17 (ada@example.com): limit_reached: Your plan allows 1,000 end users.
|
|
81
|
+
...
|
|
82
|
+
|
|
83
|
+
Warnings:
|
|
84
|
+
record 5 (bob@example.com): unsupported_hasher: Clerk's md5 hashes cannot be imported, ...
|
|
85
|
+
record 9 (cy@example.com): The google sign-in belongs to another user and was skipped.
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
A record number is the user's place in your export, counting from 1: the row
|
|
89
|
+
after the header in a CSV, the line in NDJSON, the item in a JSON array.
|
|
90
|
+
`Not sent` lists the users the command left out before sending (no email, a
|
|
91
|
+
plaintext password, deleted upstream), the "not sent" of the totals, and
|
|
92
|
+
`--dry-run` lists the same users under the same heading. `Failed` lists the
|
|
93
|
+
users the server refused.
|
|
94
|
+
`Warnings` lists users that went in without something, whatever their status:
|
|
95
|
+
a password hash that cannot be checked, a sign-in with a provider BuildBase
|
|
96
|
+
does not have, a sign-in that already belongs to another user, a phone number
|
|
97
|
+
that is not E.164 or already belongs to another user, or a password
|
|
98
|
+
`--overwrite` did not apply. Skipped users (`exists`) were already there and
|
|
99
|
+
are not listed. Notes about the whole run (`note:`) are printed once, after
|
|
100
|
+
the totals.
|
|
101
|
+
|
|
102
|
+
The command exits 0 when every user went in or was skipped, 1 when any failed
|
|
103
|
+
or a request was refused, and 2 when it could not start (a bad flag, a file it
|
|
104
|
+
cannot read, no token).
|
|
105
|
+
|
|
106
|
+
**Running it again is safe.** Users that already exist are skipped, matched by
|
|
107
|
+
email and then by `externalId`, so a run that stopped half way (a network
|
|
108
|
+
error, a refused batch) is finished by running the same command again. With
|
|
109
|
+
`--overwrite` they are updated instead. Batches are never retried on their own.
|
|
110
|
+
|
|
111
|
+
## Phone numbers
|
|
112
|
+
|
|
113
|
+
A user's phone number is imported as E.164 (`+14155550123`), with
|
|
114
|
+
`phoneVerified` true when the old system had proven it with a code. A verified
|
|
115
|
+
number counts as a way to sign in where your app offers phone sign-in, and can
|
|
116
|
+
receive text message codes for two-step sign-in. Only a value already in E.164
|
|
117
|
+
form is sent: any other (`(415) 555-0123`, a number without its country code)
|
|
118
|
+
is left out with an `invalid_phone` warning, and the user is imported without
|
|
119
|
+
it. One number belongs to one account, so a number another user already has is
|
|
120
|
+
skipped by the server with a warning, and that user is imported without it
|
|
121
|
+
too.
|
|
122
|
+
|
|
123
|
+
| Source | Where the number comes from | Verified when |
|
|
124
|
+
| -------- | -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
|
|
125
|
+
| Clerk | API: the `phone_numbers[]` entry `primary_phone_number_id` names, or the first. CSV: `primary_phone_number`, or the first listed | API: `verification.status` is `verified`. CSV: it is in `verified_phone_numbers` |
|
|
126
|
+
| Auth0 | `phone_number` | `phone_verified` is true |
|
|
127
|
+
| Firebase | `phoneNumber` | Always: Firebase sets it through phone sign-in, which proves it |
|
|
128
|
+
| Supabase | `phone`, which Supabase keeps without its `+`; the import adds it back | `phone_confirmed_at` is set |
|
|
129
|
+
|
|
130
|
+
## Password hashes
|
|
131
|
+
|
|
132
|
+
Imported users sign in with their old password. The first time they do,
|
|
133
|
+
BuildBase checks it against the imported hash and, when it matches, stores
|
|
134
|
+
its own bcrypt hash in its place, so the old hash is used once at most.
|
|
135
|
+
|
|
136
|
+
| Hasher | Comes from |
|
|
137
|
+
| ----------------------------- | ----------------------------------------------------------------------------------------------- |
|
|
138
|
+
| bcrypt | Clerk `bcrypt`, Auth0's hash export, Supabase `encrypted_password` |
|
|
139
|
+
| argon2id, argon2i | Clerk `argon2id` and `argon2i` (PHC strings, `$argon2id$v=19$m=...`) |
|
|
140
|
+
| pbkdf2_sha256 (Django's form) | Clerk `pbkdf2_sha256_django`, and Clerk `pbkdf2_sha256` whose base64 salt decodes to plain text |
|
|
141
|
+
| Firebase scrypt | Firebase's export with the project's parameters, and Clerk `scrypt_firebase` |
|
|
142
|
+
|
|
143
|
+
Any other hasher (Clerk's `md5`, `sha256`, `phpass`, `bcrypt_sha256_django`,
|
|
144
|
+
`scrypt_werkzeug` and the rest) imports the user without a password, with a
|
|
145
|
+
warning; they set one with "Forgot password?" or sign in another way. A value
|
|
146
|
+
in a hash column that does not have its hasher's shape is treated the same
|
|
147
|
+
way and never sent.
|
|
148
|
+
|
|
149
|
+
**A plaintext password is never sent.** A record that carries one (a
|
|
150
|
+
`password` field) is left out entirely and listed as failed with
|
|
151
|
+
`plaintext_password`; remove the column from the export and run again.
|
|
152
|
+
|
|
153
|
+
## Clerk
|
|
154
|
+
|
|
155
|
+
Clerk splits what you need across two exports: the dashboard CSV has the
|
|
156
|
+
password hashes and no social sign-ins, and the Backend API has the social
|
|
157
|
+
sign-ins and no hashes. Use whichever you need, or both.
|
|
158
|
+
|
|
159
|
+
**Passwords only.** In the Clerk Dashboard, open your instance's
|
|
160
|
+
**Settings**, then **User exports**, choose **Export users**, and download the
|
|
161
|
+
CSV when it is ready. Then:
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
npx buildbase import --from clerk clerk-export.csv
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
It reads `id`, `first_name`, `last_name`, `username` (when there is no name),
|
|
168
|
+
`primary_email_address`, `verified_email_addresses` (the primary address is
|
|
169
|
+
verified when it appears there), `primary_phone_number`,
|
|
170
|
+
`verified_phone_numbers` and `unverified_phone_numbers` (with no primary
|
|
171
|
+
number, the first verified one, then the first unverified one),
|
|
172
|
+
`password_digest` and `password_hasher`.
|
|
173
|
+
|
|
174
|
+
**With social sign-ins.** Save every user from the Backend API as one JSON
|
|
175
|
+
array, then pass the dashboard CSV with `--passwords` to keep the hashes:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
for offset in 0 500 1000 1500; do # one page per 500 users
|
|
179
|
+
curl -s "https://api.clerk.com/v1/users?limit=500&offset=$offset" \
|
|
180
|
+
-H "Authorization: Bearer $CLERK_SECRET_KEY"
|
|
181
|
+
done | jq -s 'add' > clerk-users.json
|
|
182
|
+
|
|
183
|
+
npx buildbase import --from clerk clerk-users.json --passwords clerk-export.csv
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
From the API it reads `id`, `first_name`, `last_name`,
|
|
187
|
+
`primary_email_address_id` and `email_addresses[]` (`email_address`, and
|
|
188
|
+
`verification.status` of `verified`), `primary_phone_number_id` and
|
|
189
|
+
`phone_numbers[]` (`phone_number`, and `verification.status` of `verified`),
|
|
190
|
+
and `external_accounts[]` (`provider` and `provider_user_id`). Hashes from the
|
|
191
|
+
CSV are matched by user id, then by email. Providers: `oauth_google`,
|
|
192
|
+
`oauth_github`, `oauth_microsoft`, `oauth_apple`, and `oauth_linkedin_oidc` or
|
|
193
|
+
`oauth_linkedin`.
|
|
194
|
+
|
|
195
|
+
Check against your export: Clerk does not document how
|
|
196
|
+
`verified_email_addresses` and `verified_phone_numbers` separate several values
|
|
197
|
+
(any address inside the cell is read, and numbers split on commas, semicolons
|
|
198
|
+
or pipes), or whether a dashboard CSV can carry external accounts. A
|
|
199
|
+
legacy `oauth_linkedin` account id may not be the id LinkedIn's OpenID sign-in
|
|
200
|
+
gives the same person, in which case that link will not match.
|
|
201
|
+
|
|
202
|
+
## Auth0
|
|
203
|
+
|
|
204
|
+
**Users.** Auth0's bulk export does not include password hashes. Start a
|
|
205
|
+
users-exports job with the Management API (or the User Import / Export
|
|
206
|
+
extension), asking for the fields below as JSON, and download the file at the
|
|
207
|
+
job's `location` once it completes. It is gzipped; pass it as it is.
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
curl -X POST "https://$AUTH0_DOMAIN/api/v2/jobs/users-exports" \
|
|
211
|
+
-H "Authorization: Bearer $AUTH0_MANAGEMENT_TOKEN" \
|
|
212
|
+
-H "Content-Type: application/json" \
|
|
213
|
+
-d '{"format":"json","fields":[{"name":"user_id"},{"name":"email"},{"name":"email_verified"},{"name":"name"},{"name":"given_name"},{"name":"family_name"},{"name":"phone_number"},{"name":"phone_verified"},{"name":"identities"}]}'
|
|
214
|
+
# then GET /api/v2/jobs/<id> until status is "completed", and download its location
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
It reads `user_id`, `email`, `email_verified`, `name` (Auth0 copies the email
|
|
218
|
+
into `name` for a database user, which is not imported as a name),
|
|
219
|
+
`given_name`, `family_name`, `phone_number`, `phone_verified`, and
|
|
220
|
+
`identities[]` (`provider` and `user_id`).
|
|
221
|
+
Providers: `google-oauth2`, `github`, `windowslive` (Microsoft), `linkedin` and
|
|
222
|
+
`apple`. `auth0`, `email` and `sms` are ways to sign in rather than accounts to
|
|
223
|
+
link. Without `identities`, each user's main sign-in still comes from
|
|
224
|
+
`user_id` (`google-oauth2|1100...`).
|
|
225
|
+
|
|
226
|
+
**Password hashes.** Open a ticket with Auth0 support asking for a password
|
|
227
|
+
hash export of your database connections (Auth0 offers it on paid plans and
|
|
228
|
+
sends it PGP-encrypted; decrypt it first). It is NDJSON, one user per line,
|
|
229
|
+
with `_id` (a string or `{ "$oid": "..." }`), `email`, `passwordHash`
|
|
230
|
+
(bcrypt) and, for users from a custom database, `alt_id`. Pass it with
|
|
231
|
+
`--passwords`:
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
npx buildbase import --from auth0 users.json.gz --passwords auth0-hashes.json
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
A hash is matched to a user by `auth0|<alt_id>` or `auth0|<_id>` against the
|
|
238
|
+
bulk export's `user_id`, then by email. A database user with no hash in the
|
|
239
|
+
file imports without a password and is listed as a warning; without
|
|
240
|
+
`--passwords` at all, the command says how many database users that is.
|
|
241
|
+
|
|
242
|
+
Check against your export: whether `{ "name": "identities" }` exports the
|
|
243
|
+
whole array in your tenant (if not, a user's second and later linked sign-ins
|
|
244
|
+
are not carried over), and the exact field names in the hash file Auth0
|
|
245
|
+
support sends.
|
|
246
|
+
|
|
247
|
+
## Firebase
|
|
248
|
+
|
|
249
|
+
1. Export with the Firebase CLI, as JSON (the CSV leaves out Microsoft and
|
|
250
|
+
Apple sign-ins, so the import does not read it). Exporting hashes needs the
|
|
251
|
+
Editor or Owner role on the project.
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
firebase auth:export users.json --format=JSON --project <project-id>
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
2. Copy the project's hash parameters: in the Firebase console, open
|
|
258
|
+
**Authentication**, then **Users**, the menu above the list of users, and
|
|
259
|
+
**Password hash parameters**. They read `base64_signer_key`,
|
|
260
|
+
`base64_salt_separator`, `rounds` and `mem_cost`. Treat the signer key as a
|
|
261
|
+
secret.
|
|
262
|
+
|
|
263
|
+
3. Import, with the signer key in the environment:
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
BUILDBASE_FIREBASE_SIGNER_KEY='<base64_signer_key>' \
|
|
267
|
+
npx buildbase import --from firebase users.json \
|
|
268
|
+
--salt-separator 'Bw==' --rounds 8 --mem-cost 14
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
It reads `users[]`: `localId`, `email`, `emailVerified`, `displayName`,
|
|
272
|
+
`phoneNumber` (imported as verified, since Firebase sets it through phone
|
|
273
|
+
sign-in), `passwordHash` and `salt`, and `providerUserInfo[]` (`providerId`
|
|
274
|
+
and `rawId`). If your own code set numbers with the Admin SDK without a code,
|
|
275
|
+
those are imported as verified too; check before relying on them. Providers:
|
|
276
|
+
`google.com`, `github.com`, `microsoft.com` and `apple.com`; `password` and
|
|
277
|
+
`phone` are not links. An export that holds password hashes is refused without
|
|
278
|
+
all four parameters, rather than importing everyone without a password.
|
|
279
|
+
|
|
280
|
+
Firebase exports only hashes it made with its own scrypt. A user imported into
|
|
281
|
+
Firebase with another hasher, who has not signed in since, comes out with an
|
|
282
|
+
empty hash and imports without a password.
|
|
283
|
+
|
|
284
|
+
## Supabase
|
|
285
|
+
|
|
286
|
+
Export `auth.users` with each user's sign-ins from `auth.identities`, as CSV
|
|
287
|
+
(the SQL editor's download, or `\copy` in psql) or JSON. For a large table use
|
|
288
|
+
psql, which has no row limit:
|
|
289
|
+
|
|
290
|
+
```sql
|
|
291
|
+
select u.id, u.email, u.email_confirmed_at, u.phone, u.phone_confirmed_at,
|
|
292
|
+
u.encrypted_password, u.raw_user_meta_data, u.deleted_at,
|
|
293
|
+
coalesce((select json_agg(json_build_object(
|
|
294
|
+
'provider', i.provider,
|
|
295
|
+
'provider_id', i.provider_id,
|
|
296
|
+
'identity_data', i.identity_data))
|
|
297
|
+
from auth.identities i where i.user_id = u.id), '[]'::json) as identities
|
|
298
|
+
from auth.users u
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
psql "$SUPABASE_DB_URL" -c "\copy (<the query above>) to 'supabase-users.csv' csv header"
|
|
303
|
+
npx buildbase import --from supabase supabase-users.csv
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
For JSON, wrap the query as `select json_agg(t) from (<the query>) t` and save
|
|
307
|
+
the result; the SQL editor's one-cell answer is read too.
|
|
308
|
+
|
|
309
|
+
It reads `id`, `email`, `email_confirmed_at` (verified when set), `phone`
|
|
310
|
+
(stored without its `+`, which is added back) and `phone_confirmed_at`
|
|
311
|
+
(verified when set), `encrypted_password` (bcrypt),
|
|
312
|
+
`raw_user_meta_data.full_name` or `.name`, `deleted_at` (a deleted user is not
|
|
313
|
+
imported), and `identities[]` (`provider`, and `provider_id` or
|
|
314
|
+
`identity_data.sub`). Providers: `google`, `github`, `azure` (Microsoft),
|
|
315
|
+
`linkedin_oidc` or `linkedin`, and `apple`; `email` and `phone` are not links.
|
|
316
|
+
JSON columns may be text in a CSV; both are read.
|
|
317
|
+
|
|
318
|
+
Check against your export: `auth.identities.provider_id` exists on projects
|
|
319
|
+
created or upgraded since late 2023; on an older one, leave it out of the
|
|
320
|
+
query and the id comes from `identity_data.sub`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@buildbase/sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.90",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A SDK for Buildbase",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -123,6 +123,7 @@
|
|
|
123
123
|
"docs/MCP-AND-AGENT-READINESS.md",
|
|
124
124
|
"docs/THEMING.md",
|
|
125
125
|
"docs/UI-CONFIG.md",
|
|
126
|
+
"docs/USER-IMPORT.md",
|
|
126
127
|
"docs/SERVER-CONTENT.md"
|
|
127
128
|
],
|
|
128
129
|
"sideEffects": [
|