@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,13 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { PGlite } from '@electric-sql/pglite';
|
|
3
|
-
import { Kysely, sql, PostgresQueryCompiler, PostgresIntrospector, PostgresAdapter, CompiledQuery } from 'kysely';
|
|
4
|
-
import { Connection, invariant, RelationNotFoundError, DataLossError } from '@supabase/lite';
|
|
5
|
-
import { isn } from '@electric-sql/pglite/contrib/isn';
|
|
6
|
-
import { ltree } from '@electric-sql/pglite/contrib/ltree';
|
|
7
|
-
import { file_fdw } from '@electric-sql/pglite/contrib/file_fdw';
|
|
8
|
-
import { pgcrypto } from '@electric-sql/pglite/contrib/pgcrypto';
|
|
9
|
-
|
|
10
|
-
try {
|
|
1
|
+
import {PGlite}from'@electric-sql/pglite';export{PGlite}from'@electric-sql/pglite';import {Kysely,sql,PostgresQueryCompiler,PostgresIntrospector,PostgresAdapter,CompiledQuery}from'kysely';import {Connection,invariant,RelationNotFoundError,DataLossError}from'@supabase/lite';import {isn}from'@electric-sql/pglite/contrib/isn';import {ltree}from'@electric-sql/pglite/contrib/ltree';import {file_fdw}from'@electric-sql/pglite/contrib/file_fdw';import {pgcrypto}from'@electric-sql/pglite/contrib/pgcrypto';try {
|
|
11
2
|
/**
|
|
12
3
|
* Adding this to avoid warnings from node:sqlite being experimental
|
|
13
4
|
*/
|
|
@@ -17,112 +8,8 @@ try {
|
|
|
17
8
|
return emitWarning(warning, ...args);
|
|
18
9
|
};
|
|
19
10
|
} catch {}
|
|
20
|
-
async function
|
|
21
|
-
|
|
22
|
-
if (typeof dataDir === "string") {
|
|
23
|
-
path = dataDir;
|
|
24
|
-
}
|
|
25
|
-
if (typeof dataDir === "object" && dataDir.dataDir) {
|
|
26
|
-
path = dataDir.dataDir;
|
|
27
|
-
}
|
|
28
|
-
if (path) {
|
|
29
|
-
const { mkdir } = await import('node:fs');
|
|
30
|
-
mkdir(path, { recursive: true }, (err) => {
|
|
31
|
-
if (err) {
|
|
32
|
-
throw err;
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
var PGliteDriver = class {
|
|
38
|
-
#client;
|
|
39
|
-
#ownsClient;
|
|
40
|
-
constructor(client, ownsClient) {
|
|
41
|
-
this.#client = client;
|
|
42
|
-
this.#ownsClient = ownsClient;
|
|
43
|
-
}
|
|
44
|
-
async acquireConnection() {
|
|
45
|
-
return new PGliteConnection(this.#client);
|
|
46
|
-
}
|
|
47
|
-
async beginTransaction(connection, _settings) {
|
|
48
|
-
await connection.executeQuery(CompiledQuery.raw("BEGIN"));
|
|
49
|
-
}
|
|
50
|
-
async commitTransaction(connection) {
|
|
51
|
-
await connection.executeQuery(CompiledQuery.raw("COMMIT"));
|
|
52
|
-
}
|
|
53
|
-
async rollbackTransaction(connection) {
|
|
54
|
-
await connection.executeQuery(CompiledQuery.raw("ROLLBACK"));
|
|
55
|
-
}
|
|
56
|
-
async destroy() {
|
|
57
|
-
if (this.#ownsClient) {
|
|
58
|
-
await this.#client.close();
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
async init() {
|
|
62
|
-
}
|
|
63
|
-
async releaseConnection(_connection) {
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
var PGliteConnection = class {
|
|
67
|
-
#client;
|
|
68
|
-
constructor(client) {
|
|
69
|
-
this.#client = client;
|
|
70
|
-
}
|
|
71
|
-
async executeQuery(compiledQuery) {
|
|
72
|
-
const result = await this.#client.query(compiledQuery.sql, [...compiledQuery.parameters]);
|
|
73
|
-
const affected = result.affectedRows;
|
|
74
|
-
return {
|
|
75
|
-
rows: result.rows,
|
|
76
|
-
numAffectedRows: typeof affected === "number" ? BigInt(affected) : void 0
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
// biome-ignore lint/correctness/useYield: .
|
|
80
|
-
async *streamQuery() {
|
|
81
|
-
throw new Error("PGlite does not support streaming.");
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
var KyselyPglite = class {
|
|
85
|
-
client;
|
|
86
|
-
#ownsClient = true;
|
|
87
|
-
constructor(dataDirOrOptionsOrPGlite, opts) {
|
|
88
|
-
void ensureDataDirExist(dataDirOrOptionsOrPGlite);
|
|
89
|
-
let options = { ...opts };
|
|
90
|
-
if (typeof dataDirOrOptionsOrPGlite === "object" && dataDirOrOptionsOrPGlite instanceof PGlite) {
|
|
91
|
-
this.client = dataDirOrOptionsOrPGlite;
|
|
92
|
-
this.#ownsClient = false;
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
if (typeof dataDirOrOptionsOrPGlite === "string") {
|
|
96
|
-
options = {
|
|
97
|
-
dataDir: dataDirOrOptionsOrPGlite,
|
|
98
|
-
...options
|
|
99
|
-
};
|
|
100
|
-
} else {
|
|
101
|
-
options = dataDirOrOptionsOrPGlite ?? {};
|
|
102
|
-
}
|
|
103
|
-
this.client = new PGlite(options);
|
|
104
|
-
}
|
|
105
|
-
dialect = {
|
|
106
|
-
createAdapter: () => new PostgresAdapter(),
|
|
107
|
-
createDriver: () => new PGliteDriver(this.client, this.#ownsClient),
|
|
108
|
-
createIntrospector: (db) => new PostgresIntrospector(db),
|
|
109
|
-
createQueryCompiler: () => new PostgresQueryCompiler()
|
|
110
|
-
};
|
|
111
|
-
};
|
|
112
|
-
var ForceRollback = class extends Error {
|
|
113
|
-
constructor(result) {
|
|
114
|
-
super("Force rollback");
|
|
115
|
-
this.result = result;
|
|
116
|
-
}
|
|
117
|
-
};
|
|
118
|
-
var BasePostgresConnection = class extends Connection {
|
|
119
|
-
dialect = "postgres";
|
|
120
|
-
constructor(options) {
|
|
121
|
-
super({
|
|
122
|
-
...options,
|
|
123
|
-
// @todo: this should be handled by the auth schema
|
|
124
|
-
baseSchema: `
|
|
125
|
-
${options.baseSchema ?? ""}
|
|
11
|
+
async function B(n){let e;if(typeof n=="string"&&(e=n),typeof n=="object"&&n.dataDir&&(e=n.dataDir),e){let{mkdir:a}=await import('node:fs');a(e,{recursive:true},o=>{if(o)throw o});}}var N=class{#e;#t;constructor(e,a){this.#e=e,this.#t=a;}async acquireConnection(){return new _(this.#e)}async beginTransaction(e,a){await e.executeQuery(CompiledQuery.raw("BEGIN"));}async commitTransaction(e){await e.executeQuery(CompiledQuery.raw("COMMIT"));}async rollbackTransaction(e){await e.executeQuery(CompiledQuery.raw("ROLLBACK"));}async destroy(){this.#t&&await this.#e.close();}async init(){}async releaseConnection(e){}},_=class{#e;constructor(e){this.#e=e;}async executeQuery(e){let a=await this.#e.query(e.sql,[...e.parameters]),o=a.affectedRows;return {rows:a.rows,numAffectedRows:typeof o=="number"?BigInt(o):void 0}}async*streamQuery(){throw new Error("PGlite does not support streaming.")}},d=class{client;#e=true;constructor(e,a){B(e);let o={...a};if(typeof e=="object"&&e instanceof PGlite){this.client=e,this.#e=false;return}typeof e=="string"?o={dataDir:e,...o}:o=e??{},this.client=new PGlite(o);}dialect={createAdapter:()=>new PostgresAdapter,createDriver:()=>new N(this.client,this.#e),createIntrospector:e=>new PostgresIntrospector(e),createQueryCompiler:()=>new PostgresQueryCompiler}};var y=class extends Error{constructor(a){super("Force rollback");this.result=a;}},g=class extends Connection{dialect="postgres";constructor(e){super({...e,baseSchema:`
|
|
12
|
+
${e.baseSchema??""}
|
|
126
13
|
|
|
127
14
|
CREATE SCHEMA IF NOT EXISTS auth;
|
|
128
15
|
|
|
@@ -148,16 +35,7 @@ var BasePostgresConnection = class extends Connection {
|
|
|
148
35
|
'{}'
|
|
149
36
|
)::jsonb;
|
|
150
37
|
$$ LANGUAGE SQL STABLE;
|
|
151
|
-
`
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
async introspect(options) {
|
|
155
|
-
invariant(typeof options === "object" || options === void 0, "options must be an object");
|
|
156
|
-
const useCache = options?.useCache ?? false;
|
|
157
|
-
const cached = await this.readCachedIntrospection({ useCache });
|
|
158
|
-
if (cached) return cached;
|
|
159
|
-
try {
|
|
160
|
-
const tblResult = await sql`
|
|
38
|
+
`});}async introspect(e){invariant(typeof e=="object"||e===void 0,"options must be an object");let a=e?.useCache??false,o=await this.readCachedIntrospection({useCache:a});if(o)return o;try{let i=(await sql`
|
|
161
39
|
SELECT
|
|
162
40
|
tbls.table_name AS "name",
|
|
163
41
|
tbls.table_schema AS "schema",
|
|
@@ -170,17 +48,7 @@ var BasePostgresConnection = class extends Connection {
|
|
|
170
48
|
tbls.table_schema NOT IN ('information_schema', 'pg_catalog')
|
|
171
49
|
AND tbls.table_type IN ('BASE TABLE', 'FOREIGN TABLE')
|
|
172
50
|
ORDER BY tbls.table_schema, tbls.table_name
|
|
173
|
-
`.execute(this.kysely)
|
|
174
|
-
const tables = tblResult.rows.map((r) => ({
|
|
175
|
-
name: r.name,
|
|
176
|
-
schema: r.schema,
|
|
177
|
-
type: "table",
|
|
178
|
-
rows: Number(r.rows),
|
|
179
|
-
sql: "",
|
|
180
|
-
engine: "",
|
|
181
|
-
collation: ""
|
|
182
|
-
}));
|
|
183
|
-
const colResult = await sql`
|
|
51
|
+
`.execute(this.kysely)).rows.map(t=>({name:t.name,schema:t.schema,type:"table",rows:Number(t.rows),sql:"",engine:"",collation:""})),m=(await sql`
|
|
184
52
|
SELECT
|
|
185
53
|
cols.table_name AS "table",
|
|
186
54
|
cols.table_schema AS "schema",
|
|
@@ -232,25 +100,7 @@ var BasePostgresConnection = class extends Connection {
|
|
|
232
100
|
LEFT JOIN pg_catalog.pg_type pt ON pt.oid = attr.atttypid
|
|
233
101
|
WHERE cols.table_schema NOT IN ('information_schema', 'pg_catalog')
|
|
234
102
|
ORDER BY cols.table_schema, cols.table_name, cols.ordinal_position
|
|
235
|
-
`.execute(this.kysely)
|
|
236
|
-
const columns = colResult.rows.map((r) => ({
|
|
237
|
-
table: r.table,
|
|
238
|
-
schema: r.schema,
|
|
239
|
-
name: r.name,
|
|
240
|
-
type: r.type,
|
|
241
|
-
nullable: r.nullable,
|
|
242
|
-
default_value: r.default_value,
|
|
243
|
-
is_primary_key: false,
|
|
244
|
-
// filled below
|
|
245
|
-
ordinal_position: Number(r.ordinal_position),
|
|
246
|
-
character_maximum_length: r.character_maximum_length ?? null,
|
|
247
|
-
precision: r.precision ?? null,
|
|
248
|
-
is_identity: r.is_identity,
|
|
249
|
-
collation: r.collation,
|
|
250
|
-
pg_type: r.udt_name ?? void 0,
|
|
251
|
-
is_generated: r.is_generated ?? false
|
|
252
|
-
}));
|
|
253
|
-
const fkResult = await sql`
|
|
103
|
+
`.execute(this.kysely)).rows.map(t=>({table:t.table,schema:t.schema,name:t.name,type:t.type,nullable:t.nullable,default_value:t.default_value,is_primary_key:!1,ordinal_position:Number(t.ordinal_position),character_maximum_length:t.character_maximum_length??null,precision:t.precision??null,is_identity:t.is_identity,collation:t.collation,pg_type:t.udt_name??void 0,is_generated:t.is_generated??!1})),p=(await sql`
|
|
254
104
|
SELECT
|
|
255
105
|
ns.nspname AS "schema",
|
|
256
106
|
cl.relname AS "table",
|
|
@@ -275,19 +125,7 @@ var BasePostgresConnection = class extends Connection {
|
|
|
275
125
|
'information_schema'
|
|
276
126
|
, 'pg_catalog')
|
|
277
127
|
ORDER BY ns.nspname, cl.relname, con.conname, cols.ord
|
|
278
|
-
`.execute(this.kysely)
|
|
279
|
-
const fks = fkResult.rows.map((r) => ({
|
|
280
|
-
table: r.table,
|
|
281
|
-
column: r.column,
|
|
282
|
-
schema: r.schema,
|
|
283
|
-
ref_table: r.ref_table,
|
|
284
|
-
ref_column: r.ref_column,
|
|
285
|
-
foreign_key_name: r.foreign_key_name,
|
|
286
|
-
fk_def: r.fk_def,
|
|
287
|
-
on_update: "",
|
|
288
|
-
on_delete: ""
|
|
289
|
-
}));
|
|
290
|
-
const pkResult = await sql`
|
|
128
|
+
`.execute(this.kysely)).rows.map(t=>({table:t.table,column:t.column,schema:t.schema,ref_table:t.ref_table,ref_column:t.ref_column,foreign_key_name:t.foreign_key_name,fk_def:t.fk_def,on_update:"",on_delete:""})),u=(await sql`
|
|
291
129
|
SELECT
|
|
292
130
|
ns.nspname AS "schema",
|
|
293
131
|
cl.relname AS "table",
|
|
@@ -304,20 +142,7 @@ var BasePostgresConnection = class extends Connection {
|
|
|
304
142
|
'information_schema'
|
|
305
143
|
, 'pg_catalog')
|
|
306
144
|
GROUP BY ns.nspname, cl.relname, con.oid
|
|
307
|
-
`.execute(this.kysely);
|
|
308
|
-
const pks = pkResult.rows.map((r) => ({
|
|
309
|
-
table: r.table,
|
|
310
|
-
columns: r.columns,
|
|
311
|
-
schema: r.schema,
|
|
312
|
-
field_count: r.columns.length
|
|
313
|
-
}));
|
|
314
|
-
const pkSet = new Set(
|
|
315
|
-
pks.flatMap((pk) => pk.columns.map((col) => `${pk.schema}.${pk.table}.${col}`))
|
|
316
|
-
);
|
|
317
|
-
for (const col of columns) {
|
|
318
|
-
col.is_primary_key = pkSet.has(`${col.schema}.${col.table}.${col.name}`);
|
|
319
|
-
}
|
|
320
|
-
const idxResult = await sql`
|
|
145
|
+
`.execute(this.kysely)).rows.map(t=>({table:t.table,columns:t.columns,schema:t.schema,field_count:t.columns.length})),T=new Set(u.flatMap(t=>t.columns.map(v=>`${t.schema}.${t.table}.${v}`)));for(let t of m)t.is_primary_key=T.has(`${t.schema}.${t.table}.${t.name}`);let L=(await sql`
|
|
321
146
|
SELECT
|
|
322
147
|
tnsp.nspname AS "schema",
|
|
323
148
|
cl.relname AS "table",
|
|
@@ -338,15 +163,7 @@ var BasePostgresConnection = class extends Connection {
|
|
|
338
163
|
'information_schema'
|
|
339
164
|
, 'pg_catalog')
|
|
340
165
|
GROUP BY tnsp.nspname, cl.relname, ic.relname, idx.indisunique
|
|
341
|
-
`.execute(this.kysely)
|
|
342
|
-
const indexes = idxResult.rows.map((r) => ({
|
|
343
|
-
table: r.table,
|
|
344
|
-
name: r.name,
|
|
345
|
-
unique: r.unique,
|
|
346
|
-
columns: r.columns,
|
|
347
|
-
schema: r.schema
|
|
348
|
-
}));
|
|
349
|
-
const viewResult = await sql`
|
|
166
|
+
`.execute(this.kysely)).rows.map(t=>({table:t.table,name:t.name,unique:t.unique,columns:t.columns,schema:t.schema})),C=(await sql`
|
|
350
167
|
SELECT
|
|
351
168
|
views.schemaname AS "schema",
|
|
352
169
|
views.viewname AS "name",
|
|
@@ -354,13 +171,7 @@ var BasePostgresConnection = class extends Connection {
|
|
|
354
171
|
FROM pg_views views
|
|
355
172
|
WHERE views.schemaname NOT IN ('information_schema', 'pg_catalog')
|
|
356
173
|
ORDER BY views.schemaname, views.viewname
|
|
357
|
-
`.execute(this.kysely)
|
|
358
|
-
const views = viewResult.rows.map((r) => ({
|
|
359
|
-
name: r.name,
|
|
360
|
-
schema: r.schema,
|
|
361
|
-
sql: r.sql ?? ""
|
|
362
|
-
}));
|
|
363
|
-
const chkResult = await sql`
|
|
174
|
+
`.execute(this.kysely)).rows.map(t=>({name:t.name,schema:t.schema,sql:t.sql??""})),I=(await sql`
|
|
364
175
|
SELECT
|
|
365
176
|
n.nspname AS "schema",
|
|
366
177
|
cl.relname AS "table",
|
|
@@ -372,13 +183,7 @@ var BasePostgresConnection = class extends Connection {
|
|
|
372
183
|
c.contype = 'c'
|
|
373
184
|
AND n.nspname NOT IN ('information_schema', 'pg_catalog')
|
|
374
185
|
ORDER BY n.nspname, cl.relname
|
|
375
|
-
`.execute(this.kysely)
|
|
376
|
-
const checkConstraints = chkResult.rows.map((r) => ({
|
|
377
|
-
schema: r.schema,
|
|
378
|
-
table: r.table,
|
|
379
|
-
expression: r.expression ?? ""
|
|
380
|
-
}));
|
|
381
|
-
const uqResult = await sql`
|
|
186
|
+
`.execute(this.kysely)).rows.map(t=>({schema:t.schema,table:t.table,expression:t.expression??""})),x=(await sql`
|
|
382
187
|
SELECT
|
|
383
188
|
n.nspname AS "schema",
|
|
384
189
|
cl.relname AS "table",
|
|
@@ -393,14 +198,7 @@ var BasePostgresConnection = class extends Connection {
|
|
|
393
198
|
c.contype = 'u'
|
|
394
199
|
AND n.nspname NOT IN ('information_schema', 'pg_catalog')
|
|
395
200
|
GROUP BY n.nspname, cl.relname, c.conname, c.oid
|
|
396
|
-
`.execute(this.kysely)
|
|
397
|
-
const uniqueConstraints = uqResult.rows.map((r) => ({
|
|
398
|
-
schema: r.schema,
|
|
399
|
-
table: r.table,
|
|
400
|
-
name: r.name,
|
|
401
|
-
columns: r.columns
|
|
402
|
-
}));
|
|
403
|
-
const commentResult = await sql`
|
|
201
|
+
`.execute(this.kysely)).rows.map(t=>({schema:t.schema,table:t.table,name:t.name,columns:t.columns})),k=(await sql`
|
|
404
202
|
SELECT
|
|
405
203
|
n.nspname AS "schema",
|
|
406
204
|
cl.relname AS "table",
|
|
@@ -415,14 +213,7 @@ var BasePostgresConnection = class extends Connection {
|
|
|
415
213
|
n.nspname NOT IN ('information_schema', 'pg_catalog')
|
|
416
214
|
AND cl.relkind IN ('r', 'v', 'm', 'f', 'p')
|
|
417
215
|
AND d.description IS NOT NULL
|
|
418
|
-
`.execute(this.kysely)
|
|
419
|
-
const comments = commentResult.rows.map((r) => ({
|
|
420
|
-
schema: r.schema,
|
|
421
|
-
table: r.table,
|
|
422
|
-
column: r.column ?? void 0,
|
|
423
|
-
text: r.text
|
|
424
|
-
}));
|
|
425
|
-
const enumResult = await sql`
|
|
216
|
+
`.execute(this.kysely)).rows.map(t=>({schema:t.schema,table:t.table,column:t.column??void 0,text:t.text})),D=await sql`
|
|
426
217
|
SELECT
|
|
427
218
|
n.nspname AS "schema",
|
|
428
219
|
t.typname AS "type",
|
|
@@ -433,8 +224,7 @@ var BasePostgresConnection = class extends Connection {
|
|
|
433
224
|
JOIN pg_namespace n ON n.oid = t.typnamespace
|
|
434
225
|
WHERE n.nspname NOT IN ('pg_catalog', 'information_schema')
|
|
435
226
|
GROUP BY n.nspname, t.typname
|
|
436
|
-
`.execute(this.kysely)
|
|
437
|
-
const compositeResult = await sql`
|
|
227
|
+
`.execute(this.kysely),P=await sql`
|
|
438
228
|
SELECT
|
|
439
229
|
n.nspname AS "schema",
|
|
440
230
|
t.typname AS "type",
|
|
@@ -456,76 +246,9 @@ var BasePostgresConnection = class extends Connection {
|
|
|
456
246
|
AND NOT a.attisdropped
|
|
457
247
|
AND n.nspname NOT IN ('pg_catalog', 'information_schema')
|
|
458
248
|
GROUP BY n.nspname, t.typname
|
|
459
|
-
`.execute(this.kysely);
|
|
460
|
-
const customTypes = [
|
|
461
|
-
...enumResult.rows.map((r) => ({
|
|
462
|
-
schema: r.schema,
|
|
463
|
-
type: r.type,
|
|
464
|
-
kind: "enum",
|
|
465
|
-
values: r.values
|
|
466
|
-
})),
|
|
467
|
-
...compositeResult.rows.map((r) => ({
|
|
468
|
-
schema: r.schema,
|
|
469
|
-
type: r.type,
|
|
470
|
-
kind: "composite",
|
|
471
|
-
fields: r.fields
|
|
472
|
-
}))
|
|
473
|
-
];
|
|
474
|
-
const dbResult = await sql`SELECT current_database() AS "name"`.execute(this.kysely);
|
|
475
|
-
const dbName = dbResult.rows[0]?.name ?? "postgres";
|
|
476
|
-
const result = {
|
|
477
|
-
tables,
|
|
478
|
-
columns,
|
|
479
|
-
indexes,
|
|
480
|
-
foreign_keys: fks,
|
|
481
|
-
primary_keys: pks,
|
|
482
|
-
views,
|
|
483
|
-
triggers: [],
|
|
484
|
-
check_constraints: checkConstraints,
|
|
485
|
-
unique_constraints: uniqueConstraints,
|
|
486
|
-
comments,
|
|
487
|
-
custom_types: customTypes,
|
|
488
|
-
database_name: dbName,
|
|
489
|
-
version: ""
|
|
490
|
-
};
|
|
491
|
-
await this.writeCachedIntrospection(result, { useDriver: useCache });
|
|
492
|
-
return result;
|
|
493
|
-
} catch (e) {
|
|
494
|
-
console.error("Introspection failed:", e);
|
|
495
|
-
return {
|
|
496
|
-
tables: [],
|
|
497
|
-
columns: [],
|
|
498
|
-
indexes: [],
|
|
499
|
-
foreign_keys: [],
|
|
500
|
-
primary_keys: [],
|
|
501
|
-
views: [],
|
|
502
|
-
triggers: [],
|
|
503
|
-
check_constraints: [],
|
|
504
|
-
unique_constraints: [],
|
|
505
|
-
comments: [],
|
|
506
|
-
custom_types: [],
|
|
507
|
-
database_name: "postgres",
|
|
508
|
-
version: ""
|
|
509
|
-
};
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
rlsState = "unknown";
|
|
513
|
-
/**
|
|
514
|
-
* Detect if any table has RLS enabled, and if so ensure anon/authenticated
|
|
515
|
-
* roles exist with default privileges. Runs once per connection.
|
|
516
|
-
*/
|
|
517
|
-
async ensureRlsContext() {
|
|
518
|
-
if (this.rlsState !== "unknown") return this.rlsState === "active";
|
|
519
|
-
const result = await sql`
|
|
249
|
+
`.execute(this.kysely),H=[...D.rows.map(t=>({schema:t.schema,type:t.type,kind:"enum",values:t.values})),...P.rows.map(t=>({schema:t.schema,type:t.type,kind:"composite",fields:t.fields}))],F=(await sql`SELECT current_database() AS "name"`.execute(this.kysely)).rows[0]?.name??"postgres",A={tables:i,columns:m,indexes:L,foreign_keys:p,primary_keys:u,views:C,triggers:[],check_constraints:I,unique_constraints:x,comments:k,custom_types:H,database_name:F,version:""};return await this.writeCachedIntrospection(A,{useDriver:a}),A}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 e=await sql`
|
|
520
250
|
SELECT count(*) ::text as count FROM pg_class WHERE relrowsecurity = true
|
|
521
|
-
`.execute(this.kysely);
|
|
522
|
-
const hasRls = Number(result.rows[0]?.count ?? 0) > 0;
|
|
523
|
-
if (!hasRls) {
|
|
524
|
-
this.rlsState = "inactive";
|
|
525
|
-
return false;
|
|
526
|
-
}
|
|
527
|
-
this.rlsState = "active";
|
|
528
|
-
await sql`
|
|
251
|
+
`.execute(this.kysely);if(!(Number(e.rows[0]?.count??0)>0))return this.rlsState="inactive",false;this.rlsState="active",await sql`
|
|
529
252
|
DO $$ BEGIN
|
|
530
253
|
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'anon') THEN
|
|
531
254
|
CREATE ROLE anon NOLOGIN;
|
|
@@ -534,357 +257,12 @@ var BasePostgresConnection = class extends Connection {
|
|
|
534
257
|
CREATE ROLE authenticated NOLOGIN;
|
|
535
258
|
END IF;
|
|
536
259
|
END $$
|
|
537
|
-
`.execute(this.kysely);
|
|
538
|
-
const schemas = await sql`
|
|
260
|
+
`.execute(this.kysely);let o=await sql`
|
|
539
261
|
SELECT DISTINCT n.nspname FROM pg_class c
|
|
540
262
|
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
541
263
|
WHERE c.relrowsecurity = true
|
|
542
|
-
`.execute(this.kysely);
|
|
543
|
-
for (const { nspname } of schemas.rows) {
|
|
544
|
-
await sql`GRANT USAGE ON SCHEMA ${sql.ref(nspname)} TO anon, authenticated`.execute(
|
|
545
|
-
this.kysely
|
|
546
|
-
);
|
|
547
|
-
await sql.raw(`GRANT ALL ON ALL TABLES IN SCHEMA "${nspname}" TO anon, authenticated`).execute(this.kysely);
|
|
548
|
-
await sql.raw(`GRANT ALL ON ALL SEQUENCES IN SCHEMA "${nspname}" TO anon, authenticated`).execute(this.kysely);
|
|
549
|
-
await sql.raw(
|
|
550
|
-
`ALTER DEFAULT PRIVILEGES IN SCHEMA "${nspname}" GRANT ALL ON TABLES TO anon, authenticated`
|
|
551
|
-
).execute(this.kysely);
|
|
552
|
-
await sql.raw(
|
|
553
|
-
`ALTER DEFAULT PRIVILEGES IN SCHEMA "${nspname}" GRANT ALL ON SEQUENCES TO anon, authenticated`
|
|
554
|
-
).execute(this.kysely);
|
|
555
|
-
}
|
|
556
|
-
return true;
|
|
557
|
-
}
|
|
558
|
-
async withContext(vars, fn, opts) {
|
|
559
|
-
const forceRollback = opts?.forceRollback === true;
|
|
560
|
-
if (!forceRollback && !vars) return fn(this.kysely);
|
|
561
|
-
const rlsActive = vars ? await this.ensureRlsContext() : false;
|
|
562
|
-
if (!forceRollback && !rlsActive) return fn(this.kysely);
|
|
563
|
-
try {
|
|
564
|
-
return await this.kysely.transaction().execute(async (trx) => {
|
|
565
|
-
if (vars && rlsActive) {
|
|
566
|
-
const auth = vars.auth;
|
|
567
|
-
const role = auth?.role || "anon";
|
|
568
|
-
const uid = String(auth?.uid ?? "");
|
|
569
|
-
const jwt = auth?.jwt;
|
|
570
|
-
await sql`SELECT set_config('role', ${role}, true)`.execute(trx);
|
|
571
|
-
await sql`SELECT set_config('request.jwt.claim.sub', ${uid}, true)`.execute(trx);
|
|
572
|
-
await sql`SELECT set_config('request.jwt.claim.role', ${role}, true)`.execute(trx);
|
|
573
|
-
if (jwt && typeof jwt === "object") {
|
|
574
|
-
await sql`SELECT set_config('request.jwt.claims', ${JSON.stringify(jwt)}, true)`.execute(
|
|
575
|
-
trx
|
|
576
|
-
);
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
const result = await fn(trx);
|
|
580
|
-
if (forceRollback) throw new ForceRollback(result);
|
|
581
|
-
return result;
|
|
582
|
-
});
|
|
583
|
-
} catch (error) {
|
|
584
|
-
if (error instanceof ForceRollback) return error.result;
|
|
585
|
-
throw error;
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
async onPostgrestAST(ast) {
|
|
589
|
-
if (!ast.from) return ast;
|
|
590
|
-
const schema = ast.schema ?? "public";
|
|
591
|
-
const relation = ast.from;
|
|
592
|
-
const introspection = await this.introspect({ useCache: true });
|
|
593
|
-
if (!introspection.tables.some((t) => t.name === relation && t.schema === schema) && !introspection.views.some((v) => v.name === relation && v.schema === schema)) {
|
|
594
|
-
throw new RelationNotFoundError(schema, relation);
|
|
595
|
-
}
|
|
596
|
-
return ast;
|
|
597
|
-
}
|
|
598
|
-
async transaction(statements, opts) {
|
|
599
|
-
await this.exec("BEGIN");
|
|
600
|
-
try {
|
|
601
|
-
for (const statement of statements) {
|
|
602
|
-
await this.exec(statement);
|
|
603
|
-
}
|
|
604
|
-
await this.exec("COMMIT");
|
|
605
|
-
} catch (error) {
|
|
606
|
-
await this.exec("ROLLBACK");
|
|
607
|
-
throw error;
|
|
608
|
-
} finally {
|
|
609
|
-
if (opts?.intent === "migration") {
|
|
610
|
-
await this.clearSchemaCache();
|
|
611
|
-
}
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
};
|
|
615
|
-
|
|
616
|
-
// src/db/postgres/migration/pgdelta-pglite.ts
|
|
617
|
-
var parseArray = (value, parseElement = (entry) => entry) => {
|
|
618
|
-
if (!value || value === "{}") return [];
|
|
619
|
-
const inner = value.slice(1, -1);
|
|
620
|
-
if (inner === "") return [];
|
|
621
|
-
const result = [];
|
|
622
|
-
let current = "";
|
|
623
|
-
let inQuotes = false;
|
|
624
|
-
let depth = 0;
|
|
625
|
-
for (let i = 0; i < inner.length; i++) {
|
|
626
|
-
const char = inner[i];
|
|
627
|
-
if (char === '"' && inner[i - 1] !== "\\") {
|
|
628
|
-
inQuotes = !inQuotes;
|
|
629
|
-
current += char;
|
|
630
|
-
} else if (char === "{" && !inQuotes) {
|
|
631
|
-
depth++;
|
|
632
|
-
current += char;
|
|
633
|
-
} else if (char === "}" && !inQuotes) {
|
|
634
|
-
depth--;
|
|
635
|
-
current += char;
|
|
636
|
-
} else if (char === "," && !inQuotes && depth === 0) {
|
|
637
|
-
result.push(parseElement(current));
|
|
638
|
-
current = "";
|
|
639
|
-
} else {
|
|
640
|
-
current += char;
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
if (current !== "") {
|
|
644
|
-
result.push(parseElement(current));
|
|
645
|
-
}
|
|
646
|
-
return result;
|
|
647
|
-
};
|
|
648
|
-
var parseStringElement = (value) => {
|
|
649
|
-
if (value === "NULL") return null;
|
|
650
|
-
if (value.startsWith('"') && value.endsWith('"')) {
|
|
651
|
-
return value.slice(1, -1).replace(/\\(.)/g, "$1");
|
|
652
|
-
}
|
|
653
|
-
return value;
|
|
654
|
-
};
|
|
655
|
-
var parseIntElement = (value) => {
|
|
656
|
-
if (value === "NULL") return null;
|
|
657
|
-
return Number.parseInt(value, 10);
|
|
658
|
-
};
|
|
659
|
-
function isSqlTagLike(value) {
|
|
660
|
-
return typeof value === "object" && value !== null && "text" in value && "values" in value;
|
|
661
|
-
}
|
|
662
|
-
function normalizeValue(value, dataTypeID) {
|
|
663
|
-
if (value === null || value === void 0) return value;
|
|
664
|
-
switch (dataTypeID) {
|
|
665
|
-
case 20:
|
|
666
|
-
return typeof value === "bigint" ? value : BigInt(value);
|
|
667
|
-
case 22:
|
|
668
|
-
if (Array.isArray(value)) return value;
|
|
669
|
-
if (typeof value === "string") {
|
|
670
|
-
return value.split(" ").map(Number).filter((entry) => !Number.isNaN(entry));
|
|
671
|
-
}
|
|
672
|
-
return value;
|
|
673
|
-
case 1002:
|
|
674
|
-
case 1009:
|
|
675
|
-
case 1015:
|
|
676
|
-
return typeof value === "string" ? parseArray(value, parseStringElement) : value;
|
|
677
|
-
case 1005:
|
|
678
|
-
case 1007:
|
|
679
|
-
case 1016:
|
|
680
|
-
return typeof value === "string" ? parseArray(value, parseIntElement) : value;
|
|
681
|
-
default:
|
|
682
|
-
return value;
|
|
683
|
-
}
|
|
684
|
-
}
|
|
685
|
-
function pgDeltaQueryable(db) {
|
|
686
|
-
return {
|
|
687
|
-
async query(input, values) {
|
|
688
|
-
const sql3 = isSqlTagLike(input) ? input.text : input;
|
|
689
|
-
const parameters = isSqlTagLike(input) ? input.values : values ?? [];
|
|
690
|
-
const result = await db.driver.query(sql3, [...parameters]);
|
|
691
|
-
const rows = result.rows.map(
|
|
692
|
-
(row) => Object.fromEntries(
|
|
693
|
-
result.fields.map((field) => [
|
|
694
|
-
field.name,
|
|
695
|
-
normalizeValue(row[field.name], field.dataTypeID)
|
|
696
|
-
])
|
|
697
|
-
)
|
|
698
|
-
);
|
|
699
|
-
return {
|
|
700
|
-
rows
|
|
701
|
-
};
|
|
702
|
-
}
|
|
703
|
-
};
|
|
704
|
-
}
|
|
264
|
+
`.execute(this.kysely);for(let{nspname:s}of o.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(e,a,o){let s=o?.forceRollback===true;if(!s&&!e)return a(this.kysely);let i=e?await this.ensureRlsContext():false;if(!s&&!i)return a(this.kysely);try{return await this.kysely.transaction().execute(async c=>{if(e&&i){let l=e.auth,p=l?.role||"anon",w=String(l?.uid??""),u=l?.jwt;await sql`SELECT set_config('role', ${p}, true)`.execute(c),await sql`SELECT set_config('request.jwt.claim.sub', ${w}, true)`.execute(c),await sql`SELECT set_config('request.jwt.claim.role', ${p}, true)`.execute(c),u&&typeof u=="object"&&await sql`SELECT set_config('request.jwt.claims', ${JSON.stringify(u)}, true)`.execute(c);}let m=await a(c);if(s)throw new y(m);return m})}catch(c){if(c instanceof y)return c.result;throw c}}async onPostgrestAST(e){if(!e.from)return e;let a=e.schema??"public",o=e.from,s=await this.introspect({useCache:true});if(!s.tables.some(i=>i.name===o&&i.schema===a)&&!s.views.some(i=>i.name===o&&i.schema===a))throw new RelationNotFoundError(a,o);return e}async transaction(e,a){await this.exec("BEGIN");try{for(let o of e)await this.exec(o);await this.exec("COMMIT");}catch(o){throw await this.exec("ROLLBACK"),o}finally{a?.intent==="migration"&&await this.clearSchemaCache();}}};var R=(n,e=a=>a)=>{if(!n||n==="{}")return [];let a=n.slice(1,-1);if(a==="")return [];let o=[],s="",i=false,c=0;for(let m=0;m<a.length;m++){let l=a[m];l==='"'&&a[m-1]!=="\\"?(i=!i,s+=l):l==="{"&&!i?(c++,s+=l):l==="}"&&!i?(c--,s+=l):l===","&&!i&&c===0?(o.push(e(s)),s=""):s+=l;}return s!==""&&o.push(e(s)),o},M=n=>n==="NULL"?null:n.startsWith('"')&&n.endsWith('"')?n.slice(1,-1).replace(/\\(.)/g,"$1"):n,j=n=>n==="NULL"?null:Number.parseInt(n,10);function b(n){return typeof n=="object"&&n!==null&&"text"in n&&"values"in n}function Q(n,e){if(n==null)return n;switch(e){case 20:return typeof n=="bigint"?n:BigInt(n);case 22:return Array.isArray(n)?n:typeof n=="string"?n.split(" ").map(Number).filter(a=>!Number.isNaN(a)):n;case 1002:case 1009:case 1015:return typeof n=="string"?R(n,M):n;case 1005:case 1007:case 1016:return typeof n=="string"?R(n,j):n;default:return n}}function h(n){return {async query(e,a){let o=b(e)?e.text:e,s=b(e)?e.values:a??[],i=await n.driver.query(o,[...s]);return {rows:i.rows.map(m=>Object.fromEntries(i.fields.map(l=>[l.name,Q(m[l.name],l.dataTypeID)])))}}}}async function K(){try{return await import('@supabase/pg-delta')}catch(n){throw new Error("Postgres/PGlite schema diffing now requires a Bun/Node-compatible runtime with pg-delta available.",{cause:n})}}function V(n){let e=/^drop table (.+)$/.exec(n);if(e)return {table:e[1],reason:"drop table"};let a=/^drop column (.+) on (.+)$/.exec(n);if(a)return {table:a[2],reason:`drop column ${a[1]}`};let o=/^drop sequence (.+)$/.exec(n);return o?{table:o[1],reason:"drop sequence"}:{table:"unknown",reason:n}}var E=class{constructor(e,a){this.from=e;this.desiredSchema=a;}#e;async#t(e){if(this.#e)return this.#e;let a=new this.from.constructor;try{return await a.exec(this.desiredSchema),this.#e=await e(h(a)),this.#e}finally{await a.close();}}async diff(){let{createPlan:e,extractCatalog:a}=await K(),o=h(this.from),s=await this.#t(a),i=await a(o),c=await e(i,s);if(!c)return {diff:"",plan:{steps:[],warnings:[],unsafe:false}};let m=c.plan.risk?.level==="data_loss"?c.plan.risk.statements.map(V):[];return {diff:c.plan.statements.join(`
|
|
705
265
|
|
|
706
|
-
|
|
707
|
-
async function loadPgDelta() {
|
|
708
|
-
try {
|
|
709
|
-
return await import('@supabase/pg-delta');
|
|
710
|
-
} catch (error) {
|
|
711
|
-
throw new Error(
|
|
712
|
-
"Postgres/PGlite schema diffing now requires a Bun/Node-compatible runtime with pg-delta available.",
|
|
713
|
-
{ cause: error }
|
|
714
|
-
);
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
function parseRiskWarning(input) {
|
|
718
|
-
const dropTableMatch = /^drop table (.+)$/.exec(input);
|
|
719
|
-
if (dropTableMatch) {
|
|
720
|
-
return {
|
|
721
|
-
table: dropTableMatch[1],
|
|
722
|
-
reason: "drop table"
|
|
723
|
-
};
|
|
724
|
-
}
|
|
725
|
-
const dropColumnMatch = /^drop column (.+) on (.+)$/.exec(input);
|
|
726
|
-
if (dropColumnMatch) {
|
|
727
|
-
return {
|
|
728
|
-
table: dropColumnMatch[2],
|
|
729
|
-
reason: `drop column ${dropColumnMatch[1]}`
|
|
730
|
-
};
|
|
731
|
-
}
|
|
732
|
-
const dropSequenceMatch = /^drop sequence (.+)$/.exec(input);
|
|
733
|
-
if (dropSequenceMatch) {
|
|
734
|
-
return {
|
|
735
|
-
table: dropSequenceMatch[1],
|
|
736
|
-
reason: "drop sequence"
|
|
737
|
-
};
|
|
738
|
-
}
|
|
739
|
-
return {
|
|
740
|
-
table: "unknown",
|
|
741
|
-
reason: input
|
|
742
|
-
};
|
|
743
|
-
}
|
|
744
|
-
var PostgresMigrator = class {
|
|
745
|
-
constructor(from, desiredSchema) {
|
|
746
|
-
this.from = from;
|
|
747
|
-
this.desiredSchema = desiredSchema;
|
|
748
|
-
}
|
|
749
|
-
// Desired schema is immutable for a migrator, so cache its extracted catalog.
|
|
750
|
-
// This avoids rebuilding a scratch PGlite database on repeated diff() calls.
|
|
751
|
-
#desiredCatalog;
|
|
752
|
-
async #getDesiredCatalog(extractCatalog) {
|
|
753
|
-
if (this.#desiredCatalog) {
|
|
754
|
-
return this.#desiredCatalog;
|
|
755
|
-
}
|
|
756
|
-
const toConnection = new this.from.constructor();
|
|
757
|
-
try {
|
|
758
|
-
await toConnection.exec(this.desiredSchema);
|
|
759
|
-
this.#desiredCatalog = await extractCatalog(pgDeltaQueryable(toConnection));
|
|
760
|
-
return this.#desiredCatalog;
|
|
761
|
-
} finally {
|
|
762
|
-
await toConnection.close();
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
async diff() {
|
|
766
|
-
const { createPlan, extractCatalog } = await loadPgDelta();
|
|
767
|
-
const from = pgDeltaQueryable(this.from);
|
|
768
|
-
const toCatalog = await this.#getDesiredCatalog(extractCatalog);
|
|
769
|
-
const fromCatalog = await extractCatalog(from);
|
|
770
|
-
const result = await createPlan(fromCatalog, toCatalog);
|
|
771
|
-
if (!result) {
|
|
772
|
-
return {
|
|
773
|
-
diff: "",
|
|
774
|
-
plan: {
|
|
775
|
-
steps: [],
|
|
776
|
-
warnings: [],
|
|
777
|
-
unsafe: false
|
|
778
|
-
}
|
|
779
|
-
};
|
|
780
|
-
}
|
|
781
|
-
const warnings = result.plan.risk?.level === "data_loss" ? result.plan.risk.statements.map(parseRiskWarning) : [];
|
|
782
|
-
return {
|
|
783
|
-
diff: result.plan.statements.join("\n\n"),
|
|
784
|
-
plan: {
|
|
785
|
-
steps: result.plan.statements.map((sql3) => ({ sql: sql3 })),
|
|
786
|
-
warnings,
|
|
787
|
-
unsafe: result.plan.risk?.level === "data_loss"
|
|
788
|
-
}
|
|
789
|
-
};
|
|
790
|
-
}
|
|
791
|
-
async migratePlan(planResult, opts) {
|
|
792
|
-
if (planResult.steps.length === 0) {
|
|
793
|
-
return;
|
|
794
|
-
}
|
|
795
|
-
if (planResult.unsafe && !opts?.force) {
|
|
796
|
-
throw new DataLossError(planResult.warnings ?? []);
|
|
797
|
-
}
|
|
798
|
-
await this.from.transaction(
|
|
799
|
-
planResult.steps.map((step) => step.sql),
|
|
800
|
-
{ intent: "migration" }
|
|
801
|
-
);
|
|
802
|
-
}
|
|
803
|
-
async migrate(opts) {
|
|
804
|
-
const result = await this.diff();
|
|
805
|
-
await this.migratePlan(result.plan, opts);
|
|
806
|
-
return result;
|
|
807
|
-
}
|
|
808
|
-
safeSortPlanSteps(steps) {
|
|
809
|
-
return steps;
|
|
810
|
-
}
|
|
811
|
-
};
|
|
812
|
-
var PgliteConnection = class extends BasePostgresConnection {
|
|
813
|
-
driver;
|
|
814
|
-
dialect = "postgres";
|
|
815
|
-
#closed = false;
|
|
816
|
-
constructor(config = {}) {
|
|
817
|
-
const client = new PGlite({
|
|
818
|
-
...config.pgliteOptions,
|
|
819
|
-
dataDir: config.url ?? void 0,
|
|
820
|
-
extensions: {
|
|
821
|
-
...config.pgliteOptions?.extensions,
|
|
822
|
-
isn,
|
|
823
|
-
ltree,
|
|
824
|
-
file_fdw,
|
|
825
|
-
pgcrypto
|
|
826
|
-
},
|
|
827
|
-
parsers: {
|
|
828
|
-
// bigint/int8 (OID 20) → JS number when safe, else BigInt. Mirrors PostgresConnection.
|
|
829
|
-
20: (x) => {
|
|
830
|
-
const n = Number(x);
|
|
831
|
-
return Number.isSafeInteger(n) ? n : BigInt(x);
|
|
832
|
-
},
|
|
833
|
-
// json (OID 114) and jsonb (OID 3802): pglite leaves both as text by default.
|
|
834
|
-
// PostgREST returns them as parsed JSON, including json_agg() in embed aggregates.
|
|
835
|
-
114: (x) => JSON.parse(x),
|
|
836
|
-
3802: (x) => JSON.parse(x),
|
|
837
|
-
// numeric (OID 1700): coerce when round-trip exact, else keep string for precision safety.
|
|
838
|
-
1700: (x) => {
|
|
839
|
-
const n = Number(x);
|
|
840
|
-
if (Number.isFinite(n) && String(n) === x) return n;
|
|
841
|
-
return x;
|
|
842
|
-
},
|
|
843
|
-
// Date/time OIDs (1082 date, 1083 time, 1114 timestamp, 1184 timestamptz,
|
|
844
|
-
// 1266 timetz): keep as raw strings to mirror SQLite. Auth/storage code uses
|
|
845
|
-
// Date.parse() on these and the spec timestamp sentinel only matches strings.
|
|
846
|
-
1082: (x) => x,
|
|
847
|
-
1083: (x) => x,
|
|
848
|
-
1114: (x) => x,
|
|
849
|
-
1184: (x) => x,
|
|
850
|
-
1266: (x) => x,
|
|
851
|
-
...config.pgliteOptions?.parsers
|
|
852
|
-
}
|
|
853
|
-
});
|
|
854
|
-
const { dialect } = new KyselyPglite(client);
|
|
855
|
-
super(config);
|
|
856
|
-
this.driver = client;
|
|
857
|
-
this.kysely = new Kysely({ dialect });
|
|
858
|
-
}
|
|
859
|
-
async exec(query, ...parameters) {
|
|
860
|
-
try {
|
|
861
|
-
if (parameters.length > 0) {
|
|
862
|
-
const { rows } = await sql(query, ...parameters ?? []).execute(this.kysely);
|
|
863
|
-
return { rows };
|
|
864
|
-
}
|
|
865
|
-
const result = await this.driver.exec(query);
|
|
866
|
-
return {
|
|
867
|
-
rows: result[0].rows
|
|
868
|
-
};
|
|
869
|
-
} catch (error) {
|
|
870
|
-
console.error(error);
|
|
871
|
-
throw new Error(`Failed to execute query: ${query}`);
|
|
872
|
-
}
|
|
873
|
-
}
|
|
874
|
-
async close() {
|
|
875
|
-
if (this.#closed) return;
|
|
876
|
-
this.#closed = true;
|
|
877
|
-
await this.clearSchemaCache();
|
|
878
|
-
await this.kysely.destroy();
|
|
879
|
-
await this.driver.close();
|
|
880
|
-
}
|
|
881
|
-
createMigrator(desiredSchema) {
|
|
882
|
-
const migrationSchema = [this.config.baseSchema, desiredSchema].filter(Boolean).join("\n\n");
|
|
883
|
-
return new PostgresMigrator(this, migrationSchema);
|
|
884
|
-
}
|
|
885
|
-
};
|
|
886
|
-
async function createPgliteConnection(config = {}) {
|
|
887
|
-
return new PgliteConnection(config);
|
|
888
|
-
}
|
|
266
|
+
`),plan:{steps:c.plan.statements.map(l=>({sql:l})),warnings:m,unsafe:c.plan.risk?.level==="data_loss"}}}async migratePlan(e,a){if(e.steps.length!==0){if(e.unsafe&&!a?.force)throw new DataLossError(e.warnings??[]);await this.from.transaction(e.steps.map(o=>o.sql),{intent:"migration"});}}async migrate(e){let a=await this.diff();return await this.migratePlan(a.plan,e),a}safeSortPlanSteps(e){return e}};var S=class extends g{driver;dialect="postgres";#e=false;constructor(e={}){let a=new PGlite({...e.pgliteOptions,dataDir:e.url??void 0,extensions:{...e.pgliteOptions?.extensions,isn:isn,ltree:ltree,file_fdw:file_fdw,pgcrypto:pgcrypto},parsers:{20:s=>{let i=Number(s);return Number.isSafeInteger(i)?i:BigInt(s)},114:s=>JSON.parse(s),3802:s=>JSON.parse(s),1700:s=>{let i=Number(s);return Number.isFinite(i)&&String(i)===s?i:s},1082:s=>s,1083:s=>s,1114:s=>s,1184:s=>s,1266:s=>s,...e.pgliteOptions?.parsers}}),{dialect:o}=new d(a);super(e),this.driver=a,this.kysely=new Kysely({dialect:o});}async exec(e,...a){try{if(a.length>0){let{rows:s}=await sql(e,...a??[]).execute(this.kysely);return {rows:s}}return {rows:(await this.driver.exec(e))[0].rows}}catch(o){throw console.error(o),new Error(`Failed to execute query: ${e}`)}}async close(){this.#e||(this.#e=true,await this.clearSchemaCache(),await this.kysely.destroy(),await this.driver.close());}createMigrator(e){let a=[this.config.baseSchema,e].filter(Boolean).join(`
|
|
889
267
|
|
|
890
|
-
|
|
268
|
+
`);return new E(this,a)}};async function Ie(n={}){return new S(n)}export{S as PgliteConnection,Ie as createPgliteConnection};
|