hazo_connect 2.4.7 → 2.7.0

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.
Files changed (54) hide show
  1. package/README.md +167 -3
  2. package/dist/adapters/clause-builder.d.ts +49 -0
  3. package/dist/adapters/clause-builder.d.ts.map +1 -0
  4. package/dist/adapters/clause-builder.js +192 -0
  5. package/dist/adapters/clause-builder.js.map +1 -0
  6. package/dist/adapters/file-adapter.d.ts +2 -1
  7. package/dist/adapters/file-adapter.d.ts.map +1 -1
  8. package/dist/adapters/file-adapter.js +3 -0
  9. package/dist/adapters/file-adapter.js.map +1 -1
  10. package/dist/adapters/pg-adapter.d.ts +64 -0
  11. package/dist/adapters/pg-adapter.d.ts.map +1 -0
  12. package/dist/adapters/pg-adapter.js +120 -0
  13. package/dist/adapters/pg-adapter.js.map +1 -0
  14. package/dist/adapters/postgrest-adapter.d.ts +30 -1
  15. package/dist/adapters/postgrest-adapter.d.ts.map +1 -1
  16. package/dist/adapters/postgrest-adapter.js +104 -0
  17. package/dist/adapters/postgrest-adapter.js.map +1 -1
  18. package/dist/adapters/sqlite-adapter.d.ts +43 -1
  19. package/dist/adapters/sqlite-adapter.d.ts.map +1 -1
  20. package/dist/adapters/sqlite-adapter.js +131 -0
  21. package/dist/adapters/sqlite-adapter.js.map +1 -1
  22. package/dist/adapters/supabase-adapter.d.ts +2 -1
  23. package/dist/adapters/supabase-adapter.d.ts.map +1 -1
  24. package/dist/adapters/supabase-adapter.js +3 -0
  25. package/dist/adapters/supabase-adapter.js.map +1 -1
  26. package/dist/factory.d.ts.map +1 -1
  27. package/dist/factory.js +7 -3
  28. package/dist/factory.js.map +1 -1
  29. package/dist/migrations/runner.d.ts +39 -0
  30. package/dist/migrations/runner.d.ts.map +1 -0
  31. package/dist/migrations/runner.js +87 -0
  32. package/dist/migrations/runner.js.map +1 -0
  33. package/dist/nextjs/setup-helpers.d.ts.map +1 -1
  34. package/dist/nextjs/setup-helpers.js +15 -4
  35. package/dist/nextjs/setup-helpers.js.map +1 -1
  36. package/dist/query-builder.d.ts +65 -0
  37. package/dist/query-builder.d.ts.map +1 -1
  38. package/dist/query-builder.js +148 -0
  39. package/dist/query-builder.js.map +1 -1
  40. package/dist/server/index.d.ts +3 -0
  41. package/dist/server/index.d.ts.map +1 -1
  42. package/dist/server/index.js +4 -1
  43. package/dist/server/index.js.map +1 -1
  44. package/dist/sqlite/query-translator.d.ts.map +1 -1
  45. package/dist/sqlite/query-translator.js +39 -2
  46. package/dist/sqlite/query-translator.js.map +1 -1
  47. package/dist/types.d.ts +65 -1
  48. package/dist/types.d.ts.map +1 -1
  49. package/dist/types.js.map +1 -1
  50. package/dist/utils/database-url.d.ts +20 -0
  51. package/dist/utils/database-url.d.ts.map +1 -0
  52. package/dist/utils/database-url.js +44 -0
  53. package/dist/utils/database-url.js.map +1 -0
  54. package/package.json +3 -1
package/README.md CHANGED
@@ -465,12 +465,176 @@ const hazo = createHazoConnect({
465
465
  })
