@supabase/lite 0.0.1 → 0.2.1-next.1
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 +311 -0
- package/STATUS.md +844 -0
- package/UPGRADE.md +221 -0
- package/dist/cli/index.js +330 -29421
- package/dist/cli/lib.js +49 -6273
- package/dist/db/browser/index.js +19 -15485
- package/dist/db/bun/index.js +19 -15473
- package/dist/db/fallback.js +18 -15369
- package/dist/db/node/index.js +19 -15466
- package/dist/db/postgres/PostgresConnection.js +18 -365
- package/dist/db/postgres/pglite/PgliteConnection.js +20 -642
- package/dist/db/workerd/index.js +18 -15591
- package/dist/index.js +258 -32242
- package/dist/vite/index.js +3 -1910
- package/package.json +8 -9
- package/dist/Connection-BJclIu8v.d.ts +0 -529
- package/dist/Connection-BsiQMo4A.d.ts +0 -562
- package/dist/db/postgres/BasePostgresConnection-COHRCvc-.d.ts +0 -24
- package/dist/db/postgres/BasePostgresConnection-Di94o0ON.d.ts +0 -24
- package/dist/db/postgres/index.js +0 -802
- package/dist/db/sqlite/index.js +0 -14724
- package/dist/index-4cbfQyFv.d.ts +0 -763
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import postgres from
|
|
2
|
-
import { PostgresJSDialect } from 'kysely-postgres-js';
|
|
3
|
-
import { Kysely, sql } from 'kysely';
|
|
4
|
-
import { Connection, invariant, RelationNotFoundError } from '@supabase/lite';
|
|
5
|
-
|
|
6
|
-
try {
|
|
1
|
+
import x from'postgres';import {PostgresJSDialect}from'kysely-postgres-js';import {Kysely,sql}from'kysely';import {Connection,invariant,RelationNotFoundError}from'@supabase/lite';try {
|
|
7
2
|
/**
|
|
8
3
|
* Adding this to avoid warnings from node:sqlite being experimental
|
|
9
4
|
*/
|
|
@@ -13,20 +8,8 @@ try {
|
|
|
13
8
|
return emitWarning(warning, ...args);
|
|
14
9
|
};
|
|
15
10
|
} catch {}
|
|
16
|
-
var
|
|
17
|
-
|
|
18
|
-
super("Force rollback");
|
|
19
|
-
this.result = result;
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
var BasePostgresConnection = class extends Connection {
|
|
23
|
-
dialect = "postgres";
|
|
24
|
-
constructor(options) {
|
|
25
|
-
super({
|
|
26
|
-
...options,
|
|
27
|
-
// @todo: this should be handled by the auth schema
|
|
28
|
-
baseSchema: `
|
|
29
|
-
${options.baseSchema ?? ""}
|
|
11
|
+
var E=class extends Error{constructor(o){super("Force rollback");this.result=o;}},N=class extends Connection{dialect="postgres";constructor(n){super({...n,baseSchema:`
|
|
12
|
+
${n.baseSchema??""}
|
|
30
13
|
|
|
31
14
|
CREATE SCHEMA IF NOT EXISTS auth;
|
|
32
15
|
|
|
@@ -52,16 +35,7 @@ var BasePostgresConnection = class extends Connection {
|
|
|
52
35
|
'{}'
|
|
53
36
|
)::jsonb;
|
|
54
37
|
$$ LANGUAGE SQL STABLE;
|
|
55
|
-
`
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
async introspect(options) {
|
|
59
|
-
invariant(typeof options === "object" || options === void 0, "options must be an object");
|
|
60
|
-
const useCache = options?.useCache ?? false;
|
|
61
|
-
const cached = await this.readCachedIntrospection({ useCache });
|
|
62
|
-
if (cached) return cached;
|
|
63
|
-
try {
|
|
64
|
-
const tblResult = await sql`
|
|
38
|
+
`});}async introspect(n){invariant(typeof n=="object"||n===void 0,"options must be an object");let o=n?.useCache??false,t=await this.readCachedIntrospection({useCache:o});if(t)return t;try{let c=(await sql`
|
|
65
39
|
SELECT
|
|
66
40
|
tbls.table_name AS "name",
|
|
67
41
|
tbls.table_schema AS "schema",
|
|
@@ -74,17 +48,7 @@ var BasePostgresConnection = class extends Connection {
|
|
|
74
48
|
tbls.table_schema NOT IN ('information_schema', 'pg_catalog')
|
|
75
49
|
AND tbls.table_type IN ('BASE TABLE', 'FOREIGN TABLE')
|
|
76
50
|
ORDER BY tbls.table_schema, tbls.table_name
|
|
77
|
-
`.execute(this.kysely)
|
|
78
|
-
const tables = tblResult.rows.map((r) => ({
|
|
79
|
-
name: r.name,
|
|
80
|
-
schema: r.schema,
|
|
81
|
-
type: "table",
|
|
82
|
-
rows: Number(r.rows),
|
|
83
|
-
sql: "",
|
|
84
|
-
engine: "",
|
|
85
|
-
collation: ""
|
|
86
|
-
}));
|
|
87
|
-
const colResult = await sql`
|
|
51
|
+
`.execute(this.kysely)).rows.map(e=>({name:e.name,schema:e.schema,type:"table",rows:Number(e.rows),sql:"",engine:"",collation:""})),l=(await sql`
|
|
88
52
|
SELECT
|
|
89
53
|
cols.table_name AS "table",
|
|
90
54
|
cols.table_schema AS "schema",
|
|
@@ -136,25 +100,7 @@ var BasePostgresConnection = class extends Connection {
|
|
|
136
100
|
LEFT JOIN pg_catalog.pg_type pt ON pt.oid = attr.atttypid
|
|
137
101
|
WHERE cols.table_schema NOT IN ('information_schema', 'pg_catalog')
|
|
138
102
|
ORDER BY cols.table_schema, cols.table_name, cols.ordinal_position
|
|
139
|
-
`.execute(this.kysely)
|
|
140
|
-
const columns = colResult.rows.map((r) => ({
|
|
141
|
-
table: r.table,
|
|
142
|
-
schema: r.schema,
|
|
143
|
-
name: r.name,
|
|
144
|
-
type: r.type,
|
|
145
|
-
nullable: r.nullable,
|
|
146
|
-
default_value: r.default_value,
|
|
147
|
-
is_primary_key: false,
|
|
148
|
-
// filled below
|
|
149
|
-
ordinal_position: Number(r.ordinal_position),
|
|
150
|
-
character_maximum_length: r.character_maximum_length ?? null,
|
|
151
|
-
precision: r.precision ?? null,
|
|
152
|
-
is_identity: r.is_identity,
|
|
153
|
-
collation: r.collation,
|
|
154
|
-
pg_type: r.udt_name ?? void 0,
|
|
155
|
-
is_generated: r.is_generated ?? false
|
|
156
|
-
}));
|
|
157
|
-
const fkResult = await sql`
|
|
103
|
+
`.execute(this.kysely)).rows.map(e=>({table:e.table,schema:e.schema,name:e.name,type:e.type,nullable:e.nullable,default_value:e.default_value,is_primary_key:!1,ordinal_position:Number(e.ordinal_position),character_maximum_length:e.character_maximum_length??null,precision:e.precision??null,is_identity:e.is_identity,collation:e.collation,pg_type:e.udt_name??void 0,is_generated:e.is_generated??!1})),p=(await sql`
|
|
158
104
|
SELECT
|
|
159
105
|
ns.nspname AS "schema",
|
|
160
106
|
cl.relname AS "table",
|
|
@@ -179,19 +125,7 @@ var BasePostgresConnection = class extends Connection {
|
|
|
179
125
|
'information_schema'
|
|
180
126
|
, 'pg_catalog')
|
|
181
127
|
ORDER BY ns.nspname, cl.relname, con.conname, cols.ord
|
|
182
|
-
`.execute(this.kysely)
|
|
183
|
-
const fks = fkResult.rows.map((r) => ({
|
|
184
|
-
table: r.table,
|
|
185
|
-
column: r.column,
|
|
186
|
-
schema: r.schema,
|
|
187
|
-
ref_table: r.ref_table,
|
|
188
|
-
ref_column: r.ref_column,
|
|
189
|
-
foreign_key_name: r.foreign_key_name,
|
|
190
|
-
fk_def: r.fk_def,
|
|
191
|
-
on_update: "",
|
|
192
|
-
on_delete: ""
|
|
193
|
-
}));
|
|
194
|
-
const pkResult = await sql`
|
|
128
|
+
`.execute(this.kysely)).rows.map(e=>({table:e.table,column:e.column,schema:e.schema,ref_table:e.ref_table,ref_column:e.ref_column,foreign_key_name:e.foreign_key_name,fk_def:e.fk_def,on_update:"",on_delete:""})),r=(await sql`
|
|
195
129
|
SELECT
|
|
196
130
|
ns.nspname AS "schema",
|
|
197
131
|
cl.relname AS "table",
|
|
@@ -208,20 +142,7 @@ var BasePostgresConnection = class extends Connection {
|
|
|
208
142
|
'information_schema'
|
|
209
143
|
, 'pg_catalog')
|
|
210
144
|
GROUP BY ns.nspname, cl.relname, con.oid
|
|
211
|
-
`.execute(this.kysely);
|
|
212
|
-
const pks = pkResult.rows.map((r) => ({
|
|
213
|
-
table: r.table,
|
|
214
|
-
columns: r.columns,
|
|
215
|
-
schema: r.schema,
|
|
216
|
-
field_count: r.columns.length
|
|
217
|
-
}));
|
|
218
|
-
const pkSet = new Set(
|
|
219
|
-
pks.flatMap((pk) => pk.columns.map((col) => `${pk.schema}.${pk.table}.${col}`))
|
|
220
|
-
);
|
|
221
|
-
for (const col of columns) {
|
|
222
|
-
col.is_primary_key = pkSet.has(`${col.schema}.${col.table}.${col.name}`);
|
|
223
|
-
}
|
|
224
|
-
const idxResult = await sql`
|
|
145
|
+
`.execute(this.kysely)).rows.map(e=>({table:e.table,columns:e.columns,schema:e.schema,field_count:e.columns.length})),S=new Set(r.flatMap(e=>e.columns.map(b=>`${e.schema}.${e.table}.${b}`)));for(let e of l)e.is_primary_key=S.has(`${e.schema}.${e.table}.${e.name}`);let g=(await sql`
|
|
225
146
|
SELECT
|
|
226
147
|
tnsp.nspname AS "schema",
|
|
227
148
|
cl.relname AS "table",
|
|
@@ -242,15 +163,7 @@ var BasePostgresConnection = class extends Connection {
|
|
|
242
163
|
'information_schema'
|
|
243
164
|
, 'pg_catalog')
|
|
244
165
|
GROUP BY tnsp.nspname, cl.relname, ic.relname, idx.indisunique
|
|
245
|
-
`.execute(this.kysely)
|
|
246
|
-
const indexes = idxResult.rows.map((r) => ({
|
|
247
|
-
table: r.table,
|
|
248
|
-
name: r.name,
|
|
249
|
-
unique: r.unique,
|
|
250
|
-
columns: r.columns,
|
|
251
|
-
schema: r.schema
|
|
252
|
-
}));
|
|
253
|
-
const viewResult = await sql`
|
|
166
|
+
`.execute(this.kysely)).rows.map(e=>({table:e.table,name:e.name,unique:e.unique,columns:e.columns,schema:e.schema})),O=(await sql`
|
|
254
167
|
SELECT
|
|
255
168
|
views.schemaname AS "schema",
|
|
256
169
|
views.viewname AS "name",
|
|
@@ -258,13 +171,7 @@ var BasePostgresConnection = class extends Connection {
|
|
|
258
171
|
FROM pg_views views
|
|
259
172
|
WHERE views.schemaname NOT IN ('information_schema', 'pg_catalog')
|
|
260
173
|
ORDER BY views.schemaname, views.viewname
|
|
261
|
-
`.execute(this.kysely)
|
|
262
|
-
const views = viewResult.rows.map((r) => ({
|
|
263
|
-
name: r.name,
|
|
264
|
-
schema: r.schema,
|
|
265
|
-
sql: r.sql ?? ""
|
|
266
|
-
}));
|
|
267
|
-
const chkResult = await sql`
|
|
174
|
+
`.execute(this.kysely)).rows.map(e=>({name:e.name,schema:e.schema,sql:e.sql??""})),A=(await sql`
|
|
268
175
|
SELECT
|
|
269
176
|
n.nspname AS "schema",
|
|
270
177
|
cl.relname AS "table",
|
|
@@ -276,13 +183,7 @@ var BasePostgresConnection = class extends Connection {
|
|
|
276
183
|
c.contype = 'c'
|
|
277
184
|
AND n.nspname NOT IN ('information_schema', 'pg_catalog')
|
|
278
185
|
ORDER BY n.nspname, cl.relname
|
|
279
|
-
`.execute(this.kysely)
|
|
280
|
-
const checkConstraints = chkResult.rows.map((r) => ({
|
|
281
|
-
schema: r.schema,
|
|
282
|
-
table: r.table,
|
|
283
|
-
expression: r.expression ?? ""
|
|
284
|
-
}));
|
|
285
|
-
const uqResult = await sql`
|
|
186
|
+
`.execute(this.kysely)).rows.map(e=>({schema:e.schema,table:e.table,expression:e.expression??""})),h=(await sql`
|
|
286
187
|
SELECT
|
|
287
188
|
n.nspname AS "schema",
|
|
288
189
|
cl.relname AS "table",
|
|
@@ -297,14 +198,7 @@ var BasePostgresConnection = class extends Connection {
|
|
|
297
198
|
c.contype = 'u'
|
|
298
199
|
AND n.nspname NOT IN ('information_schema', 'pg_catalog')
|
|
299
200
|
GROUP BY n.nspname, cl.relname, c.conname, c.oid
|
|
300
|
-
`.execute(this.kysely)
|
|
301
|
-
const uniqueConstraints = uqResult.rows.map((r) => ({
|
|
302
|
-
schema: r.schema,
|
|
303
|
-
table: r.table,
|
|
304
|
-
name: r.name,
|
|
305
|
-
columns: r.columns
|
|
306
|
-
}));
|
|
307
|
-
const commentResult = await sql`
|
|
201
|
+
`.execute(this.kysely)).rows.map(e=>({schema:e.schema,table:e.table,name:e.name,columns:e.columns})),f=(await sql`
|
|
308
202
|
SELECT
|
|
309
203
|
n.nspname AS "schema",
|
|
310
204
|
cl.relname AS "table",
|
|
@@ -319,14 +213,7 @@ var BasePostgresConnection = class extends Connection {
|
|
|
319
213
|
n.nspname NOT IN ('information_schema', 'pg_catalog')
|
|
320
214
|
AND cl.relkind IN ('r', 'v', 'm', 'f', 'p')
|
|
321
215
|
AND d.description IS NOT NULL
|
|
322
|
-
`.execute(this.kysely)
|
|
323
|
-
const comments = commentResult.rows.map((r) => ({
|
|
324
|
-
schema: r.schema,
|
|
325
|
-
table: r.table,
|
|
326
|
-
column: r.column ?? void 0,
|
|
327
|
-
text: r.text
|
|
328
|
-
}));
|
|
329
|
-
const enumResult = await sql`
|
|
216
|
+
`.execute(this.kysely)).rows.map(e=>({schema:e.schema,table:e.table,column:e.column??void 0,text:e.text})),R=await sql`
|
|
330
217
|
SELECT
|
|
331
218
|
n.nspname AS "schema",
|
|
332
219
|
t.typname AS "type",
|
|
@@ -337,8 +224,7 @@ var BasePostgresConnection = class extends Connection {
|
|
|
337
224
|
JOIN pg_namespace n ON n.oid = t.typnamespace
|
|
338
225
|
WHERE n.nspname NOT IN ('pg_catalog', 'information_schema')
|
|
339
226
|
GROUP BY n.nspname, t.typname
|
|
340
|
-
`.execute(this.kysely)
|
|
341
|
-
const compositeResult = await sql`
|
|
227
|
+
`.execute(this.kysely),T=await sql`
|
|
342
228
|
SELECT
|
|
343
229
|
n.nspname AS "schema",
|
|
344
230
|
t.typname AS "type",
|
|
@@ -360,76 +246,9 @@ var BasePostgresConnection = class extends Connection {
|
|
|
360
246
|
AND NOT a.attisdropped
|
|
361
247
|
AND n.nspname NOT IN ('pg_catalog', 'information_schema')
|
|
362
248
|
GROUP BY n.nspname, t.typname
|
|
363
|
-
`.execute(this.kysely);
|
|
364
|
-
const customTypes = [
|
|
365
|
-
...enumResult.rows.map((r) => ({
|
|
366
|
-
schema: r.schema,
|
|
367
|
-
type: r.type,
|
|
368
|
-
kind: "enum",
|
|
369
|
-
values: r.values
|
|
370
|
-
})),
|
|
371
|
-
...compositeResult.rows.map((r) => ({
|
|
372
|
-
schema: r.schema,
|
|
373
|
-
type: r.type,
|
|
374
|
-
kind: "composite",
|
|
375
|
-
fields: r.fields
|
|
376
|
-
}))
|
|
377
|
-
];
|
|
378
|
-
const dbResult = await sql`SELECT current_database() AS "name"`.execute(this.kysely);
|
|
379
|
-
const dbName = dbResult.rows[0]?.name ?? "postgres";
|
|
380
|
-
const result = {
|
|
381
|
-
tables,
|
|
382
|
-
columns,
|
|
383
|
-
indexes,
|
|
384
|
-
foreign_keys: fks,
|
|
385
|
-
primary_keys: pks,
|
|
386
|
-
views,
|
|
387
|
-
triggers: [],
|
|
388
|
-
check_constraints: checkConstraints,
|
|
389
|
-
unique_constraints: uniqueConstraints,
|
|
390
|
-
comments,
|
|
391
|
-
custom_types: customTypes,
|
|
392
|
-
database_name: dbName,
|
|
393
|
-
version: ""
|
|
394
|
-
};
|
|
395
|
-
await this.writeCachedIntrospection(result, { useDriver: useCache });
|
|
396
|
-
return result;
|
|
397
|
-
} catch (e) {
|
|
398
|
-
console.error("Introspection failed:", e);
|
|
399
|
-
return {
|
|
400
|
-
tables: [],
|
|
401
|
-
columns: [],
|
|
402
|
-
indexes: [],
|
|
403
|
-
foreign_keys: [],
|
|
404
|
-
primary_keys: [],
|
|
405
|
-
views: [],
|
|
406
|
-
triggers: [],
|
|
407
|
-
check_constraints: [],
|
|
408
|
-
unique_constraints: [],
|
|
409
|
-
comments: [],
|
|
410
|
-
custom_types: [],
|
|
411
|
-
database_name: "postgres",
|
|
412
|
-
version: ""
|
|
413
|
-
};
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
rlsState = "unknown";
|
|
417
|
-
/**
|
|
418
|
-
* Detect if any table has RLS enabled, and if so ensure anon/authenticated
|
|
419
|
-
* roles exist with default privileges. Runs once per connection.
|
|
420
|
-
*/
|
|
421
|
-
async ensureRlsContext() {
|
|
422
|
-
if (this.rlsState !== "unknown") return this.rlsState === "active";
|
|
423
|
-
const result = await sql`
|
|
249
|
+
`.execute(this.kysely),L=[...R.rows.map(e=>({schema:e.schema,type:e.type,kind:"enum",values:e.values})),...T.rows.map(e=>({schema:e.schema,type:e.type,kind:"composite",fields:e.fields}))],I=(await sql`SELECT current_database() AS "name"`.execute(this.kysely)).rows[0]?.name??"postgres",y={tables:c,columns:l,indexes:g,foreign_keys:p,primary_keys:r,views:O,triggers:[],check_constraints:A,unique_constraints:h,comments:f,custom_types:L,database_name:I,version:""};return await this.writeCachedIntrospection(y,{useDriver:o}),y}catch(s){return console.error("Introspection failed:",s),{tables:[],columns:[],indexes:[],foreign_keys:[],primary_keys:[],views:[],triggers:[],check_constraints:[],unique_constraints:[],comments:[],custom_types:[],database_name:"postgres",version:""}}}rlsState="unknown";async ensureRlsContext(){if(this.rlsState!=="unknown")return this.rlsState==="active";let n=await sql`
|
|
424
250
|
SELECT count(*) ::text as count FROM pg_class WHERE relrowsecurity = true
|
|
425
|
-
`.execute(this.kysely);
|
|
426
|
-
const hasRls = Number(result.rows[0]?.count ?? 0) > 0;
|
|
427
|
-
if (!hasRls) {
|
|
428
|
-
this.rlsState = "inactive";
|
|
429
|
-
return false;
|
|
430
|
-
}
|
|
431
|
-
this.rlsState = "active";
|
|
432
|
-
await sql`
|
|
251
|
+
`.execute(this.kysely);if(!(Number(n.rows[0]?.count??0)>0))return this.rlsState="inactive",false;this.rlsState="active",await sql`
|
|
433
252
|
DO $$ BEGIN
|
|
434
253
|
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'anon') THEN
|
|
435
254
|
CREATE ROLE anon NOLOGIN;
|
|
@@ -438,174 +257,8 @@ var BasePostgresConnection = class extends Connection {
|
|
|
438
257
|
CREATE ROLE authenticated NOLOGIN;
|
|
439
258
|
END IF;
|
|
440
259
|
END $$
|
|
441
|
-
`.execute(this.kysely);
|
|
442
|
-
const schemas = await sql`
|
|
260
|
+
`.execute(this.kysely);let t=await sql`
|
|
443
261
|
SELECT DISTINCT n.nspname FROM pg_class c
|
|
444
262
|
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
445
263
|
WHERE c.relrowsecurity = true
|
|
446
|
-
`.execute(this.kysely);
|
|
447
|
-
for (const { nspname } of schemas.rows) {
|
|
448
|
-
await sql`GRANT USAGE ON SCHEMA ${sql.ref(nspname)} TO anon, authenticated`.execute(
|
|
449
|
-
this.kysely
|
|
450
|
-
);
|
|
451
|
-
await sql.raw(`GRANT ALL ON ALL TABLES IN SCHEMA "${nspname}" TO anon, authenticated`).execute(this.kysely);
|
|
452
|
-
await sql.raw(`GRANT ALL ON ALL SEQUENCES IN SCHEMA "${nspname}" TO anon, authenticated`).execute(this.kysely);
|
|
453
|
-
await sql.raw(
|
|
454
|
-
`ALTER DEFAULT PRIVILEGES IN SCHEMA "${nspname}" GRANT ALL ON TABLES TO anon, authenticated`
|
|
455
|
-
).execute(this.kysely);
|
|
456
|
-
await sql.raw(
|
|
457
|
-
`ALTER DEFAULT PRIVILEGES IN SCHEMA "${nspname}" GRANT ALL ON SEQUENCES TO anon, authenticated`
|
|
458
|
-
).execute(this.kysely);
|
|
459
|
-
}
|
|
460
|
-
return true;
|
|
461
|
-
}
|
|
462
|
-
async withContext(vars, fn, opts) {
|
|
463
|
-
const forceRollback = opts?.forceRollback === true;
|
|
464
|
-
if (!forceRollback && !vars) return fn(this.kysely);
|
|
465
|
-
const rlsActive = vars ? await this.ensureRlsContext() : false;
|
|
466
|
-
if (!forceRollback && !rlsActive) return fn(this.kysely);
|
|
467
|
-
try {
|
|
468
|
-
return await this.kysely.transaction().execute(async (trx) => {
|
|
469
|
-
if (vars && rlsActive) {
|
|
470
|
-
const auth = vars.auth;
|
|
471
|
-
const role = auth?.role || "anon";
|
|
472
|
-
const uid = String(auth?.uid ?? "");
|
|
473
|
-
const jwt = auth?.jwt;
|
|
474
|
-
await sql`SELECT set_config('role', ${role}, true)`.execute(trx);
|
|
475
|
-
await sql`SELECT set_config('request.jwt.claim.sub', ${uid}, true)`.execute(trx);
|
|
476
|
-
await sql`SELECT set_config('request.jwt.claim.role', ${role}, true)`.execute(trx);
|
|
477
|
-
if (jwt && typeof jwt === "object") {
|
|
478
|
-
await sql`SELECT set_config('request.jwt.claims', ${JSON.stringify(jwt)}, true)`.execute(
|
|
479
|
-
trx
|
|
480
|
-
);
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
const result = await fn(trx);
|
|
484
|
-
if (forceRollback) throw new ForceRollback(result);
|
|
485
|
-
return result;
|
|
486
|
-
});
|
|
487
|
-
} catch (error) {
|
|
488
|
-
if (error instanceof ForceRollback) return error.result;
|
|
489
|
-
throw error;
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
async onPostgrestAST(ast) {
|
|
493
|
-
if (!ast.from) return ast;
|
|
494
|
-
const schema = ast.schema ?? "public";
|
|
495
|
-
const relation = ast.from;
|
|
496
|
-
const introspection = await this.introspect({ useCache: true });
|
|
497
|
-
if (!introspection.tables.some((t) => t.name === relation && t.schema === schema) && !introspection.views.some((v) => v.name === relation && v.schema === schema)) {
|
|
498
|
-
throw new RelationNotFoundError(schema, relation);
|
|
499
|
-
}
|
|
500
|
-
return ast;
|
|
501
|
-
}
|
|
502
|
-
async transaction(statements, opts) {
|
|
503
|
-
await this.exec("BEGIN");
|
|
504
|
-
try {
|
|
505
|
-
for (const statement of statements) {
|
|
506
|
-
await this.exec(statement);
|
|
507
|
-
}
|
|
508
|
-
await this.exec("COMMIT");
|
|
509
|
-
} catch (error) {
|
|
510
|
-
await this.exec("ROLLBACK");
|
|
511
|
-
throw error;
|
|
512
|
-
} finally {
|
|
513
|
-
if (opts?.intent === "migration") {
|
|
514
|
-
await this.clearSchemaCache();
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
};
|
|
519
|
-
|
|
520
|
-
// src/db/postgres/PostgresConnection.ts
|
|
521
|
-
var PostgresConnection = class extends BasePostgresConnection {
|
|
522
|
-
driver;
|
|
523
|
-
dialect = "postgres";
|
|
524
|
-
constructor(config) {
|
|
525
|
-
super(config);
|
|
526
|
-
this.driver = postgres(config.url ?? "", {
|
|
527
|
-
types: {
|
|
528
|
-
// Parse bigint/int8 (OID 20) as JS number instead of string
|
|
529
|
-
bigint: {
|
|
530
|
-
to: 20,
|
|
531
|
-
from: [20],
|
|
532
|
-
serialize: (x) => x.toString(),
|
|
533
|
-
parse: (x) => {
|
|
534
|
-
const n = Number(x);
|
|
535
|
-
if (Number.isSafeInteger(n)) return n;
|
|
536
|
-
return BigInt(x);
|
|
537
|
-
}
|
|
538
|
-
},
|
|
539
|
-
// json (OID 114) and jsonb (OID 3802): postgres.js leaves both as text by default.
|
|
540
|
-
// PostgREST returns them as parsed JSON, including json_agg() in embed aggregates.
|
|
541
|
-
json: {
|
|
542
|
-
to: 114,
|
|
543
|
-
from: [114],
|
|
544
|
-
serialize: (x) => JSON.stringify(x),
|
|
545
|
-
parse: (x) => JSON.parse(x)
|
|
546
|
-
},
|
|
547
|
-
jsonb: {
|
|
548
|
-
to: 3802,
|
|
549
|
-
from: [3802],
|
|
550
|
-
serialize: (x) => JSON.stringify(x),
|
|
551
|
-
parse: (x) => JSON.parse(x)
|
|
552
|
-
},
|
|
553
|
-
// numeric (OID 1700): postgres.js returns as string for precision safety.
|
|
554
|
-
// PostgREST returns as JSON number — coerce when round-trip is exact, else keep string.
|
|
555
|
-
numeric: {
|
|
556
|
-
to: 1700,
|
|
557
|
-
from: [1700],
|
|
558
|
-
serialize: (x) => String(x),
|
|
559
|
-
parse: (x) => {
|
|
560
|
-
const n = Number(x);
|
|
561
|
-
if (Number.isFinite(n) && String(n) === x) return n;
|
|
562
|
-
return x;
|
|
563
|
-
}
|
|
564
|
-
},
|
|
565
|
-
// Date/time OIDs: keep as raw strings to mirror SQLite, which stores ISO text.
|
|
566
|
-
// Auth/storage code already uses Date.parse() on these, and the spec timestamp
|
|
567
|
-
// sentinel only matches strings.
|
|
568
|
-
date: {
|
|
569
|
-
to: 1082,
|
|
570
|
-
from: [1082],
|
|
571
|
-
serialize: (x) => x,
|
|
572
|
-
parse: (x) => x
|
|
573
|
-
},
|
|
574
|
-
time: {
|
|
575
|
-
to: 1083,
|
|
576
|
-
from: [1083],
|
|
577
|
-
serialize: (x) => x,
|
|
578
|
-
parse: (x) => x
|
|
579
|
-
},
|
|
580
|
-
timestamp: {
|
|
581
|
-
to: 1114,
|
|
582
|
-
from: [1114],
|
|
583
|
-
serialize: (x) => x,
|
|
584
|
-
parse: (x) => x
|
|
585
|
-
},
|
|
586
|
-
timestamptz: {
|
|
587
|
-
to: 1184,
|
|
588
|
-
from: [1184],
|
|
589
|
-
serialize: (x) => x,
|
|
590
|
-
parse: (x) => x
|
|
591
|
-
},
|
|
592
|
-
timetz: {
|
|
593
|
-
to: 1266,
|
|
594
|
-
from: [1266],
|
|
595
|
-
serialize: (x) => x,
|
|
596
|
-
parse: (x) => x
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
});
|
|
600
|
-
const dialect = new PostgresJSDialect({ postgres: this.driver });
|
|
601
|
-
this.kysely = new Kysely({ dialect });
|
|
602
|
-
}
|
|
603
|
-
async close() {
|
|
604
|
-
await this.driver.end();
|
|
605
|
-
}
|
|
606
|
-
};
|
|
607
|
-
function createPostgresConnection(config) {
|
|
608
|
-
return new PostgresConnection(config);
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
export { PostgresConnection, createPostgresConnection };
|
|
264
|
+
`.execute(this.kysely);for(let{nspname:s}of t.rows)await sql`GRANT USAGE ON SCHEMA ${sql.ref(s)} TO anon, authenticated`.execute(this.kysely),await sql.raw(`GRANT ALL ON ALL TABLES IN SCHEMA "${s}" TO anon, authenticated`).execute(this.kysely),await sql.raw(`GRANT ALL ON ALL SEQUENCES IN SCHEMA "${s}" TO anon, authenticated`).execute(this.kysely),await sql.raw(`ALTER DEFAULT PRIVILEGES IN SCHEMA "${s}" GRANT ALL ON TABLES TO anon, authenticated`).execute(this.kysely),await sql.raw(`ALTER DEFAULT PRIVILEGES IN SCHEMA "${s}" GRANT ALL ON SEQUENCES TO anon, authenticated`).execute(this.kysely);return true}async withContext(n,o,t){let s=t?.forceRollback===true;if(!s&&!n)return o(this.kysely);let c=n?await this.ensureRlsContext():false;if(!s&&!c)return o(this.kysely);try{return await this.kysely.transaction().execute(async i=>{if(n&&c){let u=n.auth,p=u?.role||"anon",d=String(u?.uid??""),r=u?.jwt;await sql`SELECT set_config('role', ${p}, true)`.execute(i),await sql`SELECT set_config('request.jwt.claim.sub', ${d}, true)`.execute(i),await sql`SELECT set_config('request.jwt.claim.role', ${p}, true)`.execute(i),r&&typeof r=="object"&&await sql`SELECT set_config('request.jwt.claims', ${JSON.stringify(r)}, true)`.execute(i);}let l=await o(i);if(s)throw new E(l);return l})}catch(i){if(i instanceof E)return i.result;throw i}}async onPostgrestAST(n){if(!n.from)return n;let o=n.schema??"public",t=n.from,s=await this.introspect({useCache:true});if(!s.tables.some(c=>c.name===t&&c.schema===o)&&!s.views.some(c=>c.name===t&&c.schema===o))throw new RelationNotFoundError(o,t);return n}async transaction(n,o){await this.exec("BEGIN");try{for(let t of n)await this.exec(t);await this.exec("COMMIT");}catch(t){throw await this.exec("ROLLBACK"),t}finally{o?.intent==="migration"&&await this.clearSchemaCache();}}};var _=class extends N{driver;dialect="postgres";constructor(n){super(n),this.driver=x(n.url??"",{types:{bigint:{to:20,from:[20],serialize:t=>t.toString(),parse:t=>{let s=Number(t);return Number.isSafeInteger(s)?s:BigInt(t)}},json:{to:114,from:[114],serialize:t=>JSON.stringify(t),parse:t=>JSON.parse(t)},jsonb:{to:3802,from:[3802],serialize:t=>JSON.stringify(t),parse:t=>JSON.parse(t)},numeric:{to:1700,from:[1700],serialize:t=>String(t),parse:t=>{let s=Number(t);return Number.isFinite(s)&&String(s)===t?s:t}},date:{to:1082,from:[1082],serialize:t=>t,parse:t=>t},time:{to:1083,from:[1083],serialize:t=>t,parse:t=>t},timestamp:{to:1114,from:[1114],serialize:t=>t,parse:t=>t},timestamptz:{to:1184,from:[1184],serialize:t=>t,parse:t=>t},timetz:{to:1266,from:[1266],serialize:t=>t,parse:t=>t}}});let o=new PostgresJSDialect({postgres:this.driver});this.kysely=new Kysely({dialect:o});}async close(){await this.driver.end();}};function z(m){return new _(m)}export{_ as PostgresConnection,z as createPostgresConnection};
|