@polpo-ai/drizzle 0.15.142 → 0.15.144

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.
@@ -0,0 +1,514 @@
1
+ import { afterAll, beforeAll, describe, expect, it } from "vitest";
2
+ import postgres from "postgres";
3
+ import { DataError, DataService } from "@polpo-ai/core/data";
4
+ import { PostgresDataProvider } from "../data/index.js";
5
+ import { compileQuery } from "../data/sql.js";
6
+ describe("SQL compiler authorization before PostgreSQL", () => {
7
+ const schema = {
8
+ tables: {
9
+ customers: {
10
+ columns: {
11
+ name: { type: "text" },
12
+ email: { type: "text", unique: true },
13
+ },
14
+ },
15
+ secrets: { columns: { value: { type: "text" } } },
16
+ },
17
+ };
18
+ const access = { readTables: ["customers"], writeTables: ["customers"] };
19
+ const compile = (sql, params = 0) => compileQuery(sql, "data_compiler_test", schema, access, sql.startsWith("INSERT") || sql.startsWith("UPDATE") ? "write" : "read", params);
20
+ it.each([
21
+ "SELECT 'pg_catalog.pg_authid'::regclass",
22
+ "SELECT 'pg_catalog.set_config'::regproc",
23
+ "SELECT 'x'::public.secret_type",
24
+ "SELECT DISTINCT ON (set_config('role','none',true)) name FROM customers",
25
+ "SELECT DISTINCT ON (pg_sleep(1)) name FROM customers",
26
+ "SELECT count(*) OVER (PARTITION BY set_config('role','none',true)) FROM customers",
27
+ "SELECT count(*) OVER (ORDER BY pg_sleep(1)) FROM customers",
28
+ "INSERT INTO customers(name,email) VALUES ('a','b') ON CONFLICT(email) DO UPDATE SET name='c' WHERE set_config('role','none',true)='none'",
29
+ "INSERT INTO customers(name,email) VALUES ('a','b') ON CONFLICT(email) DO UPDATE SET _version=10",
30
+ "SELECT DISTINCT ON ((SELECT count(*) FROM pg_catalog.pg_authid)) name FROM customers",
31
+ "SELECT count(*) OVER (ORDER BY (SELECT count(*) FROM public.customers)) FROM customers",
32
+ "SELECT count(*) OVER (PARTITION BY 'x'::regclass) FROM customers",
33
+ "SELECT count(*) OVER (ORDER BY current_user) FROM customers",
34
+ "SELECT name FROM customers FOR SHARE",
35
+ "SELECT 1e999",
36
+ ])("rejects unsafe syntax in every AST position: %s", (sql) => {
37
+ expect(() => compile(sql)).toThrowError(DataError);
38
+ expect(() => compile(sql)).toThrowError(expect.objectContaining({ code: "data_invalid" }));
39
+ });
40
+ it.each([
41
+ "SELECT DISTINCT ON ((SELECT value FROM secrets LIMIT 1)) name FROM customers",
42
+ "SELECT count(*) OVER (PARTITION BY (SELECT value FROM secrets LIMIT 1)) FROM customers",
43
+ "SELECT count(*) OVER (ORDER BY (SELECT value FROM secrets LIMIT 1)) FROM customers",
44
+ "INSERT INTO customers(name,email) VALUES ('a','b') ON CONFLICT(email) DO UPDATE SET name='c' WHERE (SELECT count(*) FROM secrets)>0",
45
+ "UPDATE customers SET name='c' FROM secrets WHERE true",
46
+ "SELECT * FROM (SELECT * FROM secrets) nested",
47
+ "SELECT name FROM customers UNION ALL SELECT value FROM secrets",
48
+ ])("checks table grants even in formerly skipped fields: %s", (sql) => {
49
+ expect(() => compile(sql)).toThrowError(expect.objectContaining({ code: "data_forbidden" }));
50
+ });
51
+ it("rewrites authorized tables in DISTINCT, OVER and conflict predicates", () => {
52
+ for (const sql of [
53
+ "SELECT DISTINCT ON ((SELECT count(*) FROM customers)) name FROM customers",
54
+ "SELECT count(*) OVER (PARTITION BY (SELECT count(*) FROM customers) ORDER BY $1) FROM customers",
55
+ "INSERT INTO customers AS c(name,email) VALUES ('a','b') ON CONFLICT(email) DO UPDATE SET name=excluded.name WHERE (SELECT count(*) FROM customers)>0",
56
+ ]) {
57
+ const result = compile(sql, sql.includes("$1") ? 1 : 0).sql;
58
+ expect(result.match(/data_compiler_test\.customers/g)).toHaveLength(2);
59
+ expect(result).not.toMatch(/FROM customers/);
60
+ }
61
+ expect(() => compile("SELECT DISTINCT ON ($1) name FROM customers")).toThrowError(expect.objectContaining({ code: "data_invalid" }));
62
+ });
63
+ });
64
+ describe.skipIf(!process.env.DATA_TEST_DATABASE_URL)("Scoped database SQL", () => {
65
+ const sql = postgres(process.env.DATA_TEST_DATABASE_URL, {
66
+ max: 8,
67
+ onnotice: () => { },
68
+ });
69
+ const executor = (c) => ({
70
+ query: async (text, params = []) => [...(await c.unsafe(text, params))],
71
+ });
72
+ const provider = new PostgresDataProvider({
73
+ ...executor(sql),
74
+ transaction: (fn) => sql.begin((tx) => fn(executor(tx))),
75
+ });
76
+ const scope = `sql-${crypto.randomUUID()}`;
77
+ const admin = new DataService(provider, {
78
+ scope,
79
+ principalId: "admin",
80
+ grants: [{ resource: "*", actions: ["manage"] }],
81
+ });
82
+ let db;
83
+ beforeAll(async () => {
84
+ await provider.initialize();
85
+ db = await admin.create({
86
+ name: "shop",
87
+ schema: {
88
+ tables: {
89
+ customers: {
90
+ columns: {
91
+ name: { type: "text" },
92
+ email: { type: "text", unique: true },
93
+ },
94
+ },
95
+ orders: {
96
+ columns: {
97
+ customer: {
98
+ type: "uuid",
99
+ references: { table: "customers", column: "_id" },
100
+ },
101
+ amount: { type: "number" },
102
+ },
103
+ },
104
+ },
105
+ },
106
+ });
107
+ });
108
+ afterAll(async () => {
109
+ for (const r of await provider.list(scope))
110
+ await provider.remove(scope, r.id, r.schemaVersion);
111
+ await sql.end();
112
+ });
113
+ const q = (text, params = [], mode = "read") => admin.query(db.id, { sql: text, params, mode });
114
+ it("executes parameterized mutations with IDs/revisions and retry protection", async () => {
115
+ const input = {
116
+ sql: "INSERT INTO customers(name,email) VALUES ($1,$2) RETURNING *",
117
+ params: ["Mario'; DROP TABLE customers; --", "mario@example.test"],
118
+ mode: "write",
119
+ idempotencyKey: "insert-mario",
120
+ };
121
+ const first = await admin.query(db.id, input);
122
+ expect(first.rowCount).toBe(1);
123
+ expect(first.rows[0]).toMatchObject({
124
+ name: input.params[0],
125
+ _version: 1,
126
+ });
127
+ expect(await admin.query(db.id, input)).toEqual(first);
128
+ await expect(admin.query(db.id, {
129
+ ...input,
130
+ params: ["other", "other@example.test"],
131
+ })).rejects.toMatchObject({ code: "data_conflict" });
132
+ const id = first.rows[0]._id;
133
+ await q("INSERT INTO orders(customer,amount) VALUES ($1,10),($1,20)", [id], "write");
134
+ const changed = await q("UPDATE customers SET name = upper($1) WHERE _id = $2 AND _version = 1 RETURNING *", ["Mario", id], "write");
135
+ expect(changed.rows[0]).toMatchObject({ name: "MARIO", _version: 2 });
136
+ expect((await q("UPDATE customers SET name = $1 WHERE _id = $2 AND _version = 1", ["stale", id], "write")).rowCount).toBe(0);
137
+ });
138
+ it("supports joins, aggregates, subqueries and bounded result pages", async () => {
139
+ const result = await q("SELECT c.name, sum(o.amount) AS total FROM customers c JOIN orders o ON o.customer=c._id WHERE o.amount > $1 GROUP BY c.name HAVING count(*) > 1 ORDER BY total DESC", [5]);
140
+ expect(result.rows).toEqual([{ name: "MARIO", total: 30 }]);
141
+ expect((await q("SELECT name FROM customers WHERE _id IN (SELECT customer FROM orders)")).rowCount).toBe(1);
142
+ const page = await admin.query(db.id, {
143
+ sql: "SELECT amount FROM orders ORDER BY amount",
144
+ maxRows: 1,
145
+ });
146
+ expect(page).toMatchObject({ rows: [{ amount: 10 }], truncated: true });
147
+ });
148
+ it("checks grants for every table, including joins and subqueries", async () => {
149
+ const reader = new DataService(provider, {
150
+ scope,
151
+ principalId: "reader",
152
+ grants: [{ resource: db.id, tables: ["customers"], actions: ["read"] }],
153
+ });
154
+ expect((await reader.query(db.id, { sql: "SELECT name FROM customers" })).rows).toHaveLength(1);
155
+ for (const text of [
156
+ "SELECT * FROM orders",
157
+ "SELECT * FROM customers JOIN orders ON true",
158
+ "SELECT (SELECT count(*) FROM orders) FROM customers",
159
+ ])
160
+ await expect(reader.query(db.id, { sql: text })).rejects.toMatchObject({
161
+ code: "data_forbidden",
162
+ });
163
+ await expect(reader.query(db.id, { sql: "DELETE FROM customers", mode: "write" })).rejects.toMatchObject({ code: "data_forbidden" });
164
+ await expect(reader.migrateSql(db.id, {
165
+ id: "forged",
166
+ expectedVersion: 1,
167
+ statements: [{ sql: "DROP TABLE customers" }],
168
+ allowDestructive: true,
169
+ })).rejects.toMatchObject({ code: "data_forbidden" });
170
+ });
171
+ it.each([
172
+ "SELECT * FROM pg_catalog.pg_authid",
173
+ "SELECT * FROM _polpo_data.resources",
174
+ "SELECT * FROM public.customers",
175
+ "SELECT set_config('role','none',true)",
176
+ "SELECT pg_catalog.set_config('role','none',true)",
177
+ "SELECT pg_read_file('/etc/passwd')",
178
+ "SELECT pg_sleep(10)",
179
+ "SELECT lo_export(1,'/tmp/escape')",
180
+ "SELECT 'customers'::regclass",
181
+ "SELECT current_user",
182
+ "SELECT * FROM customers FOR UPDATE",
183
+ "SELECT 1; DELETE FROM customers",
184
+ "RESET ROLE",
185
+ "SET search_path = public",
186
+ "DO $$ BEGIN END $$",
187
+ "WITH gone AS (DELETE FROM customers RETURNING *) SELECT * FROM gone",
188
+ "COPY customers TO PROGRAM 'id'",
189
+ "DELETE FROM customers",
190
+ "UPDATE customers SET name='escape'",
191
+ "CREATE TABLE escape(id integer)",
192
+ ])("rejects unsupported or escaping SQL: %s", async (text) => {
193
+ await expect(q(text)).rejects.toHaveProperty("code");
194
+ });
195
+ it("protects system revisions", async () => {
196
+ await expect(q("UPDATE customers SET _version=100", [], "write")).rejects.toMatchObject({ code: "data_invalid" });
197
+ await expect(q("INSERT INTO customers(_id,name,email) VALUES ($1,'a','b')", [crypto.randomUUID()], "write")).rejects.toMatchObject({ code: "data_invalid" });
198
+ expect((await q("SELECT count(*) AS n FROM customers")).rows[0].n).toBe(1);
199
+ });
200
+ it("migrates schema and backfills atomically, records history and safely replays", async () => {
201
+ const migration = {
202
+ id: "customer_labels",
203
+ expectedVersion: 1,
204
+ statements: [
205
+ { sql: "ALTER TABLE customers ADD COLUMN label text" },
206
+ { sql: "UPDATE customers SET label=lower(name)" },
207
+ { sql: "ALTER TABLE customers ALTER COLUMN label SET NOT NULL" },
208
+ { sql: "CREATE INDEX customer_labels ON customers(label)" },
209
+ {
210
+ sql: "CREATE TABLE notes (body text NOT NULL, customer uuid REFERENCES customers(_id))",
211
+ },
212
+ ],
213
+ };
214
+ db = await admin.migrateSql(db.id, migration);
215
+ expect(db.schemaVersion).toBe(2);
216
+ expect(db.schema.tables.customers.columns.label).toEqual({
217
+ type: "text",
218
+ });
219
+ expect(db.schema.tables.notes.columns.customer.references).toEqual({
220
+ table: "customers",
221
+ column: "_id",
222
+ });
223
+ expect((await q("SELECT label FROM customers")).rows[0].label).toBe("mario");
224
+ expect(await admin.migrateSql(db.id, migration)).toEqual(db);
225
+ expect(await admin.migrations(db.id)).toEqual([
226
+ expect.objectContaining({ id: "customer_labels", schemaVersion: 2 }),
227
+ ]);
228
+ await expect(admin.migrateSql(db.id, {
229
+ ...migration,
230
+ statements: [{ sql: "DROP TABLE orders" }],
231
+ })).rejects.toMatchObject({ code: "data_conflict" });
232
+ });
233
+ it("rolls back DDL, backfills and catalog updates together", async () => {
234
+ await expect(admin.migrateSql(db.id, {
235
+ id: "failed",
236
+ expectedVersion: 2,
237
+ statements: [
238
+ { sql: "ALTER TABLE customers ADD COLUMN temporary text" },
239
+ { sql: "UPDATE customers SET label=NULL" },
240
+ ],
241
+ })).rejects.toHaveProperty("code");
242
+ const current = await admin.describe(db.id);
243
+ expect(current.schemaVersion).toBe(2);
244
+ expect(current.schema.tables.customers.columns.temporary).toBeUndefined();
245
+ expect(await admin.migrations(db.id)).toHaveLength(1);
246
+ });
247
+ it("requires explicit destructive intent and keeps renamed metadata in sync", async () => {
248
+ const migration = {
249
+ id: "rename_labels",
250
+ expectedVersion: 2,
251
+ statements: [
252
+ { sql: "ALTER TABLE customers RENAME COLUMN label TO title" },
253
+ { sql: "DROP INDEX customer_labels" },
254
+ { sql: "DROP TABLE notes" },
255
+ ],
256
+ };
257
+ await expect(admin.migrateSql(db.id, migration)).rejects.toMatchObject({
258
+ code: "data_invalid",
259
+ });
260
+ db = await admin.migrateSql(db.id, {
261
+ ...migration,
262
+ allowDestructive: true,
263
+ });
264
+ expect(db.schema.tables.customers.columns.title).toEqual({
265
+ type: "text",
266
+ });
267
+ expect(db.schema.tables.notes).toBeUndefined();
268
+ expect((await admin.execute(db.id, {
269
+ operations: [{ op: "list", table: "customers" }],
270
+ }))[0].rows[0].title).toBe("mario");
271
+ });
272
+ it("preserves aliased upsert predicates, increments revisions and rechecks nested grants", async () => {
273
+ const local = await admin.create({
274
+ name: "upsert_checks",
275
+ schema: {
276
+ tables: {
277
+ entries: {
278
+ columns: {
279
+ name: { type: "text" },
280
+ email: { type: "text", unique: true },
281
+ },
282
+ },
283
+ private_values: { columns: { value: { type: "text" } } },
284
+ },
285
+ },
286
+ });
287
+ const input = {
288
+ sql: "INSERT INTO entries AS e(name,email) VALUES ($1,$2) ON CONFLICT(email) DO UPDATE SET name=excluded.name WHERE e.name <> excluded.name RETURNING *",
289
+ params: ["first", "alias@example.test"],
290
+ mode: "write",
291
+ };
292
+ const first = await admin.query(local.id, input);
293
+ const changed = await admin.query(local.id, {
294
+ ...input,
295
+ params: ["second", input.params[1]],
296
+ });
297
+ expect(changed.rows[0]).toMatchObject({
298
+ _id: first.rows[0]._id,
299
+ _version: 2,
300
+ name: "second",
301
+ });
302
+ expect((await admin.query(local.id, {
303
+ ...input,
304
+ params: ["second", input.params[1]],
305
+ })).rowCount).toBe(0);
306
+ const scoped = new DataService(provider, {
307
+ scope,
308
+ principalId: "upsert_writer",
309
+ grants: [
310
+ {
311
+ resource: local.id,
312
+ tables: ["entries"],
313
+ actions: ["read", "write"],
314
+ },
315
+ ],
316
+ });
317
+ await expect(scoped.query(local.id, {
318
+ ...input,
319
+ sql: input.sql.replace("e.name <> excluded.name", "(SELECT count(*) FROM private_values)>0"),
320
+ })).rejects.toMatchObject({ code: "data_forbidden" });
321
+ expect((await admin.execute(local.id, {
322
+ operations: [{ op: "list", table: "entries" }],
323
+ }))[0].rows[0]._version).toBe(2);
324
+ });
325
+ it("rolls back mutations whose result exceeds the byte limit", async () => {
326
+ const local = await admin.create({
327
+ name: "oversize_checks",
328
+ schema: {
329
+ tables: { entries: { columns: { name: { type: "text" } } } },
330
+ },
331
+ });
332
+ const text = "x".repeat(65536);
333
+ const values = Array.from({ length: 17 }, () => "($1)").join(",");
334
+ await expect(admin.query(local.id, {
335
+ sql: `INSERT INTO entries(name) VALUES ${values} RETURNING *`,
336
+ params: [text],
337
+ mode: "write",
338
+ idempotencyKey: "too-large",
339
+ })).rejects.toMatchObject({ code: "data_limit" });
340
+ expect((await admin.query(local.id, {
341
+ sql: "SELECT count(*) AS n FROM entries",
342
+ })).rows).toEqual([{ n: 0 }]);
343
+ const retry = await admin.query(local.id, {
344
+ sql: "INSERT INTO entries(name) VALUES ($1) RETURNING name",
345
+ params: ["small"],
346
+ mode: "write",
347
+ idempotencyKey: "too-large",
348
+ });
349
+ expect(retry.rowCount).toBe(1);
350
+ });
351
+ it("counts all mutations while truncating only returned rows and serializes retries", async () => {
352
+ const local = await admin.create({
353
+ name: "retry_checks",
354
+ schema: {
355
+ tables: { entries: { columns: { name: { type: "text" } } } },
356
+ },
357
+ });
358
+ const input = {
359
+ sql: "INSERT INTO entries(name) VALUES ('a'),('b'),('c') RETURNING *",
360
+ mode: "write",
361
+ maxRows: 1,
362
+ idempotencyKey: "concurrent-insert",
363
+ };
364
+ const [first, retry] = await Promise.all([
365
+ admin.query(local.id, input),
366
+ admin.query(local.id, input),
367
+ ]);
368
+ expect(first).toMatchObject({ rowCount: 3, truncated: true });
369
+ expect(first.rows).toHaveLength(1);
370
+ expect(retry).toEqual(first);
371
+ expect((await admin.query(local.id, {
372
+ sql: "SELECT count(*) AS n FROM entries",
373
+ })).rows).toEqual([{ n: 3 }]);
374
+ });
375
+ it("supports DISTINCT ON, windows and safe nested expressions at runtime", async () => {
376
+ const result = await q("SELECT DISTINCT ON (amount) amount, sum(amount) OVER (ORDER BY amount) AS running FROM orders ORDER BY amount");
377
+ expect(result.rows).toEqual([
378
+ { amount: 10, running: 10 },
379
+ { amount: 20, running: 30 },
380
+ ]);
381
+ expect((await q("SELECT count(*) OVER (PARTITION BY (SELECT count(*) FROM customers)) AS n FROM orders")).rows).toEqual([{ n: 2 }, { n: 2 }]);
382
+ });
383
+ it("enforces portable value constraints for SQL, DDL changes and typed CRUD", async () => {
384
+ const local = await admin.create({
385
+ name: "value_checks",
386
+ schema: {
387
+ tables: {
388
+ entries: {
389
+ columns: {
390
+ name: { type: "text" },
391
+ amount: { type: "number", nullable: true },
392
+ happened: { type: "timestamp", nullable: true },
393
+ payload: { type: "json", nullable: true },
394
+ },
395
+ },
396
+ },
397
+ },
398
+ });
399
+ for (const sql of [
400
+ "INSERT INTO entries(name,amount) VALUES ('bad','NaN'::float8)",
401
+ "INSERT INTO entries(name,amount) VALUES ('bad','Infinity'::float8)",
402
+ "INSERT INTO entries(name,happened) VALUES ('bad','infinity'::timestamptz)",
403
+ "INSERT INTO entries(name,happened) VALUES ('bad','10000-01-01T00:00:00Z'::timestamptz)",
404
+ "INSERT INTO entries(name,payload) VALUES ('bad','{\"big\": 1e309}'::jsonb)",
405
+ ])
406
+ await expect(admin.query(local.id, { sql, mode: "write" })).rejects.toMatchObject({ code: "data_constraint" });
407
+ await expect(admin.query(local.id, {
408
+ sql: "INSERT INTO entries(name) VALUES ($1 || $1)",
409
+ params: ["x".repeat(40000)],
410
+ mode: "write",
411
+ })).rejects.toMatchObject({ code: "data_constraint" });
412
+ const created = await admin.query(local.id, {
413
+ sql: "INSERT INTO entries(name,amount,happened,payload) VALUES ('valid', 42, '2026-10-09T00:00:00Z'::timestamptz, '{\"nested\": [1, true]}'::jsonb)",
414
+ mode: "write",
415
+ });
416
+ expect((await admin.execute(local.id, {
417
+ operations: [{ op: "list", table: "entries" }],
418
+ }))[0].rows[0]).toMatchObject({
419
+ name: "valid",
420
+ amount: 42,
421
+ payload: { nested: [1, true] },
422
+ });
423
+ const changed = await admin.migrateSql(local.id, {
424
+ id: "types",
425
+ expectedVersion: 1,
426
+ allowDestructive: true,
427
+ statements: [
428
+ { sql: "ALTER TABLE entries RENAME COLUMN amount TO total" },
429
+ { sql: "ALTER TABLE entries ALTER COLUMN total TYPE integer" },
430
+ {
431
+ sql: "ALTER TABLE entries ALTER COLUMN total TYPE double precision",
432
+ },
433
+ { sql: "ALTER TABLE entries ADD COLUMN label text" },
434
+ { sql: "CREATE TABLE added(body text, score double precision)" },
435
+ ],
436
+ });
437
+ expect(changed.schema.tables.entries.columns.total.type).toBe("number");
438
+ for (const sql of [
439
+ "UPDATE entries SET total='Infinity'::float8",
440
+ "INSERT INTO added(score) VALUES ('NaN'::float8)",
441
+ ])
442
+ await expect(admin.query(local.id, { sql, mode: "write" })).rejects.toMatchObject({ code: "data_constraint" });
443
+ await expect(admin.query(local.id, {
444
+ sql: "UPDATE entries SET label=$1 || $1",
445
+ params: ["x".repeat(40000)],
446
+ mode: "write",
447
+ })).rejects.toMatchObject({ code: "data_constraint" });
448
+ const final = await admin.execute(local.id, {
449
+ operations: [
450
+ {
451
+ op: "update",
452
+ table: "entries",
453
+ id: created.rows[0]._id,
454
+ expectedVersion: 1,
455
+ values: { total: 50 },
456
+ },
457
+ ],
458
+ });
459
+ expect(final[0].rows[0]).toMatchObject({ total: 50, _version: 2 });
460
+ });
461
+ it("rejects computed numbers beyond JSON's finite range and rolls back RETURNING", async () => {
462
+ const local = await admin.create({
463
+ name: "numeric_result_checks",
464
+ schema: {
465
+ tables: { entries: { columns: { name: { type: "text" } } } },
466
+ },
467
+ });
468
+ // Each ordinary decimal literal fits a finite JS number; PostgreSQL's
469
+ // arbitrary-precision numeric multiplication produces 10^400.
470
+ const literal = `1${"0".repeat(100)}`;
471
+ const huge = Array.from({ length: 4 }, () => literal).join(" * ");
472
+ await expect(admin.query(local.id, { sql: `SELECT (${huge}) AS huge` })).rejects.toMatchObject({ code: "data_invalid" });
473
+ await expect(admin.query(local.id, {
474
+ sql: `INSERT INTO entries(name) VALUES ('must_rollback') RETURNING (${huge}) AS huge`,
475
+ mode: "write",
476
+ idempotencyKey: "overflow",
477
+ })).rejects.toMatchObject({ code: "data_invalid" });
478
+ expect((await admin.query(local.id, {
479
+ sql: "SELECT count(*) AS n FROM entries",
480
+ })).rows).toEqual([{ n: 0 }]);
481
+ expect((await admin.query(local.id, {
482
+ sql: "INSERT INTO entries(name) VALUES ('valid') RETURNING name",
483
+ mode: "write",
484
+ idempotencyKey: "overflow",
485
+ })).rows).toEqual([{ name: "valid" }]);
486
+ });
487
+ it("reports invalid query inputs without retryable backend errors", async () => {
488
+ await expect(q("SELECT 1 / 0 AS result")).rejects.toMatchObject({
489
+ code: "data_constraint",
490
+ });
491
+ await expect(q("SELECT _id FROM customers JOIN orders ON true")).rejects.toMatchObject({ code: "data_invalid" });
492
+ });
493
+ it("serializes concurrent schema migrations and records only the committed version", async () => {
494
+ const local = await admin.create({
495
+ name: "migration_race",
496
+ schema: {
497
+ tables: { entries: { columns: { name: { type: "text" } } } },
498
+ },
499
+ });
500
+ const migrations = ["first", "second"].map((id) => admin.migrateSql(local.id, {
501
+ id,
502
+ expectedVersion: 1,
503
+ statements: [{ sql: `ALTER TABLE entries ADD COLUMN ${id} text` }],
504
+ }));
505
+ const results = await Promise.allSettled(migrations);
506
+ expect(results.filter((r) => r.status === "fulfilled")).toHaveLength(1);
507
+ expect(results.find((r) => r.status === "rejected")).toMatchObject({
508
+ reason: { code: "data_conflict" },
509
+ });
510
+ expect((await admin.describe(local.id)).schemaVersion).toBe(2);
511
+ expect(await admin.migrations(local.id)).toHaveLength(1);
512
+ });
513
+ });
514
+ //# sourceMappingURL=data-sql.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-sql.test.js","sourceRoot":"","sources":["../../src/__tests__/data-sql.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { DataColumn } from "@polpo-ai/core/data";
2
+ export declare const dataValueConstraintName: (name: string) => string;
3
+ export declare const finiteDataJson: (value: string) => string;
4
+ export declare function dataValueConstraint(name: string, column: DataColumn): string;
5
+ //# sourceMappingURL=constraints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constraints.d.ts","sourceRoot":"","sources":["../../src/data/constraints.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGtD,eAAO,MAAM,uBAAuB,GAAI,MAAM,MAAM,WAA0B,CAAC;AAC/E,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,WACuF,CAAC;AACpI,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAe5E"}
@@ -0,0 +1,19 @@
1
+ // Names have already passed the canonical identifier validator.
2
+ export const dataValueConstraintName = (name) => `polpo_value_${name}`;
3
+ export const finiteDataJson = (value) => `NOT jsonb_path_exists(${value}, '$.** ? (@.type() == "number" && (@ > 1.7976931348623157e308 || @ < -1.7976931348623157e308))')`;
4
+ export function dataValueConstraint(name, column) {
5
+ const value = `"${name}"`;
6
+ const check = column.type === "text"
7
+ ? `octet_length(${value}) <= 65536`
8
+ : column.type === "number"
9
+ ? `${value} NOT IN ('NaN'::float8, 'Infinity'::float8, '-Infinity'::float8)`
10
+ : column.type === "timestamp"
11
+ ? `isfinite(${value}) AND ${value} >= TIMESTAMPTZ '0001-01-01 00:00:00+00' AND ${value} < TIMESTAMPTZ '10000-01-01 00:00:00+00'`
12
+ : column.type === "json"
13
+ ? finiteDataJson(value)
14
+ : undefined;
15
+ return check
16
+ ? ` CONSTRAINT "${dataValueConstraintName(name)}" CHECK (${check})`
17
+ : "";
18
+ }
19
+ //# sourceMappingURL=constraints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constraints.js","sourceRoot":"","sources":["../../src/data/constraints.ts"],"names":[],"mappings":"AAEA,gEAAgE;AAChE,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,eAAe,IAAI,EAAE,CAAC;AAC/E,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAa,EAAE,EAAE,CAC9C,yBAAyB,KAAK,mGAAmG,CAAC;AACpI,MAAM,UAAU,mBAAmB,CAAC,IAAY,EAAE,MAAkB;IAClE,MAAM,KAAK,GAAG,IAAI,IAAI,GAAG,CAAC;IAC1B,MAAM,KAAK,GACT,MAAM,CAAC,IAAI,KAAK,MAAM;QACpB,CAAC,CAAC,gBAAgB,KAAK,YAAY;QACnC,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ;YACxB,CAAC,CAAC,GAAG,KAAK,kEAAkE;YAC5E,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,WAAW;gBAC3B,CAAC,CAAC,YAAY,KAAK,SAAS,KAAK,gDAAgD,KAAK,0CAA0C;gBAChI,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM;oBACtB,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC;oBACvB,CAAC,CAAC,SAAS,CAAC;IACtB,OAAO,KAAK;QACV,CAAC,CAAC,gBAAgB,uBAAuB,CAAC,IAAI,CAAC,YAAY,KAAK,GAAG;QACnE,CAAC,CAAC,EAAE,CAAC;AACT,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { type CreateDataInput, type DataBatch, type DataMigration, type DataProvider, type DataRename, type DataResource, type DataResult, type DataQuery, type DataQueryAccess, type DataQueryResult, type DataSqlMigration, type DataMigrationRecord } from "@polpo-ai/core/data";
2
+ /** Drivers must keep every transaction callback on one connection. */
3
+ export interface DataSqlExecutor {
4
+ query(text: string, values?: unknown[]): Promise<Record<string, any>[]>;
5
+ }
6
+ export interface DataSqlDatabase extends DataSqlExecutor {
7
+ transaction<T>(fn: (tx: DataSqlExecutor) => Promise<T>): Promise<T>;
8
+ }
9
+ export declare class PostgresDataProvider implements DataProvider {
10
+ private readonly database;
11
+ readonly capabilities: {
12
+ transactions: boolean;
13
+ relations: boolean;
14
+ schemaEvolution: "additive";
15
+ sql: {
16
+ dialect: "postgresql";
17
+ migrations: boolean;
18
+ };
19
+ };
20
+ constructor(database: DataSqlDatabase);
21
+ private transaction;
22
+ initialize(): Promise<void>;
23
+ list(scope: string): Promise<DataResource[]>;
24
+ get(scope: string, reference: string): Promise<DataResource | undefined>;
25
+ private locked;
26
+ private grantTables;
27
+ private evolve;
28
+ create(scope: string, input: CreateDataInput): Promise<DataResource>;
29
+ migrate(scope: string, id: string, input: DataMigration): Promise<DataResource>;
30
+ private sqlResult;
31
+ query(scope: string, id: string, principalId: string, input: DataQuery, access: DataQueryAccess): Promise<DataQueryResult>;
32
+ migrateSql(scope: string, id: string, input: DataSqlMigration): Promise<DataResource>;
33
+ migrations(scope: string, id: string): Promise<DataMigrationRecord[]>;
34
+ rename(scope: string, id: string, input: DataRename): Promise<DataResource>;
35
+ remove(scope: string, id: string, expectedVersion: number): Promise<void>;
36
+ execute(scope: string, id: string, principalId: string, batch: DataBatch): Promise<DataResult[]>;
37
+ private boundedRows;
38
+ private operation;
39
+ }
40
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/data/index.ts"],"names":[],"mappings":"AAAA,OAAO,EASL,KAAK,eAAe,EACpB,KAAK,SAAS,EAEd,KAAK,aAAa,EAElB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,UAAU,EAIf,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACzB,MAAM,qBAAqB,CAAC;AAI7B,sEAAsE;AACtE,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;CACzE;AACD,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,eAAe,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACrE;AA0FD,qBAAa,oBAAqB,YAAW,YAAY;IAO3C,OAAO,CAAC,QAAQ,CAAC,QAAQ;IANrC,QAAQ,CAAC,YAAY;;;;;;;;MAKnB;gBAC2B,QAAQ,EAAE,eAAe;YACxC,WAAW;IAcnB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAmB3B,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAY5C,GAAG,CACP,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;YAWtB,MAAM;YAmBN,WAAW;YASX,MAAM;IA2Fd,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,YAAY,CAAC;IAoCpE,OAAO,CACX,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC,YAAY,CAAC;YAkBV,SAAS;IA6CjB,KAAK,CACT,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,EACV,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC,eAAe,CAAC;IAmDrB,UAAU,CACd,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,gBAAgB,GACtB,OAAO,CAAC,YAAY,CAAC;IAkFlB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAerE,MAAM,CACV,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,UAAU,GAChB,OAAO,CAAC,YAAY,CAAC;IAUlB,MAAM,CACV,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,EACV,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC;IAUV,OAAO,CACX,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,EACV,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,SAAS,GACf,OAAO,CAAC,UAAU,EAAE,CAAC;YA6DV,WAAW;YAoBX,SAAS;CAgHxB"}