466
466
  ```
467
467
 
468
+ ### pg Configuration
469
+
470
+ Use the `pg` adapter when you need SQL features that PostgREST does not expose, such as `SELECT … FOR UPDATE SKIP LOCKED` for job-queue locking or advisory locks. It connects directly to Postgres via the `postgres` driver (postgres.js).
471
+
472
+ ```typescript
473
+ const hazo = createHazoConnect({
474
+ type: 'pg',
475
+ pg: {
476
+ connection_string: process.env.DATABASE_URL // e.g. postgres://user:pass@host:5432/db
477
+ }
478
+ })
479
+ ```
480
+
481
+ **Adapters at a glance:**
482
+
483
+ | Adapter | When to use |
484
+ |---------|-------------|
485
+ | `postgrest` | Default REST-over-Postgres. Covers most CRUD needs. |
486
+ | `supabase` | Hosted PostgREST with Supabase auth and realtime. |
487
+ | `sqlite` | Embedded SQLite for local dev, tests, or edge deployments. |
488
+ | `pg` | Raw Postgres via `postgres` driver. Use when you need `SELECT … FOR UPDATE SKIP LOCKED` or other SQL features PostgREST doesn't expose. Requires a direct Postgres connection string. |
489
+
490
+ ---
491
+
492
+ ## Using SQLite with Next.js App Router
493
+
494
+ This walkthrough covers the bootstrap shape an embedded-SQLite app (single-operator, local-file) typically wants: `DATABASE_URL`-driven config, migrations applied at boot, Server Components reading directly, route handlers writing inside an atomic transaction with idempotent UPSERT.
495
+
496
+ ### 1. Configure via `DATABASE_URL`
497
+
498
+ ```bash
499
+ # .env.local
500
+ DATABASE_URL=sqlite:./data/site-ops.db
501
+ HAZO_CONNECT_ENABLE_ADMIN_UI=true # optional, for the built-in admin UI
502
+ ```
503
+
504
+ Supported URI forms: `sqlite:./relative`, `sqlite:/absolute`, `sqlite:///absolute`, `sqlite::memory:`. `HAZO_CONNECT_SQLITE_PATH` (if set) wins over `DATABASE_URL`.
505
+
506
+ ### 2. Singleton accessor
507
+
508
+ ```ts
509
+ // lib/db.ts
510
+ import 'server-only'
511
+ import { getHazoConnectSingleton } from 'hazo_connect/nextjs/setup'
512
+
513
+ export const db = getHazoConnectSingleton()
514
+ ```
515
+
516
+ ### 3. Apply migrations at boot
517
+
518
+ Place migration files as `migrations/0001_*.sql`, `0002_*.sql`, … in your project root.
519
+
520
+ ```ts
521
+ // lib/migrate.ts
522
+ import 'server-only'
523
+ import path from 'path'
524
+ import { runMigrations } from 'hazo_connect/server'
525
+ import { db } from './db'
526
+
527
+ let applied: Promise<void> | null = null
528
+ export function ensureMigrationsApplied() {
529
+ if (!applied) {
530
+ applied = runMigrations(db, {
531
+ directory: path.join(process.cwd(), 'migrations')
532
+ }).then(() => undefined)
533
+ }
534
+ return applied
535
+ }
536
+ ```
537
+
538
+ `runMigrations` is idempotent — pending files are detected via a `_migrations` tracking table, applied inside an `adapter.transaction()`, and recorded with a SHA-256 checksum.
539
+
540
+ ### 4. Read inside Server Components
541
+
542
+ ```tsx
543
+ // app/(dashboard)/runs/page.tsx
544
+ import { QueryBuilder } from 'hazo_connect/server'
545
+ import { db } from '@/lib/db'
546
+ import { ensureMigrationsApplied } from '@/lib/migrate'
547
+
548
+ export default async function RunsPage() {
549
+ await ensureMigrationsApplied()
550
+ const runs = await db.query(
551
+ new QueryBuilder().from('daily_runs').order('run_date', 'desc').limit(20)
552
+ )
553
+ return <RunsTable runs={runs} />
554
+ }
555
+ ```
556
+
557
+ All adapter methods return `Promise`s — Server Components `await` them directly.
558
+
559
+ ### 5. Write inside route handlers (idempotent UPSERT + transactions)
560
+
561
+ ```ts
562
+ // app/api/v1/runs/route.ts
563
+ import { NextResponse } from 'next/server'
564
+ import { QueryBuilder, type SqliteTransactionContext } from 'hazo_connect/server'
565
+ import { SqliteAdapter } from 'hazo_connect/server'
566
+ import { db } from '@/lib/db'
567
+
568
+ export async function POST(req: Request) {
569
+ const payload = await req.json()
570
+ const adapter = db as SqliteAdapter
571
+
572
+ const runId = await adapter.transaction(async (tx: SqliteTransactionContext) => {
573
+ // Idempotent on (site_id, run_date). Re-running the same routine on the
574
+ // same day updates the existing row.
575
+ const [run] = await tx.query(
576
+ new QueryBuilder()
577
+ .from('daily_runs')
578
+ .onConflict(['site_id', 'run_date'])
579
+ .doUpdate(),
580
+ 'POST',
581
+ {
582
+ site_id: payload.site_id,
583
+ run_date: payload.run_date,
584
+ status: payload.status,
585
+ steps_completed: payload.steps_completed
586
+ }
587
+ )
588
+
589
+ for (const article of payload.articles ?? []) {
590
+ await tx.query(
591
+ new QueryBuilder().from('articles_published'),
592
+ 'POST',
593
+ { ...article, run_id: run.run_id }
594
+ )
595
+ }
596
+
597
+ for (const check of payload.health_checks ?? []) {
598
+ await tx.query(
599
+ new QueryBuilder()
600
+ .from('health_checks')
601
+ .onConflict(['site_id', 'check_date', 'check_key'])
602
+ .doUpdate(),
603
+ 'POST',
604
+ { ...check, run_id: run.run_id, site_id: payload.site_id }
605
+ )
606
+ }
607
+
608
+ return run.run_id
609
+ })
610
+
611
+ return NextResponse.json({ ok: true, data: { run_id: runId } }, { status: 201 })
612
+ }
613
+ ```
614
+
615
+ Key points:
616
+
617
+ - `adapter.transaction(fn)` wraps the callback in `BEGIN`/`COMMIT`. If `fn` throws, `ROLLBACK` runs and no rows reach disk.
618
+ - The SQLite adapter persists the in-memory DB image to disk **exactly once** per transaction (not once per statement) — large multi-write payloads are reasonably fast.
619
+ - `QueryBuilder.onConflict(cols).doUpdate()` defaults to `SET col = excluded.col` for every inserted column except the conflict target. Pass an object — `doUpdate({ status: 'done' })` — to update only specific columns. Pass `doNothing()` to keep the existing row.
620
+
621
+ ### 6. Backups
622
+
623
+ `sql.js` works on an in-memory image, so a "hot backup" while a transaction is mid-flight isn't meaningful. The simplest backup pattern is a cron job:
624
+
625
+ ```bash
626
+ cp data/site-ops.db data/backups/$(date +%F).db
627
+ ```
628
+
629
+ Run it outside an in-flight transaction window. (A typed `store.backup()` helper is on the roadmap once we move to `better-sqlite3`.)
630
+
468
631
  ### Environment Variables
