@@ -13,17 +13,27 @@ import { Code } from "@/components/Code"
13
13
### Installation
14
14
15
15
```bash npm2yarn
16
-
npm install @auth/surrealdb-adapter surrealdb.js
16
+
npm install @auth/surrealdb-adapter surrealdb
17
17
```
18
18
19
19
### Environment Variables
20
20
21
+
A valid authentication combination must be provided. The following authentication combinations are supported:
22
+
23
+
- RootAuth
24
+
- NamespaceAuth
25
+
- DatabaseAuth
26
+
- ScopeAuth
27
+
21
28
```sh
22
-
AUTH_SURREALDB_CONNECTION
23
-
AUTH_SURREALDB_USERNAME
24
-
AUTH_SURREALDB_PASSWORD
25
-
AUTH_SURREALDB_NS
26
-
AUTH_SURREALDB_DB
29
+
AUTH_SURREAL_URL (required)
30
+
AUTH_SURREAL_NS
31
+
AUTH_SURREAL_DB
32
+
AUTH_SURREAL_USER
33
+
AUTH_SURREAL_PW
34
+
AUTH_SURREAL_SCOPE
35
+
SURREAL_NS (required when using RootAuth or NamespaceAuth)
36
+
SURREAL_DB (required when using RootAuth or NamespaceAuth)
27
37
```
28
38
29
39
### Configuration
@@ -97,84 +107,172 @@ app.use(
97
107
98
108
The SurrealDB adapter does not handle connections automatically, so you will have to make sure that you pass the Adapter a `SurrealDBClient` that is connected already. Below you can see an example how to do this.
99
109
110
+
### Utils File
111
+
112
+
```ts filename="./lib/surrealdb_utils.ts"
113
+
import type { ConnectOptions, AnyAuth } from "surrealdb"
114
+
import { Surreal, ConnectionStatus } from "surrealdb"
115
+
116
+
/**
117
+
* Maintains a single instance of surrealdb.
118
+
* Automatically reconnects unless options.reconnect is set to false manually.
119
+
*/
120
+
export class MySurreal {
121
+
// A single instantiation of a surreal connection
122
+
private _surrealdb: Surreal | undefined
123
+
private _url: string | URL
124
+
private _opts: ConnectOptions | undefined
125
+
126
+
constructor(
127
+
url: Parameters<InstanceType<typeof Surreal>["connect"]>[0],
128
+
opts?: ConnectOptions
129
+
) {
130
+
this._url = url
131
+
if (opts && opts.reconnect === undefined) {
132
+
opts.reconnect = true
133
+
}
134
+
this._opts = opts
135
+
}
136
+
137
+
async surrealdb(): Promise<Surreal> {
138
+
// Init Surreal
139
+
if (!this._surrealdb) {
140
+
this._surrealdb = new Surreal()
141
+
}
142
+
143
+
if (this._surrealdb.status == ConnectionStatus.Connected) {
144
+
return this._surrealdb
145
+
} else if (this._surrealdb.status == ConnectionStatus.Disconnected) {
146
+
try {
147
+
// Connect as a database user
148
+
await this._surrealdb.connect(this._url, this._opts)
149
+
if (process.env.NODE_ENV === "development") {
150
+
const str = this.toConnectionString(
151
+
this._surrealdb.status,
152
+
this._opts
153
+
)
154
+
console.info(str)
155
+
}
156
+
} catch (error) {
157
+
if (error instanceof Error) throw error
158
+
throw new Error(error as unknown as string)
159
+
}
160
+
}
161
+
return this._surrealdb
162
+
}
163
+
164
+
private toConnectionString(status: ConnectionStatus, opts?: ConnectOptions) {
165
+
let str = `${status}`
166
+
const auth = opts?.auth
167
+
168
+
if (auth && typeof auth !== "string") {
169
+
if ("username" in auth) {
170
+
str += ` as ${auth.username}`
171
+
}
172
+
if ("database" in auth && "namespace" in auth) {
173
+
str += ` for ${auth.namespace} ${auth.database}`
174
+
} else if ("namespace" in auth) {
175
+
str += ` for ${auth.namespace}`
176
+
} else if ("database" in auth) {
177
+
str += ` for ${auth.database}`
178
+
}
179
+
}
180
+
return str
181
+
}
182
+
}
183
+
184
+
/**
185
+
* Converts environment variables to an AnyAuth type
186
+
* to connect with the database
187
+
* @param param0 - environment variables
188
+
* @returns {RootAuth | NamespaceAuth | DatabaseAuth | ScopeAuth}
189
+
*/
190
+
export function toAnyAuth({
191
+
username,
192
+
password,
193
+
namespace,
194
+
database,
195
+
scope,
196
+
}: Record<string, string | undefined>) {
197
+
let auth: AnyAuth
198
+
if (username && password && namespace && database) {
199
+
auth = {
200
+
database,
201
+
namespace,
202
+
username,
203
+
password,
204
+
}
205
+
} else if (username && password && namespace) {
206
+
auth = {
207
+
namespace,
208
+
username,
209
+
password,
210
+
}
211
+
} else if (username && password) {
212
+
auth = {
213
+
username,
214
+
password,
215
+
}
216
+
} else if (scope) {
217
+
auth = {
218
+
namespace,
219
+
database,
220
+
username,
221
+
password,
222
+
scope,
223
+
}
224
+
} else {
225
+
throw new Error("unsupported any auth configuration")
226
+
}
227
+
return auth
228
+
}
229
+
```
230
+
100
231
### Authorization
101
232
102
-
#### Option 1 – Using RPC:
233
+
The clientPromise provides a connection to the database. You could use any connect option you wish. For quick setup, use the DatabaseAuth method. For best security, we recommend creating a Record Access method if you know how to properly setup access table permissions.
103
234
104
235
```ts filename="./lib/surrealdb.ts"
105
-
import { Surreal } from "surrealdb.js"
106
-
107
-
const connectionString = process.env.AUTH_SURREALDB_CONNECTION
108
-
const username = process.env.AUTH_SURREALDB_USERNAME
109
-
const password = process.env.AUTH_SURREALDB_PASSWORD
110
-
const namespace = process.env.AUTH_SURREALDB_NAMESPACE
111
-
const database = process.env.AUTH_SURREALDB_DATABASE
112
-
if (!connectionString || !username || !password || !namespace || !database) {
113
-
throw new Error(
114
-
"SurrealDB connection string, username, password, namespace, and database are required"
115
-
)
116
-
}
236
+
import { type Surreal } from "surrealdb"
237
+
import { handleDisconnect, MySurreal, toAnyAuth } from "./lib/surrealdb_utils"
117
238
118
239
const clientPromise = new Promise<Surreal>(async (resolve, reject) => {
119
-
const db = new Surreal()
120
240
try {
121
-
await db.connect(`${connectionString}/rpc`, {
241
+
const {
242
+
AUTH_SURREAL_URL: auth_url,
243
+
AUTH_SURREAL_NS: auth_ns,
244
+
AUTH_SURREAL_DB: auth_db,
245
+
AUTH_SURREAL_USER: auth_user,
246
+
AUTH_SURREAL_PW: auth_pw,
247
+
AUTH_SURREAL_SCOPE: auth_scope,
248
+
SURREAL_NS: namespace,
249
+
SURREAL_DB: database,
250
+
} = process.env
251
+
if (!auth_url) throw new Error("required auth_url")
252
+
const auth = toAnyAuth({
253
+
namespace: auth_ns,
254
+
database: auth_db,
255
+
username: auth_user,
256
+
password: auth_pw,
257
+
scope: auth_scope,
258
+
})
259
+
const surreal = new MySurreal(auth_url, {
122
260
namespace,
123
261
database,
124
-
auth: {
125
-
username,
126
-
password,
127
-
},
262
+
auth,
128
263
})
264
+
const db = await surreal.surrealdb()
129
265
resolve(db)
130
266
} catch (e) {
131
267
reject(e)
132
268
}
133
269
})
134
-
135
-
// Export a module-scoped Promise<Surreal>. By doing this in a
136
-
// separate module, the client can be shared across functions.
137
-
export default clientPromise
138
270
```
139
271
140
-
#### Option 2 – Using HTTP:
272
+
#### HTTP ENGINE
141
273
142
-
Useful in serverless environments like Vercel.
274
+
With this configuration, we can use the database's http endpoint. Thus, the `AUTH_SURREAL_URL` should begin with `http` or `https`.
143
275
144
-
```ts filename="./lib/surrealdb.ts"
145
-
import { ExperimentalSurrealHTTP } from "surrealdb.js"
146
-
147
-
const connectionString = process.env.AUTH_SURREALDB_CONNECTION
148
-
const username = process.env.AUTH_SURREALDB_USERNAME
149
-
const password = process.env.AUTH_SURREALDB_PASSWORD
150
-
const namespace = process.env.AUTH_SURREALDB_NAMESPACE
151
-
const database = process.env.AUTH_SURREALDB_DATABASE
152
-
if (!connectionString || !username || !password || !namespace || !database) {
153
-
throw new Error(
154
-
"SurrealDB connection string, username, password, namespace, and database are required"
155
-
)
156
-
}
276
+
#### Websocket ENGINE
157
277
158
-
const clientPromise = new Promise<ExperimentalSurrealHTTP<typeof fetch>>(
159
-
async (resolve, reject) => {
160
-
try {
161
-
const db = new ExperimentalSurrealHTTP(connectionString, {
162
-
fetch,
163
-
namespace,
164
-
database,
165
-
auth: {
166
-
username,
167
-
password,
168
-
},
169
-
})
170
-
resolve(db)
171
-
} catch (e) {
172
-
reject(e)
173
-
}
174
-
}
175
-
)
176
-
177
-
// Export a module-scoped Promise<Surreal>. By doing this in a
178
-
// separate module, the client can be shared across functions.
179
-
export default clientPromise
180
-
```
278
+
With this configuration, we can use the database's websocket endpoint. Thus, the `AUTH_SURREAL_URL` should begin with `ws` or `wss`.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4