or3-provider-sqlite 0.0.4 → 0.0.7
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/README.md +112 -19
- package/dist/module.json +1 -1
- package/dist/runtime/server/admin/adapters/sync-sqlite.js +90 -16
- package/dist/runtime/server/admin/stores/sqlite-store.js +7 -8
- package/dist/runtime/server/auth/sqlite-auth-workspace-store.d.ts +5 -0
- package/dist/runtime/server/auth/sqlite-auth-workspace-store.js +368 -40
- package/dist/runtime/server/connect/sqlite-connect-store.js +19 -5
- package/dist/runtime/server/db/d1-dialect.d.ts +39 -0
- package/dist/runtime/server/db/d1-dialect.js +70 -0
- package/dist/runtime/server/db/d1.d.ts +13 -0
- package/dist/runtime/server/db/d1.js +30 -0
- package/dist/runtime/server/db/kysely.d.ts +53 -15
- package/dist/runtime/server/db/kysely.js +364 -16
- package/dist/runtime/server/db/migrate.js +3 -1
- package/dist/runtime/server/db/migrations/016_connect_runtime_binding.d.ts +4 -0
- package/dist/runtime/server/db/migrations/016_connect_runtime_binding.js +28 -0
- package/dist/runtime/server/db/schema.d.ts +3 -0
- package/dist/runtime/server/plugins/register.js +33 -13
- package/dist/runtime/server/rate-limit/sqlite-provider.d.ts +2 -0
- package/dist/runtime/server/rate-limit/sqlite-provider.js +70 -1
- package/dist/runtime/server/sync/maintenance-state.d.ts +26 -0
- package/dist/runtime/server/sync/maintenance-state.js +66 -0
- package/dist/runtime/server/sync/sqlite-sync-gateway-adapter.d.ts +15 -4
- package/dist/runtime/server/sync/sqlite-sync-gateway-adapter.js +780 -21
- package/dist/runtime/server/webhooks/sqlite-webhook-store.d.ts +3 -2
- package/dist/runtime/server/webhooks/sqlite-webhook-store.js +90 -39
- package/package.json +10 -6
package/README.md
CHANGED
|
@@ -7,6 +7,9 @@ SQLite sync and workspace store provider for OR3 Chat. Provides a lightweight, s
|
|
|
7
7
|
- **AuthWorkspaceStore** (`sqlite`) — user identity mapping, workspace CRUD, role resolution
|
|
8
8
|
- **SyncGatewayAdapter** (`sqlite`) — push/pull sync, consistent materialized snapshot pages, LWW conflict resolution, and cursor tracking
|
|
9
9
|
- **ConnectStore** (`sqlite`) — durable, atomic device enrollment and connected-computer records for OR3 Connect
|
|
10
|
+
- **WebhookStore** (`sqlite`) — durable webhook registrations and delivery logs (local, Bun, and Turso runtimes)
|
|
11
|
+
- **Admin stores** (`sqlite`) — workspace access/lifecycle, workspace settings, user search, and deployment-admin grants (local, Bun, and Turso runtimes)
|
|
12
|
+
- **RateLimitProvider** (`sqlite`) — durable rate-limit counters
|
|
10
13
|
|
|
11
14
|
## Install
|
|
12
15
|
|
|
@@ -20,19 +23,20 @@ Add to your provider module list (e.g. `or3.providers.generated.ts`):
|
|
|
20
23
|
export default ['or3-provider-sqlite/nuxt'];
|
|
21
24
|
```
|
|
22
25
|
|
|
23
|
-
##
|
|
26
|
+
## Native runtimes and configuration
|
|
24
27
|
|
|
25
|
-
|
|
28
|
+
`better-sqlite3` remains the default, so existing local-file installations do
|
|
29
|
+
not need to change. Set `OR3_SQLITE_DRIVER` only when selecting another native
|
|
30
|
+
runtime.
|
|
26
31
|
|
|
27
|
-
|
|
|
32
|
+
| Runtime | `OR3_SQLITE_DRIVER` | Required configuration | Extra install |
|
|
28
33
|
|---|---|---|---|
|
|
29
|
-
|
|
|
30
|
-
|
|
|
31
|
-
|
|
|
32
|
-
| `
|
|
33
|
-
| `OR3_SQLITE_STRICT` | No | `false` | Fail startup if `:memory:` is used |
|
|
34
|
+
| Local Node (default) | `better-sqlite3` | `OR3_SQLITE_DB_PATH` | `better-sqlite3` |
|
|
35
|
+
| Bun | `bun` | `OR3_SQLITE_DB_PATH` | None; uses built-in `bun:sqlite` |
|
|
36
|
+
| Turso/libSQL | `turso` | `OR3_SQLITE_TURSO_URL`, `OR3_SQLITE_TURSO_AUTH_TOKEN` | `libsql` |
|
|
37
|
+
| Cloudflare D1 | `d1` | `OR3_SQLITE_D1_BINDING` (defaults to `DB`) | None; uses the Worker binding |
|
|
34
38
|
|
|
35
|
-
###
|
|
39
|
+
### Local Node (existing default)
|
|
36
40
|
|
|
37
41
|
```bash
|
|
38
42
|
OR3_SQLITE_DB_PATH=/data/or3-sync.db
|
|
@@ -40,15 +44,73 @@ OR3_SQLITE_PRAGMA_JOURNAL_MODE=WAL
|
|
|
40
44
|
OR3_SQLITE_PRAGMA_SYNCHRONOUS=NORMAL
|
|
41
45
|
```
|
|
42
46
|
|
|
43
|
-
|
|
47
|
+
### Bun
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
OR3_SQLITE_DRIVER=bun
|
|
51
|
+
OR3_SQLITE_DB_PATH=/data/or3-sync.db
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Turso/libSQL
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
bun add libsql
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
OR3_SQLITE_DRIVER=turso
|
|
62
|
+
OR3_SQLITE_TURSO_URL=libsql://your-database.turso.io
|
|
63
|
+
OR3_SQLITE_TURSO_AUTH_TOKEN=your-server-only-token
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Cloudflare D1
|
|
67
|
+
|
|
68
|
+
Run the application in a Cloudflare Worker that already has a D1 binding, then
|
|
69
|
+
set its binding name:
|
|
70
|
+
|
|
71
|
+
```toml
|
|
72
|
+
[[d1_databases]]
|
|
73
|
+
binding = "DB"
|
|
74
|
+
database_name = "or3"
|
|
75
|
+
database_id = "your-database-id"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
OR3_SQLITE_DRIVER=d1
|
|
80
|
+
OR3_SQLITE_D1_BINDING=DB
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The provider initializes D1 and applies pending migrations on the first Worker
|
|
84
|
+
request, which keeps D1 I/O inside Cloudflare's request context.
|
|
85
|
+
|
|
86
|
+
For D1, use Workers-compatible auth and storage providers. The local Basic
|
|
87
|
+
Auth and filesystem providers depend on Node-native local storage and are not
|
|
88
|
+
Workers-compatible. OR3 Connect with D1 throws at startup, persistent webhooks
|
|
89
|
+
are not registered (a warning is logged), and server-side admin stores are
|
|
90
|
+
registered with all capabilities disabled; the install wizard reports these
|
|
91
|
+
boundaries explicitly.
|
|
92
|
+
|
|
93
|
+
`OR3_SQLITE_PRAGMA_*`, `OR3_SQLITE_ALLOW_IN_MEMORY`, and
|
|
94
|
+
`OR3_SQLITE_STRICT` apply only to local-file runtimes. The Turso auth token is
|
|
95
|
+
server-only and must not be exposed through public runtime configuration.
|
|
96
|
+
|
|
97
|
+
| Variable | Default | Notes |
|
|
98
|
+
|---|---|---|
|
|
99
|
+
| `OR3_SQLITE_PRAGMA_JOURNAL_MODE` | `WAL` | better-sqlite3 and Bun only |
|
|
100
|
+
| `OR3_SQLITE_PRAGMA_SYNCHRONOUS` | `NORMAL` | better-sqlite3 and Bun only |
|
|
101
|
+
| `OR3_SQLITE_ALLOW_IN_MEMORY` | unset | required to run on `:memory:` outside tests; data is lost on restart |
|
|
102
|
+
| `OR3_SQLITE_STRICT` | unset | forbids `:memory:`; requires `OR3_SQLITE_DB_PATH` |
|
|
103
|
+
|
|
104
|
+
`OR3_SQLITE_DB_PATH` is required in non-test environments unless
|
|
105
|
+
`OR3_SQLITE_ALLOW_IN_MEMORY=true`; otherwise startup fails with a clear error.
|
|
106
|
+
|
|
107
|
+
OR3 Connect uses the same database with local, Bun, or Turso runtimes:
|
|
44
108
|
|
|
45
109
|
```bash
|
|
46
110
|
OR3_CONNECT_ENABLED=true
|
|
47
111
|
OR3_CONNECT_PROVIDER=sqlite
|
|
48
112
|
```
|
|
49
113
|
|
|
50
|
-
No Convex deployment or second database is required.
|
|
51
|
-
|
|
52
114
|
## How it works
|
|
53
115
|
|
|
54
116
|
### Registration
|
|
@@ -60,8 +122,12 @@ On server startup, the Nitro plugin:
|
|
|
60
122
|
3. Registers `AuthWorkspaceStore` with ID `sqlite`
|
|
61
123
|
4. Registers `SyncGatewayAdapter` when SQLite sync is selected
|
|
62
124
|
5. Registers `ConnectStore` when SQLite Connect persistence is selected
|
|
125
|
+
6. Registers `WebhookStore` and the admin stores (workspace access, workspace
|
|
126
|
+
settings, user search) — all runtimes except D1
|
|
127
|
+
7. Registers `RateLimitProvider` with ID `sqlite` and the sync admin adapter
|
|
63
128
|
|
|
64
|
-
Registration is skipped when `auth.enabled` is `false
|
|
129
|
+
Registration is skipped when `auth.enabled` is `false`, or when neither SQLite
|
|
130
|
+
sync nor SQLite Connect is selected (local-only mode).
|
|
65
131
|
|
|
66
132
|
### Schema
|
|
67
133
|
|
|
@@ -73,19 +139,23 @@ Ordered migrations create and evolve all tables:
|
|
|
73
139
|
- **006_sync_snapshots**: winning operation IDs plus immutable snapshot headers/items
|
|
74
140
|
- **009_or3_connect**: single-use device authorizations and connected computers
|
|
75
141
|
|
|
142
|
+
Additional migrations (007–008, 010–016) evolve device-cursor ownership,
|
|
143
|
+
upload intents, and Connect credential/lifecycle hardening and rate limits.
|
|
144
|
+
|
|
76
145
|
All tables use snake_case aligned with the sync wire format.
|
|
77
146
|
|
|
78
147
|
### Sync semantics
|
|
79
148
|
|
|
80
|
-
- **Push**: validates ops → checks `op_id` idempotency → allocates contiguous `server_version` block → applies LWW to materialized tables →
|
|
149
|
+
- **Push**: validates ops → checks `op_id` idempotency → allocates contiguous `server_version` block → writes change_log → applies LWW to materialized tables → upserts tombstones for deletes
|
|
81
150
|
- **Pull**: returns ordered changes for `server_version > cursor` with limit/pagination and optional table filtering
|
|
82
|
-
- **Snapshot**: captures canonical live rows and current tombstones
|
|
151
|
+
- **Snapshot**: captures canonical live rows and current tombstones at one `highWatermark`, then serves immutable, keyset-paginated pages ordered by `(tableName, pk, kind)`
|
|
83
152
|
- **Cursor**: forward-only per-device cursor tracking
|
|
84
153
|
- **Retention safety**: tombstone and `change_log` GC is enabled only under the explicit `snapshot-v1` capability and deletes old revisions acknowledged by every registered device
|
|
85
154
|
|
|
86
155
|
LWW conflict resolution: incoming wins when `clock` is higher, or when clocks are equal and `hlc` is lexicographically greater.
|
|
87
156
|
|
|
88
|
-
|
|
157
|
+
Local, Bun, and Turso runtimes use `BEGIN IMMEDIATE` transactions. D1 uses its
|
|
158
|
+
native atomic batch API for grouped writes.
|
|
89
159
|
|
|
90
160
|
### Workspace store
|
|
91
161
|
|
|
@@ -95,13 +165,16 @@ Push uses `BEGIN IMMEDIATE` transactions to prevent concurrent server_version ra
|
|
|
95
165
|
|
|
96
166
|
## Backup
|
|
97
167
|
|
|
98
|
-
|
|
168
|
+
For local-file and Bun runtimes, everything lives in a single SQLite file:
|
|
99
169
|
|
|
100
170
|
```bash
|
|
101
171
|
# While the app is running (WAL mode supports this)
|
|
102
172
|
sqlite3 /data/or3-sync.db ".backup /backup/or3-sync-$(date +%s).db"
|
|
103
173
|
```
|
|
104
174
|
|
|
175
|
+
Use Turso or Cloudflare's own backup/export facilities for their managed
|
|
176
|
+
databases.
|
|
177
|
+
|
|
105
178
|
## Development
|
|
106
179
|
|
|
107
180
|
```bash
|
|
@@ -115,11 +188,31 @@ bun run build # build for distribution
|
|
|
115
188
|
|
|
116
189
|
- Works with multiple auth providers (`basic-auth`, `clerk`, or custom)
|
|
117
190
|
- Replaces `or3-provider-convex` for sync + workspace store functionality
|
|
118
|
-
- Provides OR3 Connect persistence without Convex
|
|
191
|
+
- Provides OR3 Connect persistence without Convex for local, Bun, and Turso runtimes
|
|
119
192
|
- Does NOT provide storage — pair with `or3-provider-fs` for file storage
|
|
120
193
|
|
|
121
194
|
### Known differences vs Convex
|
|
122
195
|
|
|
123
196
|
- Single-process SQLite vs distributed Convex backend
|
|
124
197
|
- No real-time subscriptions (gateway polling only)
|
|
125
|
-
- Migrations run on boot; schema changes require restart
|
|
198
|
+
- Migrations run on boot, or on the first Worker request for D1; schema changes require restart
|
|
199
|
+
|
|
200
|
+
## Troubleshooting
|
|
201
|
+
|
|
202
|
+
- **`OR3_SQLITE_DB_PATH is required in non-test environments`** — set a file
|
|
203
|
+
path, or pass `OR3_SQLITE_ALLOW_IN_MEMORY=true` only for ephemeral storage.
|
|
204
|
+
- **`OR3_SQLITE_STRICT=true forbids in-memory SQLite`** — the two settings
|
|
205
|
+
cannot be combined; set `OR3_SQLITE_DB_PATH`.
|
|
206
|
+
- **`Unsupported OR3_SQLITE_DRIVER value`** — use `better-sqlite3`, `bun`,
|
|
207
|
+
`turso`, or `d1`.
|
|
208
|
+
- **`Unable to load better-sqlite3`** — install `better-sqlite3`, or select
|
|
209
|
+
another driver via `OR3_SQLITE_DRIVER`.
|
|
210
|
+
- **`OR3_SQLITE_TURSO_URL` / `OR3_SQLITE_TURSO_AUTH_TOKEN` required** — both
|
|
211
|
+
must be set when `OR3_SQLITE_DRIVER=turso`, and `libsql` must be installed.
|
|
212
|
+
- **`Cloudflare D1 binding "…" was not found`** — set `OR3_SQLITE_D1_BINDING`
|
|
213
|
+
to the binding name declared in your Worker's `wrangler.jsonc`.
|
|
214
|
+
- **`Cloudflare D1 supports Auth and Sync, but OR3 Connect still requires a
|
|
215
|
+
synchronous SQLite runtime`** — Connect is unavailable with D1; set
|
|
216
|
+
`OR3_CONNECT_ENABLED=false` or switch to better-sqlite3, Bun, or Turso.
|
|
217
|
+
- **`OR3_SQLITE_DRIVER=bun requires Bun`** — the Bun driver only runs under
|
|
218
|
+
the Bun runtime with its built-in `bun:sqlite`.
|
package/dist/module.json
CHANGED
|
@@ -1,38 +1,85 @@
|
|
|
1
1
|
import { createError } from "h3";
|
|
2
|
-
import { SYNC_HISTORY_GC_POLICY } from "../../sync/history-gc-policy.js";
|
|
2
|
+
import { SYNC_HISTORY_GC_POLICY, canRunSyncHistoryGc } from "../../sync/history-gc-policy.js";
|
|
3
|
+
import {
|
|
4
|
+
beginSyncMaintenanceRun,
|
|
5
|
+
completeSyncMaintenanceRun,
|
|
6
|
+
computeSyncMaintenanceBacklog,
|
|
7
|
+
failSyncMaintenanceRun,
|
|
8
|
+
getSyncMaintenanceState,
|
|
9
|
+
SYNC_MAINTENANCE_RETENTION_SECONDS
|
|
10
|
+
} from "../../sync/maintenance-state.js";
|
|
11
|
+
import { createSqliteSyncGatewayAdapter } from "../../sync/sqlite-sync-gateway-adapter.js";
|
|
12
|
+
import { getSqliteDriver } from "../../db/kysely.js";
|
|
3
13
|
const SQLITE_PROVIDER_ID = "sqlite";
|
|
14
|
+
let gatewayInstance;
|
|
15
|
+
function getGateway() {
|
|
16
|
+
gatewayInstance ??= createSqliteSyncGatewayAdapter();
|
|
17
|
+
return gatewayInstance;
|
|
18
|
+
}
|
|
4
19
|
export const sqliteSyncAdminAdapter = {
|
|
5
20
|
id: SQLITE_PROVIDER_ID,
|
|
6
21
|
kind: "sync",
|
|
7
22
|
async getStatus(_event, _ctx) {
|
|
23
|
+
const driver = getSqliteDriver();
|
|
24
|
+
const isLocalDriver = driver === "better-sqlite3" || driver === "bun";
|
|
8
25
|
const dbPath = process.env.OR3_SQLITE_DB_PATH;
|
|
9
26
|
const warnings = [];
|
|
10
|
-
if (!dbPath) {
|
|
27
|
+
if (isLocalDriver && !dbPath) {
|
|
11
28
|
warnings.push({
|
|
12
29
|
level: "warning",
|
|
13
30
|
message: "OR3_SQLITE_DB_PATH is not set. SQLite may run in ephemeral mode."
|
|
14
31
|
});
|
|
15
|
-
} else if (dbPath === ":memory:") {
|
|
32
|
+
} else if (isLocalDriver && dbPath === ":memory:") {
|
|
16
33
|
warnings.push({
|
|
17
34
|
level: "warning",
|
|
18
35
|
message: "SQLite is configured with :memory:. Data will not persist across restarts."
|
|
19
36
|
});
|
|
20
37
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
38
|
+
if (driver === "d1") {
|
|
39
|
+
warnings.push({
|
|
40
|
+
level: "warning",
|
|
41
|
+
message: "Cloudflare D1 does not provide server-side admin stores or persistent webhooks."
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
const maintenance = getSyncMaintenanceState();
|
|
45
|
+
if (maintenance.state === "failed") {
|
|
46
|
+
warnings.push({
|
|
47
|
+
level: "warning",
|
|
48
|
+
message: `Sync history maintenance failed: ${maintenance.lastError ?? "unknown error"}`
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
const backlog = computeSyncMaintenanceBacklog(SYNC_MAINTENANCE_RETENTION_SECONDS);
|
|
25
52
|
return {
|
|
26
53
|
details: {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
54
|
+
driver,
|
|
55
|
+
dbPath: isLocalDriver ? dbPath ?? ":memory:" : void 0,
|
|
56
|
+
tursoUrl: driver === "turso" ? process.env.OR3_SQLITE_TURSO_URL : void 0,
|
|
57
|
+
d1Binding: driver === "d1" ? process.env.OR3_SQLITE_D1_BINDING ?? "DB" : void 0,
|
|
58
|
+
journalMode: isLocalDriver ? process.env.OR3_SQLITE_PRAGMA_JOURNAL_MODE ?? "WAL" : void 0,
|
|
59
|
+
synchronous: isLocalDriver ? process.env.OR3_SQLITE_PRAGMA_SYNCHRONOUS ?? "NORMAL" : void 0,
|
|
60
|
+
maintenance: {
|
|
61
|
+
...maintenance,
|
|
62
|
+
backlog
|
|
63
|
+
}
|
|
30
64
|
},
|
|
31
65
|
warnings,
|
|
32
|
-
actions: [
|
|
66
|
+
actions: [
|
|
67
|
+
{
|
|
68
|
+
id: "sync.gc-change-log",
|
|
69
|
+
label: "GC change log",
|
|
70
|
+
description: `Prune change-log entries older than ${SYNC_MAINTENANCE_RETENTION_SECONDS / 86400} days and behind every device cursor.`,
|
|
71
|
+
danger: true
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: "sync.gc-tombstones",
|
|
75
|
+
label: "GC tombstones",
|
|
76
|
+
description: `Prune tombstones older than ${SYNC_MAINTENANCE_RETENTION_SECONDS / 86400} days and behind every device cursor.`,
|
|
77
|
+
danger: true
|
|
78
|
+
}
|
|
79
|
+
]
|
|
33
80
|
};
|
|
34
81
|
},
|
|
35
|
-
async runAction(
|
|
82
|
+
async runAction(event, actionId, _payload, ctx) {
|
|
36
83
|
if (!ctx.session.workspace?.id) {
|
|
37
84
|
throw createError({
|
|
38
85
|
statusCode: 400,
|
|
@@ -40,10 +87,37 @@ export const sqliteSyncAdminAdapter = {
|
|
|
40
87
|
});
|
|
41
88
|
}
|
|
42
89
|
if (actionId === "sync.gc-change-log" || actionId === "sync.gc-tombstones") {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
90
|
+
if (!canRunSyncHistoryGc()) {
|
|
91
|
+
throw createError({
|
|
92
|
+
statusCode: 503,
|
|
93
|
+
statusMessage: SYNC_HISTORY_GC_POLICY.reason
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
const workspaceId = ctx.session.workspace.id;
|
|
97
|
+
const retentionSeconds = SYNC_MAINTENANCE_RETENTION_SECONDS;
|
|
98
|
+
const gateway = getGateway();
|
|
99
|
+
beginSyncMaintenanceRun();
|
|
100
|
+
try {
|
|
101
|
+
if (actionId === "sync.gc-change-log") {
|
|
102
|
+
await gateway.gcChangeLog(event, { scope: { workspaceId }, retentionSeconds });
|
|
103
|
+
} else {
|
|
104
|
+
await gateway.gcTombstones(event, { scope: { workspaceId }, retentionSeconds });
|
|
105
|
+
}
|
|
106
|
+
const backlog = computeSyncMaintenanceBacklog(retentionSeconds, true);
|
|
107
|
+
const lastRun = (/* @__PURE__ */ new Date()).toISOString();
|
|
108
|
+
completeSyncMaintenanceRun({ lastRun, backlog });
|
|
109
|
+
return {
|
|
110
|
+
ok: true,
|
|
111
|
+
actionId,
|
|
112
|
+
workspaceId,
|
|
113
|
+
retentionSeconds,
|
|
114
|
+
lastRun,
|
|
115
|
+
backlog
|
|
116
|
+
};
|
|
117
|
+
} catch (error) {
|
|
118
|
+
failSyncMaintenanceRun(error instanceof Error ? error.message : String(error));
|
|
119
|
+
throw error;
|
|
120
|
+
}
|
|
47
121
|
}
|
|
48
122
|
throw createError({ statusCode: 400, statusMessage: "Unknown action" });
|
|
49
123
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { randomUUID } from "node:crypto";
|
|
2
1
|
import { getSqliteDb } from "../../db/kysely.js";
|
|
3
2
|
function nowEpoch() {
|
|
4
3
|
return Math.floor(Date.now() / 1e3);
|
|
@@ -40,7 +39,7 @@ class SqliteWorkspaceAccessStore {
|
|
|
40
39
|
if (existing) {
|
|
41
40
|
userId = existing.id;
|
|
42
41
|
} else {
|
|
43
|
-
userId = randomUUID();
|
|
42
|
+
userId = globalThis.crypto.randomUUID();
|
|
44
43
|
await this.db.insertInto("users").values({
|
|
45
44
|
id: userId,
|
|
46
45
|
email: normalized,
|
|
@@ -60,7 +59,7 @@ class SqliteWorkspaceAccessStore {
|
|
|
60
59
|
}
|
|
61
60
|
}
|
|
62
61
|
if (!userId) {
|
|
63
|
-
userId = randomUUID();
|
|
62
|
+
userId = globalThis.crypto.randomUUID();
|
|
64
63
|
await this.db.insertInto("users").values({
|
|
65
64
|
id: userId,
|
|
66
65
|
email: null,
|
|
@@ -69,7 +68,7 @@ class SqliteWorkspaceAccessStore {
|
|
|
69
68
|
created_at: now
|
|
70
69
|
}).execute();
|
|
71
70
|
await this.db.insertInto("auth_accounts").values({
|
|
72
|
-
id: randomUUID(),
|
|
71
|
+
id: globalThis.crypto.randomUUID(),
|
|
73
72
|
user_id: userId,
|
|
74
73
|
provider: provider || "custom",
|
|
75
74
|
provider_user_id: lookup,
|
|
@@ -89,7 +88,7 @@ class SqliteWorkspaceAccessStore {
|
|
|
89
88
|
return;
|
|
90
89
|
}
|
|
91
90
|
await this.db.insertInto("workspace_members").values({
|
|
92
|
-
id: randomUUID(),
|
|
91
|
+
id: globalThis.crypto.randomUUID(),
|
|
93
92
|
workspace_id: input.workspaceId,
|
|
94
93
|
user_id: userId,
|
|
95
94
|
role: input.role,
|
|
@@ -249,7 +248,7 @@ class SqliteWorkspaceAccessStore {
|
|
|
249
248
|
if (!owner) {
|
|
250
249
|
throw new Error("Owner user not found");
|
|
251
250
|
}
|
|
252
|
-
const workspaceId = randomUUID();
|
|
251
|
+
const workspaceId = globalThis.crypto.randomUUID();
|
|
253
252
|
const now = nowEpoch();
|
|
254
253
|
await this.db.transaction().execute(async (tx) => {
|
|
255
254
|
await tx.insertInto("workspaces").values({
|
|
@@ -262,7 +261,7 @@ class SqliteWorkspaceAccessStore {
|
|
|
262
261
|
deleted_at: null
|
|
263
262
|
}).execute();
|
|
264
263
|
await tx.insertInto("workspace_members").values({
|
|
265
|
-
id: randomUUID(),
|
|
264
|
+
id: globalThis.crypto.randomUUID(),
|
|
266
265
|
workspace_id: workspaceId,
|
|
267
266
|
user_id: input.ownerUserId,
|
|
268
267
|
role: "owner",
|
|
@@ -312,7 +311,7 @@ class SqliteWorkspaceSettingsStore {
|
|
|
312
311
|
}
|
|
313
312
|
async set(workspaceId, key, value) {
|
|
314
313
|
await this.db.insertInto("admin_workspace_settings").values({
|
|
315
|
-
id: randomUUID(),
|
|
314
|
+
id: globalThis.crypto.randomUUID(),
|
|
316
315
|
workspace_id: workspaceId,
|
|
317
316
|
key,
|
|
318
317
|
value,
|
|
@@ -122,5 +122,10 @@ export declare class SqliteAuthWorkspaceStore implements AuthWorkspaceStore {
|
|
|
122
122
|
ok: false;
|
|
123
123
|
reason: 'not_found' | 'expired' | 'revoked' | 'already_used' | 'token_mismatch';
|
|
124
124
|
}>;
|
|
125
|
+
private getOrCreateUserInD1;
|
|
126
|
+
private validateInviteInD1;
|
|
127
|
+
private acceptInviteAndProvisionUserInD1;
|
|
128
|
+
private consumeInviteInD1;
|
|
129
|
+
private inviteProvisionFailureInD1;
|
|
125
130
|
}
|
|
126
131
|
export declare function createSqliteAuthWorkspaceStore(): AuthWorkspaceStore;
|