469
632
 
470
633
  | Variable | Description | Default |
471
634
  |----------|-------------|---------|
472
- | `HAZO_CONNECT_TYPE` | Database type (`sqlite`, `postgrest`, `supabase`) | `sqlite` |
473
- | `HAZO_CONNECT_SQLITE_PATH` | Path to SQLite database file. Ignored when the config object supplies `sqlite.initial_sql` (so test seeds aren't overridden by ambient env). | `./database.sqlite` |
635
+ | `HAZO_CONNECT_TYPE` | Database type (`sqlite`, `postgrest`, `supabase`, `pg`) | `sqlite` |
636
+ | `DATABASE_URL` | SQLite-only URI form, e.g. `sqlite:./data/site-ops.db`, `sqlite:/var/lib/x.db`, `sqlite:///var/lib/x.db`, `sqlite::memory:`. Read by `createHazoConnectFromEnv` when `HAZO_CONNECT_SQLITE_PATH` is not set. | - |
637
+ | `HAZO_CONNECT_SQLITE_PATH` | Path to SQLite database file. Ignored when the config object supplies `sqlite.initial_sql` (so test seeds aren't overridden by ambient env). Takes precedence over `DATABASE_URL` when both are set. | `./database.sqlite` |
474
638
  | `HAZO_CONNECT_SQLITE_READONLY` | Enable read-only mode | `false` |
475
639
  | `HAZO_CONNECT_SQLITE_WASM_DIR` | Path to sql-wasm.wasm directory | Auto-detected |
476
640
  | `HAZO_CONNECT_ENABLE_ADMIN_UI` | Enable SQLite admin UI | `false` |
@@ -575,7 +739,7 @@ Main configuration interface:
575
739
 
576
740
  ```typescript
577
741
  interface HazoConnectConfig {
578
- type: 'postgrest' | 'supabase' | 'sqlite' | 'file'
742
+ type: 'postgrest' | 'supabase' | 'sqlite' | 'file' | 'pg'
579
743
  logger?: Logger
580
744
  log_level?: 'debug' | 'info' | 'warn' | 'error' | 'none'
581
745
  enable_admin_ui?: boolean // SQLite only
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Shared serialization helpers for the claimRows primitive.
3
+ * Pure functions; no I/O. Used by Pg, Postgrest, and Sqlite adapters.
4
+ */
5
+ export type Dialect = "pg" | "postgrest" | "sqlite";
6
+ export type NowSentinel = {
7
+ $now: true;
8
+ };
9
+ export declare function isNowSentinel(v: unknown): v is NowSentinel;
10
+ export declare function validateColumnName(name: string): void;
11
+ export declare function validateOperator(op: string): void;
12
+ export type ResolvedNow = {
13
+ kind: "sql";
14
+ value: string;
15
+ } | {
16
+ kind: "literal";
17
+ value: unknown;
18
+ };
19
+ export declare function resolveNowSentinel(v: unknown, dialect: Dialect): ResolvedNow;
20
+ export declare function serializeWhereToPostgrest(where: Record<string, unknown>): Record<string, string>;
21
+ export interface PgSqlFragment {
22
+ fragment: string;
23
+ params: unknown[];
24
+ nextParamIndex: number;
25
+ }
26
+ export declare function serializeWhereToPgSql(where: Record<string, unknown>, startIndex: number): PgSqlFragment;
27
+ type SetValue = unknown | NowSentinel | {
28
+ increment: number;
29
+ };
30
+ export declare function serializeSetToPgSql(set: Record<string, SetValue>, startIndex: number): PgSqlFragment;
31
+ export declare function serializeSetToPostgrestBody(set: Record<string, SetValue>, observed: Record<string, unknown>): Record<string, unknown>;
32
+ /** Columns the caller incremented — needed for CAS witnesses on PostgrestAdapter. */
33
+ export declare function incrementedColumns(set: Record<string, SetValue>): string[];
34
+ /**
35
+ * Reject empty where/set/returning at the API boundary so adapters
36
+ * don't generate malformed SQL or — on PostgrestAdapter — accidentally
37
+ * match every row.
38
+ *
39
+ * Caller is expected to pass the full ClaimRowsOptions; types kept loose
40
+ * here because the helper lives in clause-builder which doesn't import
41
+ * from types.ts (avoids circular import risk).
42
+ */
43
+ export declare function validateClaimRowsOptions(opts: {
44
+ where: Record<string, unknown>;
45
+ set: Record<string, unknown>;
46
+ returning?: string[];
47
+ }): void;
48
+ export {};
49
+ //# sourceMappingURL=clause-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clause-builder.d.ts","sourceRoot":"","sources":["../../src/lib/adapters/clause-builder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,MAAM,MAAM,OAAO,GAAG,IAAI,GAAG,WAAW,GAAG,QAAQ,CAAC;AAEpD,MAAM,MAAM,WAAW,GAAG;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,CAAC;AACzC,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,WAAW,CAE1D;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAIrD;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAIjD;AAED,MAAM,MAAM,WAAW,GAAG;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAC/F,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,WAAW,CAK5E;AAgBD,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAqBhG;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,EAAE,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACxB;AAMD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,EAAE,MAAM,GAAG,aAAa,CAiCvG;AAID,KAAK,QAAQ,GAAG,OAAO,GAAG,WAAW,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9D,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,UAAU,EAAE,MAAM,GAAG,aAAa,CAqBpG;AAED,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAmBrI;AAED,qFAAqF;AACrF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,MAAM,EAAE,CAI1E;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC7C,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB,GAAG,IAAI,CAUP"}
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+ /**
3
+ * Shared serialization helpers for the claimRows primitive.
4
+ * Pure functions; no I/O. Used by Pg, Postgrest, and Sqlite adapters.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.isNowSentinel = isNowSentinel;
8
+ exports.validateColumnName = validateColumnName;
9
+ exports.validateOperator = validateOperator;
10
+ exports.resolveNowSentinel = resolveNowSentinel;
11
+ exports.serializeWhereToPostgrest = serializeWhereToPostgrest;
12
+ exports.serializeWhereToPgSql = serializeWhereToPgSql;
13
+ exports.serializeSetToPgSql = serializeSetToPgSql;
14
+ exports.serializeSetToPostgrestBody = serializeSetToPostgrestBody;
15
+ exports.incrementedColumns = incrementedColumns;
16
+ exports.validateClaimRowsOptions = validateClaimRowsOptions;
17
+ const COLUMN_NAME_RE = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
18
+ const ALLOWED_OPS = new Set(["eq", "lte", "gte", "lt", "gt", "in", "increment", "$now"]);
19
+ function isNowSentinel(v) {
20
+ return typeof v === "object" && v !== null && "$now" in v && v.$now === true;
21
+ }
22
+ function validateColumnName(name) {
23
+ if (!COLUMN_NAME_RE.test(name)) {
24
+ throw new Error(`invalid column name: ${JSON.stringify(name)}`);
25
+ }
26
+ }
27
+ function validateOperator(op) {
28
+ if (!ALLOWED_OPS.has(op)) {
29
+ throw new Error(`unknown operator: ${JSON.stringify(op)}`);
30
+ }
31
+ }
32
+ function resolveNowSentinel(v, dialect) {
33
+ if (!isNowSentinel(v))
34
+ return { kind: "literal", value: v };
35
+ if (dialect === "pg")
36
+ return { kind: "sql", value: "now()" };
37
+ if (dialect === "sqlite")
38
+ return { kind: "sql", value: "datetime('now')" };
39
+ return { kind: "literal", value: new Date().toISOString() };
40
+ }
41
+ function asOperator(v) {
42
+ if (typeof v !== "object" || v === null || isNowSentinel(v))
43
+ return null;
44
+ const keys = Object.keys(v).filter((k) => ["lte", "gte", "lt", "gt", "in"].includes(k));
45
+ if (keys.length === 0)
46
+ return null;
47
+ if (keys.length > 1) {
48
+ throw new Error(`multiple operators in single clause not supported: ${keys.join(", ")}`);
49
+ }
50
+ const op = keys[0];
51
+ return { op, value: v[op] };
52
+ }
53
+ function serializeWhereToPostgrest(where) {
54
+ const out = {};
55
+ for (const [col, raw] of Object.entries(where)) {
56
+ validateColumnName(col);
57
+ const opObj = asOperator(raw);
58
+ if (opObj) {
59
+ if (opObj.op === "in") {
60
+ if (!Array.isArray(opObj.value))
61
+ throw new Error(`in clause requires array for column ${col}`);
62
+ out[col] = `in.(${opObj.value.map(String).join(",")})`;
63
+ }
64
+ else {
65
+ const resolved = resolveNowSentinel(opObj.value, "postgrest");
66
+ if (resolved.kind === "sql")
67
+ throw new Error("postgrest path cannot use sql sentinel");
68
+ out[col] = `${opObj.op}.${String(resolved.value)}`;
69
+ }
70
+ }
71
+ else {
72
+ // scalar => eq
73
+ const resolved = resolveNowSentinel(raw, "postgrest");
74
+ out[col] = `eq.${String(resolved.value)}`;
75
+ }
76
+ }
77
+ return out;
78
+ }
79
+ const PG_OP_SQL = {
80
+ lte: "<=", gte: ">=", lt: "<", gt: ">", eq: "=",
81
+ };
82
+ function serializeWhereToPgSql(where, startIndex) {
83
+ const parts = [];
84
+ const params = [];
85
+ let idx = startIndex;
86
+ for (const [col, raw] of Object.entries(where)) {
87
+ validateColumnName(col);
88
+ const opObj = asOperator(raw);
89
+ if (opObj) {
90
+ if (opObj.op === "in") {
91
+ if (!Array.isArray(opObj.value))
92
+ throw new Error(`in clause requires array for column ${col}`);
93
+ const slots = opObj.value.map(() => `$${idx++}`);
94
+ params.push(...opObj.value);
95
+ parts.push(`${col} IN (${slots.join(", ")})`);
96
+ }
97
+ else {
98
+ const resolved = resolveNowSentinel(opObj.value, "pg");
99
+ if (resolved.kind === "sql") {
100
+ parts.push(`${col} ${PG_OP_SQL[opObj.op]} ${resolved.value}`);
101
+ }
102
+ else {
103
+ parts.push(`${col} ${PG_OP_SQL[opObj.op]} $${idx++}`);
104
+ params.push(resolved.value);
105
+ }
106
+ }
107
+ }
108
+ else {
109
+ const resolved = resolveNowSentinel(raw, "pg");
110
+ if (resolved.kind === "sql") {
111
+ parts.push(`${col} = ${resolved.value}`);
112
+ }
113
+ else {
114
+ parts.push(`${col} = $${idx++}`);
115
+ params.push(resolved.value);
116
+ }
117
+ }
118
+ }
119
+ return { fragment: parts.join(" AND "), params, nextParamIndex: idx };
120
+ }
121
+ function serializeSetToPgSql(set, startIndex) {
122
+ const parts = [];
123
+ const params = [];
124
+ let idx = startIndex;
125
+ for (const [col, raw] of Object.entries(set)) {
126
+ validateColumnName(col);
127
+ if (typeof raw === "object" && raw !== null && "increment" in raw) {
128
+ const n = raw.increment;
129
+ if (typeof n !== "number" || !Number.isFinite(n))
130
+ throw new Error(`increment must be a finite number for column ${col}`);
131
+ parts.push(`${col} = ${col} + ${n}`);
132
+ continue;
133
+ }
134
+ const resolved = resolveNowSentinel(raw, "pg");
135
+ if (resolved.kind === "sql") {
136
+ parts.push(`${col} = ${resolved.value}`);
137
+ }
138
+ else {
139
+ parts.push(`${col} = $${idx++}`);
140
+ params.push(resolved.value);
141
+ }
142
+ }
143
+ return { fragment: parts.join(", "), params, nextParamIndex: idx };
144
+ }
145
+ function serializeSetToPostgrestBody(set, observed) {
146
+ const out = {};
147
+ for (const [col, raw] of Object.entries(set)) {
148
+ validateColumnName(col);
149
+ if (typeof raw === "object" && raw !== null && "increment" in raw) {
150
+ const n = raw.increment;
151
+ if (typeof n !== "number" || !Number.isFinite(n))
152
+ throw new Error(`increment must be a finite number for column ${col}`);
153
+ const current = observed[col];
154
+ if (typeof current !== "number") {
155
+ const display = current === null ? "null" : typeof current;
156
+ throw new Error(`increment on ${col} requires observed numeric value (got ${display})`);
157
+ }
158
+ out[col] = current + n;
159
+ continue;
160
+ }
161
+ const resolved = resolveNowSentinel(raw, "postgrest");
162
+ out[col] = resolved.value;
163
+ }
164
+ return out;
165
+ }
166
+ /** Columns the caller incremented — needed for CAS witnesses on PostgrestAdapter. */
167
+ function incrementedColumns(set) {
168
+ return Object.entries(set)
169
+ .filter(([_, v]) => typeof v === "object" && v !== null && "increment" in v)
170
+ .map(([col]) => col);
171
+ }
172
+ /**
173
+ * Reject empty where/set/returning at the API boundary so adapters
174
+ * don't generate malformed SQL or — on PostgrestAdapter — accidentally
175
+ * match every row.
176
+ *
177
+ * Caller is expected to pass the full ClaimRowsOptions; types kept loose
178
+ * here because the helper lives in clause-builder which doesn't import
179
+ * from types.ts (avoids circular import risk).
180
+ */
181
+ function validateClaimRowsOptions(opts) {
182
+ if (Object.keys(opts.where).length === 0) {
183
+ throw new Error("claimRows: where must contain at least one condition");
184
+ }
185
+ if (Object.keys(opts.set).length === 0) {
186
+ throw new Error("claimRows: set must contain at least one field");
187
+ }
188
+ if (opts.returning !== undefined && opts.returning.length === 0) {
189
+ throw new Error("claimRows: returning must contain at least one column (or omit for default *)");
190
+ }
191
+ }
192
+ //# sourceMappingURL=clause-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clause-builder.js","sourceRoot":"","sources":["../../src/lib/adapters/clause-builder.ts"],"names":[],"mappings":"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"}
@@ -13,7 +13,7 @@
13
13
  * }
14
14
  * }
15
15
  */
16
- import type { HazoConnectAdapter, Logger } from '../types.js';
16
+ import type { HazoConnectAdapter, Logger, ClaimRowsOptions } from '../types.js';
17
17
  import { BaseAdapter } from './base-adapter.js';
18
18
  import { QueryBuilder } from '../query-builder.js';
19
19
  /**
@@ -46,5 +46,6 @@ export declare class FileAdapter extends BaseAdapter implements HazoConnectAdapt
46
46
  * @returns Promise with adapter-specific config
47
47
  */
48
48
  getConfig(): Promise<any>;
49
+ claimRows<T = Record<string, unknown>>(_opts: ClaimRowsOptions): Promise<T[]>;
49
50
  }
50
51
  //# sourceMappingURL=file-adapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-adapter.d.ts","sourceRoot":"","sources":["../../src/lib/adapters/file-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAGlD;;GAEG;AACH,qBAAa,WAAY,SAAQ,WAAY,YAAW,kBAAkB;IACxE;;;;OAIG;gBACS,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,MAAM;IAKxC;;;;;;OAMG;IACG,KAAK,CACT,OAAO,EAAE,YAAY,EACrB,MAAM,GAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAgB,EAC3D,IAAI,CAAC,EAAE,GAAG,GACT,OAAO,CAAC,GAAG,CAAC;IAOf;;;;;OAKG;IACG,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,GAAG,CAAC;IAOzE;;;OAGG;IACG,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC;CAGhC"}
1
+ {"version":3,"file":"file-adapter.d.ts","sourceRoot":"","sources":["../../src/lib/adapters/file-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC/E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAGlD;;GAEG;AACH,qBAAa,WAAY,SAAQ,WAAY,YAAW,kBAAkB;IACxE;;;;OAIG;gBACS,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,MAAM;IAKxC;;;;;;OAMG;IACG,KAAK,CACT,OAAO,EAAE,YAAY,EACrB,MAAM,GAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAgB,EAC3D,IAAI,CAAC,EAAE,GAAG,GACT,OAAO,CAAC,GAAG,CAAC;IAOf;;;;;OAKG;IACG,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,GAAG,CAAC;IAOzE;;;OAGG;IACG,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC;IAIzB,SAAS,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;CAGpF"}
@@ -57,6 +57,9 @@ class FileAdapter extends base_adapter_js_1.BaseAdapter {
57
57
  async getConfig() {
58
58
  return Promise.resolve(this.config.file || this.config);
59
59
  }
60
+ async claimRows(_opts) {
61
+ this.throwError(types_js_1.ErrorCode.NOT_IMPLEMENTED, "FileAdapter.claimRows: not supported by file backend");
62
+ }
60
63
  }
61
64
  exports.FileAdapter = FileAdapter;
62
65
  //# sourceMappingURL=file-adapter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-adapter.js","sourceRoot":"","sources":["../../src/lib/adapters/file-adapter.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;AAGH,uDAA+C;AAE/C,0CAAuC;AAEvC;;GAEG;AACH,MAAa,WAAY,SAAQ,6BAAW;IAC1C;;;;OAIG;IACH,YAAY,MAAW,EAAE,MAAe;QACtC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QACrB,8CAA8C;IAChD,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,KAAK,CACT,OAAqB,EACrB,SAAsD,KAAK,EAC3D,IAAU;QAEV,IAAI,CAAC,UAAU,CACb,oBAAS,CAAC,eAAe,EACzB,4EAA4E,CAC7E,CAAA;IACH,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,QAAQ,CAAC,QAAgB,EAAE,UAAuB,EAAE;QACxD,IAAI,CAAC,UAAU,CACb,oBAAS,CAAC,eAAe,EACzB,4EAA4E,CAC7E,CAAA;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,SAAS;QACb,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,CAAA;IACzD,CAAC;CACF;AAjDD,kCAiDC"}
1
+ {"version":3,"file":"file-adapter.js","sourceRoot":"","sources":["../../src/lib/adapters/file-adapter.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;AAGH,uDAA+C;AAE/C,0CAAuC;AAEvC;;GAEG;AACH,MAAa,WAAY,SAAQ,6BAAW;IAC1C;;;;OAIG;IACH,YAAY,MAAW,EAAE,MAAe;QACtC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QACrB,8CAA8C;IAChD,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,KAAK,CACT,OAAqB,EACrB,SAAsD,KAAK,EAC3D,IAAU;QAEV,IAAI,CAAC,UAAU,CACb,oBAAS,CAAC,eAAe,EACzB,4EAA4E,CAC7E,CAAA;IACH,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,QAAQ,CAAC,QAAgB,EAAE,UAAuB,EAAE;QACxD,IAAI,CAAC,UAAU,CACb,oBAAS,CAAC,eAAe,EACzB,4EAA4E,CAC7E,CAAA;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,SAAS;QACb,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,CAAA;IACzD,CAAC;IAED,KAAK,CAAC,SAAS,CAA8B,KAAuB;QAClE,IAAI,CAAC,UAAU,CAAC,oBAAS,CAAC,eAAe,EAAE,sDAAsD,CAAC,CAAA;IACpG,CAAC;CACF;AArDD,kCAqDC"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Purpose: PostgreSQL adapter powered by the `postgres` (postgres.js) driver.
3
+ *
4
+ * Supports raw SQL execution via sql.unsafe(), which is required for advanced
5
+ * Postgres features (e.g., SELECT … FOR UPDATE SKIP LOCKED) that PostgREST
6
+ * does not expose. The query(builder) method intentionally throws until Task 1.3
7
+ * adds toPgSql() to the QueryBuilder.
8
+ */
9
+ import type { Logger, ClaimRowsOptions } from '../types.js';
10
+ import { BaseAdapter } from './base-adapter.js';
11
+ import type { QueryBuilder } from '../query-builder.js';
12
+ export interface PgAdapterConfig {
13
+ type: 'pg';
14
+ connectionString: string;
15
+ poolMax?: number;
16
+ ssl?: boolean | 'require';
17
+ log_level?: string;
18
+ }
19
+ export declare class PgAdapter extends BaseAdapter {
20
+ private sql;
21
+ constructor(config: PgAdapterConfig, logger?: Logger);
22
+ /**
23
+ * Execute a query using the QueryBuilder.
24
+ * Not yet implemented — toPgSql() is added in Task 1.3.
25
+ * hazo_jobs should use raw() directly until then.
26
+ */
27
+ query(_builder: QueryBuilder, _method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE', _body?: unknown): Promise<never>;
28
+ /**
29
+ * Not applicable for the pg adapter (no HTTP layer).
30
+ * Satisfies the HazoConnectAdapter interface — use raw() for direct SQL.
31
+ */
32
+ rawQuery(_endpoint: string, _options?: RequestInit): Promise<never>;
33
+ /**
34
+ * Execute a raw SQL statement with positional parameters.
35
+ * Uses sql.unsafe() so that the caller controls the full query text.
36
+ * Parameters are passed as a plain array and forwarded to postgres.js.
37
+ *
38
+ * @param text - SQL text, e.g. "SELECT * FROM jobs WHERE id = $1"
39
+ * @param values - Positional parameter values
40
+ * @returns Array of row objects
41
+ */
42
+ raw<T = unknown>(text: string, values?: unknown[]): Promise<T[]>;
43
+ /**
44
+ * Atomically claim rows from a queue table using FOR UPDATE SKIP LOCKED.
45
+ *
46
+ * A CTE selects candidate rows matching `where`, locks them with
47
+ * SKIP LOCKED so concurrent callers never contend, then UPDATE sets
48
+ * the requested fields and returns the RETURNING projection.
49
+ *
50
+ * @param opts - Table, where filter, set patch, optional orderBy/limit/returning
51
+ * @returns Array of updated row objects (empty when no rows match)
52
+ */
53
+ claimRows<T = Record<string, unknown>>(opts: ClaimRowsOptions): Promise<T[]>;
54
+ /**
55
+ * Drain the connection pool and release all Postgres connections.
56
+ * Call this on process shutdown or when the adapter is no longer needed.
57
+ */
58
+ close(): Promise<void>;
59
+ /**
60
+ * Return the resolved adapter configuration.
61
+ */
62
+ getConfig(): Promise<PgAdapterConfig>;
63
+ }
64
+ //# sourceMappingURL=pg-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pg-adapter.d.ts","sourceRoot":"","sources":["../../src/lib/adapters/pg-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAE/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAQvD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,IAAI,CAAA;IACV,gBAAgB,EAAE,MAAM,CAAA;IACxB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,GAAG,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,qBAAa,SAAU,SAAQ,WAAW;IACxC,OAAO,CAAC,GAAG,CAAK;gBAEJ,MAAM,EAAE,eAAe,EAAE,MAAM,CAAC,EAAE,MAAM;IAYpD;;;;OAIG;IACG,KAAK,CACT,QAAQ,EAAE,YAAY,EACtB,OAAO,GAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAgB,EAC5D,KAAK,CAAC,EAAE,OAAO,GACd,OAAO,CAAC,KAAK,CAAC;IAOjB;;;OAGG;IACG,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC;IAOzE;;;;;;;;OAQG;IACG,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAS1E;;;;;;;;;OASG;IACG,SAAS,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAkClF;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,eAAe,CAAC;CAG5C"}