@palbase/backend 38.0.16 → 39.0.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 (58) hide show
  1. package/dist/bin/palbase-backend.cjs +46 -1
  2. package/dist/bin/palbase-backend.cjs.map +1 -1
  3. package/dist/bin/palbase-backend.js +5 -5
  4. package/dist/{chunk-LFUNRWUE.js → chunk-4J6I4KVQ.js} +67 -3
  5. package/dist/{chunk-LFUNRWUE.js.map → chunk-4J6I4KVQ.js.map} +1 -1
  6. package/dist/{chunk-7WAGQ3VR.js → chunk-AR2I4M7I.js} +497 -17
  7. package/dist/chunk-AR2I4M7I.js.map +1 -0
  8. package/dist/{chunk-YANGWAIM.js → chunk-H7EKL6HC.js} +2 -2
  9. package/dist/{chunk-EHKEMHB4.js → chunk-JJSR4BUX.js} +49 -5
  10. package/dist/chunk-JJSR4BUX.js.map +1 -0
  11. package/dist/{chunk-CS6NQ6PO.js → chunk-JPTFYHP3.js} +2 -2
  12. package/dist/{chunk-CS6NQ6PO.js.map → chunk-JPTFYHP3.js.map} +1 -1
  13. package/dist/{chunk-X7UR3VXA.js → chunk-XZWOMPD3.js} +3 -2
  14. package/dist/chunk-XZWOMPD3.js.map +1 -0
  15. package/dist/{chunk-PDD55QWN.js → chunk-ZNQDL466.js} +2 -2
  16. package/dist/db/index.cjs +378 -14
  17. package/dist/db/index.cjs.map +1 -1
  18. package/dist/db/index.d.cts +1 -1
  19. package/dist/db/index.d.ts +1 -1
  20. package/dist/db/index.js +3 -3
  21. package/dist/engine/index.cjs +46 -1
  22. package/dist/engine/index.cjs.map +1 -1
  23. package/dist/engine/index.d.cts +3 -3
  24. package/dist/engine/index.d.ts +3 -3
  25. package/dist/engine/index.js +5 -5
  26. package/dist/{index-CI7S0Wqv.d.cts → index-B0mjUnxy.d.cts} +25 -2
  27. package/dist/{index-CUy50OLU.d.ts → index-eN4KzGa5.d.ts} +555 -29
  28. package/dist/{index-DRx880KY.d.cts → index-pK2At5Yc.d.cts} +555 -29
  29. package/dist/{index-Ogi30dbt.d.ts → index-yDno9Ju9.d.ts} +25 -2
  30. package/dist/index.cjs +628 -17
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.d.cts +183 -8
  33. package/dist/index.d.ts +183 -8
  34. package/dist/index.js +74 -6
  35. package/dist/index.js.map +1 -1
  36. package/dist/openapi/index.cjs.map +1 -1
  37. package/dist/openapi/index.d.cts +2 -2
  38. package/dist/openapi/index.d.ts +2 -2
  39. package/dist/openapi/index.js +2 -2
  40. package/dist/{registry-C7UCkQf0.d.cts → registry-9dNeVN5d.d.cts} +1 -1
  41. package/dist/{registry-DJcvbomD.d.ts → registry-B8ddZiMY.d.ts} +1 -1
  42. package/dist/test/index.cjs +19 -0
  43. package/dist/test/index.cjs.map +1 -1
  44. package/dist/test/index.d.cts +1 -1
  45. package/dist/test/index.d.ts +1 -1
  46. package/dist/test/index.js +20 -2
  47. package/dist/test/index.js.map +1 -1
  48. package/docs/README.md +1 -1
  49. package/docs/database.md +79 -0
  50. package/docs/llms-full.txt +462 -33
  51. package/docs/schema.md +382 -32
  52. package/package.json +1 -1
  53. package/template/package.json +1 -1
  54. package/dist/chunk-7WAGQ3VR.js.map +0 -1
  55. package/dist/chunk-EHKEMHB4.js.map +0 -1
  56. package/dist/chunk-X7UR3VXA.js.map +0 -1
  57. /package/dist/{chunk-YANGWAIM.js.map → chunk-H7EKL6HC.js.map} +0 -0
  58. /package/dist/{chunk-PDD55QWN.js.map → chunk-ZNQDL466.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/db/input-guards.ts","../src/db/tx-plan.ts","../src/db/schema-json.ts","../src/db/transaction-options.ts"],"sourcesContent":["/**\n * The refusals a Database call gets BEFORE any SQL exists — written once, so the\n * engine and the test double cannot disagree about them.\n *\n * WHY THIS FILE EXISTS. `fakeDatabase()` is a second implementation of the same\n * surface (`__tests__/helpers/mock-db.ts`), and it never touched `compileWhere`\n * or `asBindParams`. Measured against the published 24.1.0: all four of the\n * calls that release had just started refusing went through the fake SILENTLY —\n * `update{title:undefined}`, `insert{title:undefined}`, `findMany{done:{}}`,\n * `deleteMany{owner,created_at:{}}`.\n *\n * The scaffold tells authors to test the service layer against exactly that\n * fake. So a test went green on a call production would throw on, and the\n * author found out in production instead — the same \"the surface does not match\n * the engine\" shape these refusals exist to end, arriving through the door the\n * SDK hands people for testing.\n *\n * These are pure and SQL-free on purpose: an in-memory store can run them as\n * easily as the driver path can.\n */\n\n/**\n * İşaretçilerin MARKASI — `col()` ve `sqlFragment()` ürünlerini bu süreçte\n * üretilmiş olmakla tanımlar.\n *\n * NEDEN ŞEKİL DEĞİL DE MARKA (gözcü W2-A/C1 ve W2-B/C3, ikisi de ÖLÇTÜ):\n * şekil kontrolü, işaretçiyi güvenilmeyen bir istek gövdesinden UYDURULABİLİR\n * kılıyordu. Ölçülen iki sonuç:\n *\n * findMany(\"docs\", { owner_id: JSON.parse('{\"$col\":\"owner_id\"}') })\n * → WHERE true AND t.\"owner_id\" = t.\"owner_id\" ← kiracılık predikatı totoloji\n * findMany(\"todos\", JSON.parse('{\"$sql\":{\"text\":[\"1=1 -- pwned\"],\"values\":[]}}'))\n * → WHERE true AND 1=1 -- pwned ← saldırganın metni SQL'e HARFİYEN\n *\n * `{ where: { tenant_id: tid, ...req.body.filter } }` bu SDK'nın öğrettiği\n * desen; T010/T014 öncesinde aynı anahtarlar \"bilinmeyen operatör\" diye\n * REDDEDİLİYORDU. Marka o reddi geri getiriyor.\n *\n * Sembol GLOBAL kayıttan (`Symbol.for`) ve ENUMERABLE DEĞİL. İkisi de kasıtlı:\n * global kayıt paketin iki kopyası arasında da eşleşir; enumerable olmaması ise\n * `JSON.stringify` ve `{...ref, gt: 5}` yayılımının markayı DÜŞÜRMESİNİ sağlar —\n * yani telden geçen ya da elle karıştırılan hiçbir şey işaretçi sayılmaz.\n * Kardeş özellik (`increment`) zaten `Symbol.for(\"palbase.tx.expr\")` kullanıyor;\n * bu onun aynısı.\n */\nconst REF_BRAND = Symbol.for(\"palbase.db.ref\");\n\n/** İşaretçiyi markalar. Yalnız `col()` ve `sqlFragment()` çağırır. */\nexport function brandRef<T extends object>(v: T, kind: \"col\" | \"sql\" | \"ref\"): T {\n Object.defineProperty(v, REF_BRAND, { value: kind, enumerable: false });\n return v;\n}\n\nfunction brandOf(v: unknown): unknown {\n if (typeof v !== \"object\" || v === null) return undefined;\n // KENDİ özelliği olmalı, prototip zincirinden MİRAS ALINMIŞ değil:\n // `Object.create(col(\"x\"))` markayı zincirden okuyup işaretçi sayılıyordu\n // (gözcü ölçtü). Telden erişilemez — JSON `__proto__` üstünden sembol\n // yazamaz — ama daraltmak bedava ve \"işaretçi bu süreçte ÜRETİLDİ\"\n // iddiasının tam karşılığı budur.\n return Object.hasOwn(v, REF_BRAND) ? (v as Record<symbol, unknown>)[REF_BRAND] : undefined;\n}\n\n/**\n * Bir değer, MARKASIZ bir işaretçi taklidi mi? (`{$col:…}` / `{$sql:…}`)\n *\n * Üst düzeyde bunlar zaten \"bilinmeyen operatör\" diye reddediliyor. Ama\n * operatörün SAĞINDA — `{ amount: { gt: {\"$col\":\"other\"} } }` — sessizce\n * PARAMETRE olarak bağlanıyorlardı: sayısal kolonda sürücünün 22P02'si,\n * jsonb/text kolonunda ise HİÇBİR SATIR, hatasız (gözcü ölçtü).\n *\n * `in` listesindeki aynı kusur adıyla reddediliyor; bu onun bir seviye\n * yanındaki hâli ve aynı cevabı hak ediyor.\n */\nexport function looksLikeUnbrandedRef(v: unknown): \"col\" | \"sql\" | \"expr\" | null {\n if (typeof v !== \"object\" || v === null) return null;\n if (brandOf(v) !== undefined) return null; // gerçek işaretçi\n if (isColumnExpr(v)) return null; // gerçek ifade tutamağı (kendi markası var)\n const o = v as { $col?: unknown; $sql?: unknown; $expr?: unknown };\n if (typeof o.$col === \"string\") return \"col\";\n if (o.$sql !== undefined && typeof o.$sql === \"object\" && o.$sql !== null) return \"sql\";\n // `$expr` `now()`/`increment()`'in TEL BİÇİMİ. `now()` filtrede geçerli bir\n // değer olduğu andan itibaren bu şekil de uydurulabilir hâle geldi: ÖLÇÜLDÜ,\n // gövdeden gelen `{\"$expr\":{\"fn\":\"now\"}}` sessizce PARAMETRE olarak bağlanıp\n // sorguyu hatasız biçimde boş sonuca çeviriyordu. `$col`/`$sql`/`$ref` ile\n // aynı kapı, aynı gerekçe.\n if (o.$expr !== undefined && typeof o.$expr === \"object\" && o.$expr !== null) return \"expr\";\n return null;\n}\n\n/**\n * `col()` ürünü mü? (FR-011)\n *\n * Burada, çünkü bu dosya \"iki uygulamanın da okuduğu kurallar\" dosyası: motor,\n * `fakeDatabase` ve guard AYNI cevabı vermek zorunda.\n */\nexport function isColRef(v: unknown): v is { readonly $col: string } {\n return brandOf(v) === \"col\" && typeof (v as { $col?: unknown }).$col === \"string\";\n}\n\n/**\n * `sqlFragment` ürünü mü? (FR-018)\n *\n * `isColRef` ile aynı gerekçeyle burada: motor, guard ve `fakeDatabase` üçü de\n * aynı cevabı vermek zorunda — biri fragment'i \"kolon haritası\" sanarsa filtre\n * sessizce düşer.\n */\n/**\n * Plan REFERANSI mı? (`{ $ref: { op, field } }`)\n *\n * `$ref` bu dilin MARKASIZ KALAN TEK işaretçisiydi — `engine/db.ts` onu\n * `\"$ref\" in v` diye tanıyordu — ve SDK'nın öğrettiği desen\n * `{ where: { tenant_id: tid, ...req.body.filter } }`. Ölçüldü (gözcü):\n * istek gövdesinden gelen `{\"id\":{\"$ref\":{\"op\":0,\"field\":\"id\"}}}` filtreyi\n * ÖNCEKİ bir işlemin satır değeriyle karşılaştırtıyor —\n * DELETE … WHERE t.\"tenant_id\" = $1 AND t.\"id\" = $2 PRM [\"t1\",\"SIZAN_DEGER\"]\n * gövdenin hiç görmediği bir değer. Enjeksiyon değil (değerler bound) ama bir\n * ORACLE: `op`/`field` seçip `rows_affected`'tan o değeri öğrenmek.\n *\n * Marka `Symbol.for` olduğu için SDK'nın İKİ KOPYASI arasında da eşleşiyor —\n * kontrolcü bundle'ı kendi kopyasını inline ediyor, planı çalıştıran ise\n * runtime'ınki. Ve plan gövdesi JSON'lanmıyor: tek üretim `txPlan` uygulaması\n * süreç içi (`engine/db.ts`), doğrulandı.\n */\nexport function isPlanRef(v: unknown): v is { readonly $ref: { op: number; field: string } } {\n if (brandOf(v) !== \"ref\") return false;\n const r = (v as { $ref?: { op?: unknown; field?: unknown } }).$ref;\n return r !== undefined && typeof r.op === \"number\" && typeof r.field === \"string\";\n}\n\n/** Markasız bir `{ $ref: … }` taklidi mi? Adıyla reddedilmesi için. */\nexport function looksLikeUnbrandedPlanRef(v: unknown): boolean {\n if (typeof v !== \"object\" || v === null || brandOf(v) !== undefined) return false;\n const r = (v as { $ref?: unknown }).$ref;\n return r !== undefined && typeof r === \"object\" && r !== null;\n}\n\nexport function isSqlFragment(v: unknown): v is { readonly $sql: { text: string[]; values: unknown[] } } {\n if (brandOf(v) !== \"sql\") return false;\n const f = (v as { $sql?: { text?: unknown; values?: unknown } }).$sql;\n return f !== undefined && Array.isArray(f.text) && Array.isArray(f.values);\n}\n\n/**\n * İFADE TUTAMAĞI DEĞER DEĞİLDİR — değer bekleyen yollarda adıyla reddedilir.\n *\n * `increment()` / `decrement()` / `now()` bir Proxy döndürür ve yalnız\n * `updateMany` ile plan yolunun `updateWhere`'i onu SQL'e derler. `insert` /\n * `update` / `put` / `supersede` derlemez; oralarda tutamak bound parametre\n * olarak sürücüye gidiyordu ve reddi SÜRÜCÜ veriyordu (\"Unknown object is not\n * a valid PostgreSQL type\") — yazarın yazdığı hiçbir şeyi adlandırmayan bir\n * mesaj (inceleme I-2/I8, ölçüldü). Plan yolu aynı hatayı kendi diliyle\n * reddediyor; bu, doğrudan yolun karşılığı.\n *\n * Sembol `tx-plan.ts`'in markasıyla AYNI global kayıttan okunuyor; bu dosya\n * kural dosyası olduğu için oraya bağımlılık kurmuyor.\n */\nconst TX_EXPR = Symbol.for(\"palbase.tx.expr\");\n\n/**\n * `now()` — SUNUCU SAATİ, karşılaştırma değeri olarak.\n *\n * `increment()`/`decrement()` bir YAZMA ifadesidir ve filtrede anlamsızdır;\n * `now()` öyle değil: `expires_at > now()` sıradan bir karşılaştırma ve her\n * backend'in en sık yazdığı yüklemlerden biri. Filtrede TÜM ifade tutamaklarını\n * reddetmek, yazarı bunun için `sqlFragment`e düşürüyordu — yani sorgunun\n * içine giren parça, en sıradan koşul için gerekiyordu.\n *\n * Ayrım MARKAYLA: bir istek gövdesinden gelen `{\"$expr\":{\"fn\":\"now\"}}` bu\n * süreçte `now()` ile üretilmediği için marka taşımaz ve reddedilir.\n */\nexport function isNowExpr(v: unknown): boolean {\n if (!isColumnExpr(v)) return false;\n try {\n const e = (v as Record<symbol, unknown>)[TX_EXPR];\n return typeof e === \"object\" && e !== null && (e as { fn?: unknown }).fn === \"now\";\n } catch {\n return false;\n }\n}\n\nexport function isColumnExpr(v: unknown): boolean {\n if (typeof v !== \"object\" && typeof v !== \"function\") return false;\n if (v === null) return false;\n try {\n return (v as Record<symbol, unknown>)[TX_EXPR] !== undefined;\n } catch {\n // Tutamak bir Proxy; bilinmeyen bir prop'ta trap fırlatabilir.\n return false;\n }\n}\n\n/**\n * Değer bekleyen bir yazma yolunda ifade tutamağı ya da `col()` var mı?\n *\n * Motor ve `fakeDatabase` AYNI cevabı vermek zorunda: fake tutamağı satıra\n * YAZIYORDU (`row[k] = proxy`) ve satır artık JSON'a bile çevrilemiyordu, motor\n * ise sürücüde patlıyordu. İki farklı yanlış, tek doğru.\n */\nexport function assertNoExpressionHandles(\n caller: string,\n table: string,\n cols: readonly string[],\n data: Record<string, unknown>,\n): void {\n for (const c of cols) {\n const v = data[c];\n // `now()` ile sayaç ifadeleri AYRI cevaplar hak ediyor: ikisinin de\n // çalışan alternatifi var ama farklı (P6 — hata çalışan bir alternatifi\n // ADIYLA söyler). Tek bir \"ifade tutamağı\" mesajı, `now()` yazan kişiye\n // `increment()` öneriyordu.\n if (isNowExpr(v)) {\n throw new Error(\n `${caller}(${table}): \"${c}\" now() aldı — bu yolda değer beklenir. ` +\n `Satır EKLENİRKEN sunucu saatini yazmanın yolu kolonu defaultNow() ile ` +\n `bildirmek (varsayılan kolonun yanında durur, her çağrıda tekrarlanmaz); ` +\n `var olan bir satırı damgalamak için updateMany({ where, set: { ${c}: now() } }) ` +\n `ya da $transaction içinde tx.public.${table}.updateWhere(where, { ${c}: now() }).`,\n );\n }\n if (isColumnExpr(v)) {\n throw new Error(\n `${caller}(${table}): \"${c}\" bir ifade tutamağı aldı (increment()/decrement()). ` +\n `Bu yolda değer beklenir. Sayaç artışı için updateMany({ where, set: { ${c}: increment(n) } }) ` +\n `ya da $transaction içinde tx.public.${table}.updateWhere(where, { ${c}: increment(n) }) kullanın.`,\n );\n }\n if (isColRef(v)) {\n throw new Error(\n `${caller}(${table}): \"${c}\" bir col() aldı. Kolon referansı yalnız FİLTREDE durabilir; ` +\n `bir kolonun değerini başka bir kolona yazmak için $query kullanın.`,\n );\n }\n }\n}\n\n/** The comparison operators a filter value may carry. Kept here because the\n * guard has to tell an operator object from a plain value. */\nconst KNOWN_OPS = new Set([\n \"gt\", \"gte\", \"lt\", \"lte\", \"neq\", \"in\",\n // K1 metin operatörleri (FR-005) ve null testi (FR-006). Bu küme\n // `fakeDatabase()` ile ORTAK kaynaktır: fake bir çağrıyı motorun reddettiği\n // yerde kabul ederse, yazarın testi üretimde patlayan koda karşı yeşil verir.\n \"contains\", \"icontains\", \"startsWith\", \"endsWith\", \"isNull\",\n]);\n\n/**\n * `eq` ADIYLA reddedilir, ve reddi buradadır çünkü guard'ı motor da fake de\n * okuyor.\n *\n * Eşitliğin yazımı ÇIPLAK DEĞERDİR: `{ owner: \"u1\" }`. `eq`'i ikinci bir yazım\n * olarak eklemek, bu run'ın kapatmak için var olduğu şeyi — aynı iş için iki\n * uyumsuz yazım — filtre dilinin İÇİNDE yeniden açardı. Ve eskiden kabul eden\n * ile reddeden ayrışıyordu: guard `eq`'i geçiriyor, derleyici\n * `bilinmeyen operatör \"eq\"` diyordu (gözcü ölçtü).\n */\nconst REFUSED_OPS: Record<string, string> = {\n eq: 'eşitlik ÇIPLAK yazılır: { <kolon>: <değer> } (ya da kolon karşılaştırması için { <kolon>: col(\"…\") })',\n};\n\n/**\n * Refuse a filter that would compile to something other than what it reads like.\n *\n * Three shapes, each measured in production before it was closed:\n *\n * `{ col: undefined }` binds NULL; `= NULL` matches no row, so the query\n * answered \"no records\" and said nothing.\n * `{ col: {} }` produces no term at all — every row on the read\n * path, a dropped condition on the write path.\n * `{ col: { gte: undefined } }` and an `undefined` inside `in`: the same NULL,\n * one level down.\n */\nexport function assertUsableFilter(\n caller: string,\n table: string,\n where: Record<string, unknown> | undefined,\n): void {\n // Bileşim anahtarları (FR-007) bir KOLON adı değildir; kolon doğrulamasından\n // ve operatör kontrolünden muaftır, kendi dalları özyinelemeli olarak aynı\n // kurallardan geçer.\n const COMPOSITES = new Set([\"OR\", \"AND\", \"NOT\"]);\n\n if (!where) return;\n // Fragment bir kolon haritası DEĞİLDİR (FR-018): içeriği SQL'dir, kolon\n // doğrulaması ona uygulanamaz. Değerleri zaten bound gidiyor.\n if (isSqlFragment(where)) return;\n for (const [col, cond] of Object.entries(where)) {\n // Bileşim anahtarları (FR-007) kolon DEĞİLDİR: dalları aynı kurallardan\n // özyinelemeli geçer, ama kendileri operatör kontrolüne girmez.\n if (COMPOSITES.has(col)) {\n const branches = col === \"NOT\" ? [cond] : cond;\n if (!Array.isArray(branches) && col !== \"NOT\") {\n throw new Error(`${caller}(${table}): where.${col} bir dizi olmalı`);\n }\n for (const b of branches as unknown[]) {\n if (b === null || typeof b !== \"object\") {\n throw new Error(`${caller}(${table}): where.${col} dalları filtre nesnesi olmalı`);\n }\n assertUsableFilter(caller, table, b as Record<string, unknown>);\n }\n continue;\n }\n // `has` de kolon DEĞİLDİR: anahtarları İLİŞKİ adları, değerleri BİR TABLO\n // ÖTESİNİN filtresi. İç filtre aynı kurallardan geçiyor — `has` ikinci bir\n // filtre dili değil, aynı dilin bir tablo ötesi.\n //\n // İlişki ADI burada doğrulanMIYOR: grafiği yalnız motor tanıyor (ve tip,\n // derleme anında). Guard'ın onu bilmesi ilişki grafiğinin İKİNCİ bir\n // yorumcusu demekti — `buildRelations`'ın yorumunun adıyla yasakladığı şey.\n if (col === \"has\") {\n if (cond === null || typeof cond !== \"object\" || Array.isArray(cond)) {\n throw new Error(`${caller}(${table}): where.has bir ilişki haritası olmalı ({ <ilişki>: { … } })`);\n }\n for (const [rel, inner] of Object.entries(cond as Record<string, unknown>)) {\n if (inner === null || typeof inner !== \"object\" || Array.isArray(inner)) {\n throw new Error(`${caller}(${table}): where.has.${rel} bir filtre nesnesi olmalı`);\n }\n assertUsableFilter(caller, table, inner as Record<string, unknown>);\n }\n continue;\n }\n if (cond === undefined) {\n throw new Error(\n `${caller}(${table}): where.${col} değeri undefined — bu bir filtre değeri değil. ` +\n `Bağlanınca NULL olur ve '= NULL' hiçbir satıra uymaz, yani sorgu sessizce ` +\n `boş sonuç dönerdi. Değer yoksa anahtarı filtreye hiç koymayın.`,\n );\n }\n if (cond === null || typeof cond !== \"object\" || Array.isArray(cond)) continue;\n // `col()` ürünü bir DEĞER'dir, operatör nesnesi değil (FR-011). Ayırt\n // edilmezse `{ $col: \"x\" }` bir operatör haritası sanılır ve \"bilinmeyen\n // operatör $col\" diye reddedilirdi.\n if (isColRef(cond)) continue;\n // `now()` de bir DEĞER'dir, aynı gerekçeyle — ve tutamak bir Proxy olduğu\n // için `Object.entries` BOŞ döner: ayırt edilmezse \"boş operatör nesnesi\"\n // diye reddedilirdi, yani doğru yazım yanlış bir hatayla karşılanırdı.\n if (isNowExpr(cond)) continue;\n\n const entries = Object.entries(cond as Record<string, unknown>);\n if (entries.length === 0) {\n throw new Error(\n `${caller}(${table}): where.${col} boş bir operatör nesnesi ({}) — hiçbir koşul ` +\n `üretmez, yani bu alan filtreden sessizce DÜŞERDİ. Koşul kurulmayacaksa ` +\n `anahtarı filtreye hiç koymayın (D-21).`,\n );\n }\n for (const [op, v] of entries) {\n if (op === \"in\") {\n if (!Array.isArray(v)) throw new Error(`${caller}(${table}): where.${col}.in bir dizi olmalı`);\n if (v.some((x) => x === undefined)) {\n throw new Error(\n `${caller}(${table}): where.${col}.in listesinde undefined var — sessizce NULL'a ` +\n `bağlanır ve o eleman hiçbir satırla eşleşmez. Listeyi kurarken eleyin.`,\n );\n }\n continue;\n }\n // Sağ tarafta kolon durabilir: `{ total: { gt: col(\"amount_paid\") } }`.\n // Değer kontrolleri (undefined) ona da uygulanır, ama `in` gibi şekil\n // kontrolleri değil — o dal aşağıda zaten ayrı.\n if (REFUSED_OPS[op] !== undefined) {\n // Bilinmeyen değil — BİLİNEREK reddedilen. Hata çalışan yazımı söylüyor.\n throw new Error(`${caller}(${table}): where.${col}.${op} bu filtre dilinde yok — ${REFUSED_OPS[op]}`);\n }\n if (!KNOWN_OPS.has(op)) {\n throw new Error(\n `${caller}(${table}): where.${col} bilinmeyen operatör \"${op}\" (gt/gte/lt/lte/neq/in/contains/icontains/startsWith/endsWith/isNull)`,\n );\n }\n if (v === undefined) {\n throw new Error(\n `${caller}(${table}): where.${col}.${op} değeri undefined — karşılaştırmanın ` +\n `sağ tarafı NULL olur ve sonuç hiçbir satıra uymaz. Koşulu kurmayın.`,\n );\n }\n }\n }\n}\n\n/**\n * Refuse a write whose value never arrived.\n *\n * `{ title: req.body.title }` with no `title` in the body bound NULL and\n * answered 200 — the column was ERASED. `null` is untouched, and the difference\n * is the whole point: null is an author SAYING \"empty this column\"; undefined is\n * nobody saying anything.\n */\nexport function assertUsableWriteValues(\n caller: string,\n table: string,\n cols: readonly string[],\n data: Record<string, unknown>,\n): void {\n for (const c of cols) {\n if (data[c] === undefined) {\n throw new Error(\n `${caller}(${table}): \"${c}\" değeri undefined — bu bir yazma değeri değil. ` +\n `Kolonu boşaltmak istiyorsan null yaz; kolonu değiştirmek istemiyorsan nesneye hiç koyma ` +\n `(bir eksik istek alanı sessizce NULL yazıyordu — FR-016).`,\n );\n }\n }\n}\n","/**\n * tx-plan.ts — `Database.$transaction()` as a PLAN, not a pinned session.\n *\n * A transaction used to be a conversation: BEGIN, then one network round trip\n * per operation, then COMMIT. Each of those round trips cost ~4 ms and, because\n * the pooler runs in transaction mode, an open transaction pinned a Postgres\n * backend for the whole conversation. A 121-operation statement upload pinned\n * one backend for ~490 ms.\n *\n * So the callback no longer TALKS to the database. It DESCRIBES what should\n * happen; the description is serialised and sent once; the broker runs the whole\n * thing inside one transaction and answers once. Committing on return and\n * rolling back on throw is unchanged — that is the only property tenant code\n * actually asked for.\n *\n * The consequences, stated plainly, because they are the whole design:\n *\n * - The callback is SYNCHRONOUS. There is nothing to await: no statement has\n * run yet when it returns. `async` on the callback and `await` inside it are\n * both compile errors (see {@link TxPlan} and {@link NotAwaitable}).\n * - `insert()` does not hand back a row, it hands back {@link TxRows}. Reading\n * a field requires `.expectOne(err)` first, which makes \"what if the row\n * isn't there\" a question you cannot route around: it is the argument.\n * - A field read from a row is a {@link Ref} — a PROMISE OF A VALUE THE SERVER\n * WILL PRODUCE, not the value. It can be written into a later operation and\n * it can be returned from the callback (it is substituted for the real value\n * before `transaction()` resolves). It cannot be branched on. See the\n * \"Truthiness\" note below — this is the sharp edge of the whole design.\n * - Control flow that needs a real value must move OUT of the callback: read\n * before the transaction, or express the condition as a guard\n * (`updateWhere({ id, accepted_at: null }, …).expectOne(new Conflict(…))`)\n * which the server evaluates and which rolls the whole plan back.\n *\n * # Truthiness — the hole this file CANNOT close\n *\n * JavaScript does not let a Proxy trap truthiness. `if (ref)` takes the true\n * branch, always, for every Ref, and no `get` handler ever runs. `tsc` is silent\n * because a Ref is a perfectly good object. So:\n *\n * const pot = tx.tables.pots.select({ id }, { limit: 1 }).expectOne(e);\n * if (!pot.balance) { … } // ← ALWAYS false. Silently wrong data.\n *\n * What this file does close: coercion (`Symbol.toPrimitive`/`valueOf`/\n * `toString`), awaiting (`then` is a callable member with a non-thenable\n * signature, which is a *compile* error), serialisation (`toJSON`), and nesting\n * a Ref inside a literal value where the server would store it as data. What it\n * cannot close is a bare truthiness test. The real defence is the build-time\n * static analysis (`tx_analysis.js`, phase P4); until that ships, this hole is\n * open and this comment is the only warning.\n *\n * # Wire contract\n *\n * The JSON this file emits is consumed by\n * the plan executor in `engine/db.ts`. That executor rejects\n * unknown fields at every level, so an op carries EXACTLY the fields its kind\n * takes. Everything here that looks like a needless restriction is one of the\n * server's rules made visible early:\n *\n * - `$ref` only points BACKWARDS, and only at an op statically known to yield\n * at most one row (insert, or a `one`/`atMost 1` guard, or `select limit 1`).\n * `.expectOne()` is what this file uses to satisfy that, always.\n * - `$expr` is a closed set: `inc`/`dec` (update only — they read the column's\n * current value) and `now()`.\n * - `update`/`delete` require a `where`; `insert` refuses one.\n * - `insertMany` rows must all set the same columns.\n * - ≤1000 ops, ≤5000 rows per insertMany, ≤8 MiB of JSON.\n *\n * Column keys are emitted SORTED, so the same callback always produces byte-\n * identical JSON. That is what lets the Go decoder be locked to golden files\n * this SDK emits (`testdata/tx_plan_golden/`).\n */\n\n// ---------------------------------------------------------------------------\n// Errors\n// ---------------------------------------------------------------------------\n\n/**\n * A plan handle was used as if it were a value: awaited, coerced to a string or\n * number, serialised, or nested inside another value.\n *\n * Thrown while the callback is still BUILDING the plan, so nothing has been sent\n * and nothing has been written.\n */\n// TİP-ONLY, ve döngü kasıtlı: `typed-db.ts` bu dosyadan tip alıyor, bu dosya\n// ondan `WhereOp` alıyor. Çalışma zamanında hiçbir şey ithal edilmiyor (import\n// type), yani modül döngüsü yok — paylaşılan olan şey TEK FİLTRE DİLİ, ve onu\n// iki yerde ayrı ayrı tanımlamak bu run'ın kapattığı \"iki yazım\"ın tipteki\n// hâli olurdu.\nimport type { WhereOpWith, ColRefOf, HasOnly, SqlFragment } from \"./typed-db.js\";\nimport { isColRef, isSqlFragment, brandRef, isNowExpr } from \"./input-guards.js\";\n\nexport class TxRefError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"TxRefError\";\n }\n}\n\n/**\n * The plan the callback described cannot be sent: it breaks a rule the server\n * would reject, and rejecting it here names the line that wrote it instead of\n * returning a 400 about an op index.\n */\nexport class TxPlanError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"TxPlanError\";\n }\n}\n\n// ---------------------------------------------------------------------------\n// Wire types — mirror the plan executor in `engine/db.ts` exactly.\n// ---------------------------------------------------------------------------\n\n/** A backwards reference to an earlier op's single-row result. */\nexport interface TxWireRef {\n $ref: { op: number; field: string };\n}\n\n/** A call from the server's closed function set. */\nexport interface TxWireExpr {\n $expr: { fn: \"inc\" | \"dec\"; by: number | string } | { fn: \"now\" };\n}\n\n/** One value in a `values`/`set`/`where` map: a literal, a `$ref` or a `$expr`. */\nexport type TxWireValue = TxWireRef | TxWireExpr | unknown;\n\n/** The tenant's declared expectation about an op's row count. `slot` indexes the\n * client-side error table — the error OBJECT never travels. */\nexport interface TxWireGuard {\n kind: \"one\" | \"none\" | \"atLeast\" | \"atMost\";\n n: number;\n slot: number;\n}\n\n/** One operation in the wire plan. Fields are omitted, never null: the decoder\n * rejects a field that does not belong to the op's kind. */\nexport interface TxWireOp {\n /** upsert and insertMany: the columns Postgres matches on. */\n onConflict?: readonly string[];\n /** insertMany only: what a collision does. Absent means no ON CONFLICT clause\n * at all, which is what every insertMany did before this option existed. */\n action?: \"ignore\" | \"update\";\n op: \"insert\" | \"insertMany\" | \"upsert\" | \"update\" | \"delete\" | \"select\";\n table: string;\n values?: Record<string, TxWireValue>;\n rows?: Record<string, TxWireValue>[];\n set?: Record<string, TxWireValue>;\n where?: Record<string, TxWireValue>;\n limit?: number;\n lock?: \"update\";\n guard?: TxWireGuard;\n}\n\n/** The plan the engine executes on the request's own transaction. */\nexport interface TxPlanBody {\n ops: TxWireOp[];\n}\n\n/** One op's outcome, positionally matched to the plan's ops. */\nexport interface TxPlanOpResult {\n rows: Record<string, unknown>[];\n rows_affected: number;\n}\n\n/** One result per op, in plan order. */\nexport interface TxPlanResponse {\n results: TxPlanOpResult[];\n}\n\n/**\n * The fields the runtime must copy from the broker's error envelope onto the\n * rejection it throws out of {@link DBClient.txPlan}.\n *\n * `slot` is the whole point: on a guard failure the server answers with the\n * INDEX of the expectation that did not hold, never with an error message of its\n * own, and this SDK maps that index back to the `Error` the callback handed to\n * `.expectOne(…)`. Without `slot` a guard failure degrades to a generic 409.\n */\nexport interface TxPlanRejection {\n status?: number;\n /** `tx_plan_invalid` | `tx_guard_failed` | `tx_ref_unresolved` | a pg class. */\n error_code?: string;\n /** Present only for `tx_guard_failed`: the client-side error table index. */\n slot?: number;\n /** Present on a database error: which op failed. */\n op?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Handle types\n// ---------------------------------------------------------------------------\n\ndeclare const refBrand: unique symbol;\ndeclare const rowBrand: unique symbol;\ndeclare const rowsBrand: unique symbol;\n\n/**\n * Makes a handle a compile error to `await`.\n *\n * `then` is declared as a CALLABLE member whose signature is not `PromiseLike`,\n * which is precisely the shape TypeScript rejects: `await handle` is TS1320 and\n * `async () => handle` is TS1058. A non-callable `then` would not do it — the\n * compiler simply ignores those.\n */\nexport interface NotAwaitable {\n /** Not a promise. Nothing here has run yet; there is nothing to await. */\n then(doNotAwaitAPlanHandle: \"a transaction plan is built synchronously\"): never;\n}\n\n/**\n * A value the SERVER will produce, standing in for a column of a row this plan\n * writes or reads.\n *\n * Legal uses: write it into a later operation's `values`/`set`/`where`, or\n * return it from the callback (it is replaced by the real value before\n * `transaction()` resolves).\n *\n * Illegal, and caught: `await`, `String(ref)`, `` `${ref}` ``, `ref + 1`,\n * `JSON.stringify(ref)`, burying it inside a jsonb object.\n *\n * Illegal, and NOT caught: `if (ref)`. See the truthiness note at the top.\n */\nexport interface Ref<T> extends NotAwaitable {\n readonly [refBrand]: T;\n}\n\n/** The brand carried by a single-row handle, and the seam `Materialized` reads\n * to turn `return st` into the whole row. */\nexport interface TxRowHandle<Row> extends NotAwaitable {\n readonly [rowBrand]: Row;\n}\n\n/**\n * A row this plan is known to produce exactly one of. Every property is a\n * {@link Ref}; returning the handle itself yields the whole row.\n *\n * Only `.expectOne(err)` produces one — which is the design: a row you can read\n * fields from is a row whose absence you have already answered for.\n */\nexport type TxRow<Row> = { readonly [K in keyof Row]: Ref<Row[K]> } & TxRowHandle<Row>;\n\n/**\n * The result of one operation, before any expectation is declared about it.\n *\n * Deliberately not a row and not a list: an operation's row count is not known\n * until the server runs it, so the only thing that can be said about it here is\n * an EXPECTATION. Declaring one is also the only way to get a readable row.\n *\n * At most one expectation per operation — the wire carries one guard per op, and\n * a second call throws rather than silently dropping the first.\n */\nexport interface TxRows<Row> extends NotAwaitable {\n readonly [rowsBrand]: Row;\n /**\n * Require exactly one row, and read it. On any other count the server rolls\n * the whole transaction back and this `error` is thrown to the caller.\n *\n * This is the only way to reach a row's fields, and the only shape a `$ref`\n * may point at.\n */\n expectOne(error: Error): TxRow<Row>;\n /** Require zero rows (e.g. \"this membership must not already exist\"). */\n expectNone(error: Error): void;\n /** Require at least `n` rows. */\n expectAtLeast(n: number, error: Error): void;\n /** Require at most `n` rows. */\n expectAtMost(n: number, error: Error): void;\n}\n\n/** `now()` — the server's clock, usable wherever a value is. */\nexport interface TxNow extends NotAwaitable {\n readonly $expr: { fn: \"now\" };\n}\n\n/** `inc(n)` / `dec(n)` — read the column's CURRENT value and write it back\n * changed. Only meaningful in an update's `set`, which is where the types allow\n * it and where the server allows it. */\nexport interface TxColumnExpr extends NotAwaitable {\n readonly $expr: { fn: \"inc\" | \"dec\"; by: number | string };\n}\n\n/**\n * Resolve a callback's return type against what actually comes back: every\n * {@link Ref} becomes its value, every {@link TxRow} becomes its row, and\n * anything else keeps its shape.\n *\n * A {@link TxRows} resolves to an explanatory string type rather than a row\n * list: it has no single answer to give, and saying so in the type is louder\n * than a runtime throw.\n */\nexport type Materialized<T> = T extends Ref<infer U>\n ? U\n : T extends TxRowHandle<infer R>\n ? R\n : T extends TxRows<unknown>\n ? \"a TxRows cannot leave the transaction callback — read a row with .expectOne(err) first\"\n : T extends Date\n ? T\n : T extends object\n ? { [K in keyof T]: Materialized<T[K]> }\n : T;\n\n// ---------------------------------------------------------------------------\n// Author-facing value types\n// ---------------------------------------------------------------------------\n\n/** A value written by an INSERT: a literal, an earlier row's field, or `now()`.\n * `inc`/`dec` are absent on purpose — they read a current value, and an inserted\n * row has none. */\nexport type TxInsertValue<V> = V | Ref<V> | TxNow;\n\n/** A value written by an UPDATE's `set`: everything an insert takes, plus the\n * read-modify-write expressions. */\n/**\n * TEK KURAL: ifade tutamağı yalnız sayısal-benzeri kolonlarda.\n *\n * Bu tip KOŞULSUZDU ve doğrudan yolun `SetValue<V>`'si koşulluydu, yani aynı\n * nesne için İKİ tip kuralı vardı: `tx.tables.todos.updateWhere({id}, { done:\n * increment(1) })` (boolean kolon!) DERLENİYOR, `updateMany`'nin aynısı derleme\n * hatası veriyordu. Bu run'ın kapatmak için var olduğu şey \"aynı iş için iki\n * uyumsuz yazım\"dı; tip kuralı ikinci yazımın kendisi olmuştu (gözcü I6/I-1).\n */\nexport type TxSetValue<V> =\n | V\n | Ref<V>\n | TxNow\n | (NonNullable<V> extends number | string ? TxColumnExpr : never);\n\n/** An insert payload: the table's insert shape, with refs and `now()` allowed. */\nexport type TxInsertShape<Insert> = { [K in keyof Insert]: TxInsertValue<Insert[K]> };\n\n/** An update's `set`: any subset of the insert shape, with expressions allowed. */\nexport type TxSetShape<Insert> = { [K in keyof Insert]?: TxSetValue<Insert[K]> };\n\n/**\n * A filter. Every entry is an equality test and they are AND-ed; a `null`\n * becomes `IS NULL`, which is what makes `{ accepted_at: null }` a usable\n * \"not yet accepted\" guard rather than a clause that matches nothing.\n */\n/**\n * Plan filtresinin tipi — `WhereFilter<Row>` ile AYNI sözlük, artı `Ref`.\n *\n * Eskiden yalnız eşitlikti (`Row[K] | Ref<Row[K]>`), ve iki şeye mal oluyordu:\n * FR-014'ün amiral deseni (`{ balance: { gte: amount } }`) `$transaction`\n * İÇİNDE yazılamıyordu — koşullu bir yazmayı plana koyamayan yazar `$query`'ye\n * düşüyordu — ve motor tarafında tip atlandığında aynı nesne SESSİZCE parametre\n * olarak bağlanıyordu.\n *\n * `Ref` fazladan üye ve öyle kalmalı: bir plan filtresi ÖNCEKİ bir işlemin\n * döndürdüğü değere bakabilir, `findMany` bakamaz — plan dışında böyle bir\n * \"önceki işlem\" yok.\n */\ntype TxWhereField<Row, K extends keyof Row> = WhereOpWith<\n Row[K],\n // `Ref` KOLON REFERANSININ YANINDA duruyor, `V`'nin içinde DEĞİL: `V`'ye\n // eklenseydi `TextOps<V>`'nin `V extends string` sorusu HAYIR olur ve\n // `contains`/`startsWith` sessizce kaybolurdu (ölçüldü).\n ColRefOf<Row, Row[K]> | Ref<Row[K]>\n>;\n\nexport type TxWhere<Row, Rels = unknown> = {\n [K in keyof Row]?: TxWhereField<Row, K>;\n} & {\n // Düz op'lardaki `WhereFilter` ile AYNI: dal bir `sqlFragment` de olabilir.\n // İki filtre dilinin bir dalda ayrışması, \"tek dil\" iddiasını tam da bileşim\n // anında boşa çıkarırdı — ve motor plan yolunda da fragment'i derliyor\n // (ölçüldü: `SELECT t.* FROM \"crew\" t WHERE true AND (((a > 1)) AND (…))`).\n OR?: (TxWhere<Row, Rels> | SqlFragment)[];\n AND?: (TxWhere<Row, Rels> | SqlFragment)[];\n NOT?: TxWhere<Row, Rels> | SqlFragment;\n} & HasOnly<Rels>;\n\n/** Options for a plan `select`. */\nexport interface TxSelectOptions {\n /** Cap the rows read. */\n limit?: number;\n /** Take a real `FOR UPDATE` row lock for the rest of the transaction. */\n lock?: \"update\";\n}\n\n/** One table, as the plan sees it. */\nexport interface TxTable<Row, Insert, Rels = unknown> {\n /** Insert one row. Returns a handle — call `.expectOne(err)` to read fields. */\n insert(values: TxInsertShape<Insert>): TxRows<Row>;\n /**\n * Insert many rows in ONE statement. Every row must set the same columns\n * (a row that omits one would silently take the column's default).\n *\n * An empty list writes nothing and sends nothing.\n */\n /**\n * Insert many rows in ONE statement, optionally choosing what a collision does.\n *\n * Without `opts` this is a plain multi-row INSERT and a collision aborts the\n * transaction — the behaviour every call had before the option existed.\n *\n * `action: \"ignore\"` emits `ON CONFLICT DO NOTHING`, which is how \"insert the\n * ones that are new\" becomes one round-trip instead of one per row with a\n * 23505 caught around each. **The returned rows are the ones actually\n * INSERTED**: a row that collided is skipped, so it is absent from the result\n * — Postgres does not return what it did not write.\n *\n * `action: \"update\"` emits `ON CONFLICT DO UPDATE`, setting every non-conflict\n * column from the incoming row, and every row comes back.\n */\n insertMany(\n rows: readonly TxInsertShape<Insert>[],\n opts?: {\n onConflict: readonly Extract<keyof Row, string>[];\n action?: \"ignore\" | \"update\";\n },\n ): TxRows<Row>;\n /**\n * Satırı yaz, `onConflict` kolonlarında çakışırsa üzerine yaz — planın\n * savepoint'i içinde, `Database.<şema>.<tablo>.put()` ile AYNI anlamda.\n *\n * Adı bilerek aynı: aynı iş için transaction içinde ve dışında iki farklı\n * yazım, bu run'ın kapatmak için var olduğu şeydir (P1). TEL şekli\n * (`op: \"upsert\"`) değişmedi — o iç sözleşme, yazarın gördüğü ad değil.\n *\n * Bir operasyon olmasının sebebi: alternatifi burada yazılamaz — başarısız\n * bir insert tüm transaction'ı abort eder, yani \"dene, sonra geri düş\" iki\n * plan adımı olamaz.\n */\n put(\n values: TxInsertShape<Insert>,\n options: { onConflict: readonly Extract<keyof Row, string>[] },\n ): TxRows<Row>;\n /**\n * Update every row matching `where`. The filter comes first because it is the\n * dangerous half: an update whose `where` you got wrong rewrites rows you\n * never looked at. The server refuses an update with no `where` at all.\n */\n updateWhere(where: TxWhere<Row, Rels>, set: TxSetShape<Insert>): TxRows<Row>;\n /** Delete every row matching `where`. The server refuses an unfiltered delete. */\n deleteWhere(where: TxWhere<Row, Rels>): TxRows<Row>;\n /** Read rows, optionally locking them for the rest of the transaction. */\n select(where?: TxWhere<Row, Rels>, options?: TxSelectOptions): TxRows<Row>;\n}\n\n/**\n * The handle a transaction callback receives.\n *\n * It carries tables and nothing else: no `query`, no `findById`, no `asService`.\n * A read whose value the plan does not write belongs OUTSIDE the transaction,\n * where it costs one round trip and can be branched on like an ordinary value.\n */\nexport interface TxPlanHandle<TTables> {\n /**\n * @deprecated `tx.public` kullanın. Bu ad public'in takma adı olarak DURUYOR\n * (göç notu onu öğretiyor ve her mevcut çağrı onu kullanıyor), ama ARTIK\n * ÖĞRETİLMİYOR: doğrudan yüzeyde `Database.tables` FR-001 ile kaldırıldı, ve\n * plan yüzeyinin onu öğretmeye devam etmesi yazarı bir yüzeyde çalışıp\n * diğerinde derlenmeyen bir yazıma alıştırıyordu (gözcü M-6).\n */\n tables: TTables;\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — expressions\n// ---------------------------------------------------------------------------\n\n/** Internal marker read by the serialiser. */\nconst EXPR = Symbol.for(\"palbase.tx.expr\");\nconst REF = Symbol.for(\"palbase.tx.ref\");\nconst ROW = Symbol.for(\"palbase.tx.row\");\nconst ROWS = Symbol.for(\"palbase.tx.rows\");\n\ninterface RefDescriptor {\n op: number;\n field: string;\n}\n\n/** Property reads that must not silently produce a value on a plan handle.\n * `then` is the one that matters for correctness (it makes `await` a compile\n * error AND stops a handle from being adopted by a promise); the rest turn a\n * silent wrong answer — `\"[object Object]\"`, `NaN`, `{}` — into a thrown one. */\nconst TRAPPED_PROPS: readonly (string | symbol)[] = [\n \"then\",\n \"valueOf\",\n \"toString\",\n \"toJSON\",\n Symbol.toPrimitive,\n];\n\nfunction trap(prop: string | symbol, what: string, hint: string): never {\n const name = typeof prop === \"symbol\" ? prop.description ?? String(prop) : prop;\n throw new TxRefError(\n `${what} was used as a value (via \\`${name}\\`). Nothing in a transaction ` +\n `callback has run yet, so there is no value to read. ${hint}`,\n );\n}\n\n/** The server's `now()`. */\nexport function now(): TxNow {\n return makeExpr({ fn: \"now\" }) as TxNow;\n}\n\n/** Add `by` to the column's current value. Only valid in an update's `set`. */\nexport function increment(by: number | string): TxColumnExpr {\n assertAmount(by, \"increment\");\n return makeExpr({ fn: \"inc\", by }) as TxColumnExpr;\n}\n\n/**\n * `increment`'in eski adı. AYNI fabrikadır — iki uygulama değil, iki ad.\n *\n * @deprecated `increment()` kullanın; bu ad geriye dönük uyumluluk için duruyor.\n */\nexport const inc = increment;\n\n/** Subtract `by` from the column's current value. Only valid in an update's `set`. */\nexport function decrement(by: number | string): TxColumnExpr {\n assertAmount(by, \"decrement\");\n return makeExpr({ fn: \"dec\", by }) as TxColumnExpr;\n}\n\n/**\n * `decrement`'in eski adı. AYNI fabrikadır.\n *\n * @deprecated `decrement()` kullanın.\n */\nexport const dec = decrement;\n\n/**\n * Miktarın taşınabilir olduğunu doğrular.\n *\n * String kabul edilir ve KASITLIDIR (D-007): `numeric` bir kolonda miktar JS\n * `number`'a uğrarsa 0.1 + 0.2 orada 0.30000000000000004'tür ve para hesabı\n * sessizce kayar. String hem burada hem `renderValue`'da bound parametre olarak\n * taşınır — Postgres onu tam ondalık olarak okur.\n */\nfunction assertAmount(by: number | string, fn: string): void {\n if (typeof by === \"string\") {\n // Metin SQL'e girmiyor (bound parametre), ama şekli yine de doğrulanır:\n // \"abc\" bind edilirse hata Postgres'ten gelir, çağıranın diliyle değil.\n if (!/^-?\\d+(\\.\\d+)?$/.test(by)) {\n throw new TxPlanError(\n `${fn}() ondalık bir sayı metni bekliyor, \"${by}\" aldı — kabul edilen biçim: \"12\", \"-12\", \"12.50\"`,\n );\n }\n } else if (typeof by !== \"number\" || !Number.isFinite(by)) {\n // JSON has no NaN/Infinity: they would serialise to `null` and the server\n // would reject the plan with an unhelpful decode error.\n throw new TxPlanError(`${fn}() needs a finite number, got ${String(by)}`);\n }\n // NEGATİF MİKTAR REDDEDİLİR — ve bu şekil kontrolünden çok daha fazlası.\n // `decrement(\"-5\")` `SET c = c - $1` derliyordu, `$1 = -5`, yani beş EKLİYORDU.\n // FR-014'ün amiral deseninde (`where: { balance: { gte: amount } }`) miktar\n // istek gövdesinden geliyorsa `balance >= -5` her zaman doğru: hesap\n // KREDİLENDİRİLİR ve çağrı bunu 1 satırla \"başarı\" diye raporlar. Guard\n // okunduğunda işaret kontrol edilmiş gibi duruyordu (gözcü I9, ölçüldü).\n const negative = typeof by === \"string\" ? by.trimStart().startsWith(\"-\") : by < 0;\n if (negative) {\n const other = fn === \"increment\" ? \"decrement\" : \"increment\";\n throw new TxPlanError(\n `${fn}() negatif miktar almaz (\"${String(by)}\"). Ters yön için ${other}() kullanın — ` +\n `işaretin miktarda saklanması, yönü okuyan hiçbir kod tarafından görülmezdi.`,\n );\n }\n}\n\n/**\n * Bir değer `increment()`/`decrement()` ürünü mü? Öyleyse tel şekli.\n *\n * DOĞRUDAN yol (`updateMany`) da bu ifadeyi anlamak zorunda: aynı nesnenin iki\n * yerde çalışması, \"kolona ekle\"nin tek yazımı olmasının şartı (P1).\n */\nexport function columnExprOf(v: unknown): TxWireExpr[\"$expr\"] | null {\n return exprOf(v);\n}\n\nfunction makeExpr(expr: TxWireExpr[\"$expr\"]): unknown {\n return new Proxy(\n { [EXPR]: expr } as Record<string | symbol, unknown>,\n {\n get(target, prop) {\n if (prop === EXPR) return target[EXPR];\n if (TRAPPED_PROPS.includes(prop)) {\n trap(prop, \"A plan expression\", \"Write it into an operation instead.\");\n }\n return undefined;\n },\n },\n );\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — refs and row handles\n// ---------------------------------------------------------------------------\n\nfunction makeRef(op: number, field: string): unknown {\n const target: Record<string | symbol, unknown> = { [REF]: { op, field } satisfies RefDescriptor };\n return new Proxy(target, {\n get(t, prop) {\n if (prop === REF) return t[REF];\n if (TRAPPED_PROPS.includes(prop)) {\n trap(\n prop,\n `\\`${field}\\` of a row this transaction has not written yet`,\n \"Pass it to another operation in the same plan, or return it from the \" +\n \"callback and read it after `transaction()` resolves.\",\n );\n }\n return undefined;\n },\n });\n}\n\nfunction makeRowHandle(op: number): unknown {\n const target: Record<string | symbol, unknown> = { [ROW]: op };\n return new Proxy(target, {\n get(t, prop) {\n if (prop === ROW) return t[ROW];\n if (TRAPPED_PROPS.includes(prop)) {\n trap(\n prop,\n \"A row this transaction has not written yet\",\n \"Read one of its columns to reference it, or return the row from the \" +\n \"callback and read it after `transaction()` resolves.\",\n );\n }\n if (typeof prop === \"symbol\") return undefined;\n return makeRef(op, prop);\n },\n });\n}\n\nfunction refDescriptor(v: unknown): RefDescriptor | null {\n if (typeof v !== \"object\" || v === null) return null;\n const d = (v as Record<symbol, unknown>)[REF];\n return isRefDescriptor(d) ? d : null;\n}\n\nfunction isRefDescriptor(d: unknown): d is RefDescriptor {\n return (\n typeof d === \"object\" &&\n d !== null &&\n typeof (d as RefDescriptor).op === \"number\" &&\n typeof (d as RefDescriptor).field === \"string\"\n );\n}\n\nfunction rowOpIndex(v: unknown): number | null {\n if (typeof v !== \"object\" || v === null) return null;\n const op = (v as Record<symbol, unknown>)[ROW];\n return typeof op === \"number\" ? op : null;\n}\n\nfunction exprOf(v: unknown): TxWireExpr[\"$expr\"] | null {\n if (typeof v !== \"object\" || v === null) return null;\n const e = (v as Record<symbol, unknown>)[EXPR];\n return typeof e === \"object\" && e !== null ? (e as TxWireExpr[\"$expr\"]) : null;\n}\n\nfunction isRowsHandle(v: unknown): boolean {\n return typeof v === \"object\" && v !== null && (v as Record<symbol, unknown>)[ROWS] !== undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — value encoding\n// ---------------------------------------------------------------------------\n\n/**\n * Encode one value of a `values`/`set`/`where` map.\n *\n * The nesting check is not defensive tidiness. The server treats `$ref` as a\n * tagged value only at the TOP of a column's value; a ref buried inside a jsonb\n * payload is just data, and would be stored as the literal object\n * `{\"$ref\":{...}}` — a write that succeeds, commits, and is wrong. So a nested\n * handle is a hard error here, where the line that wrote it is still on the\n * stack.\n */\nfunction encodeValue(value: unknown, column: string, allowColumnExpr: boolean): TxWireValue {\n const ref = refDescriptor(value);\n if (ref) return brandRef({ $ref: { op: ref.op, field: ref.field } }, \"ref\") satisfies TxWireRef;\n\n // `now()` bir KARŞILAŞTIRMA değeri olarak geçer — sunucu saati. Diğer\n // ifadeler (increment/decrement) yazma ifadesidir ve aşağıda adıyla\n // reddediliyor. Düz op yolu ile aynı ayrım, aynı gerekçe.\n if (isNowExpr(value)) return { $expr: { fn: \"now\" } };\n const expr = exprOf(value);\n if (expr) {\n if (expr.fn !== \"now\" && !allowColumnExpr) {\n throw new TxPlanError(\n `\\`${column}\\`: ${expr.fn}() reads the column's current value, so it is ` +\n `only valid in updateWhere(where, set).`,\n );\n }\n return { $expr: expr } satisfies TxWireExpr;\n }\n\n if (rowOpIndex(value) !== null) {\n throw new TxPlanError(\n `\\`${column}\\`: a row handle is not a value. Read the column you meant ` +\n `(e.g. \\`row.id\\`).`,\n );\n }\n if (isRowsHandle(value)) {\n throw new TxPlanError(\n `\\`${column}\\`: an operation result is not a value. Declare an expectation ` +\n `first (\\`.expectOne(err)\\`) and read a column from the row.`,\n );\n }\n\n assertNoNestedHandles(value, column);\n return value;\n}\n\n/**\n * Encode a FİLTRE — `values`/`set` ile AYNI kodlayıcı değil, ve olmaması bir\n * düzeltme.\n *\n * `encodeValue` bir `$ref`'i yalnız kolonun EN ÜSTÜNDE kabul ediyor, çünkü bir\n * insert değerinin İÇİNE gömülü ref sunucuda çözülmez, literal JSON olarak\n * SAKLANIR — \"başarıyla commit olan ve yanlış olan bir yazma\". O kural DEĞER\n * yolu için doğru.\n *\n * FİLTREDE öyle değil: motorun `resolveRefsDeep`'i bir ref'i filtrenin HER\n * yerinde çözüyor — operatörün sağında, `OR`/`AND`/`NOT` dallarının içinde. Ama\n * kodlayıcı hâlâ değer kuralını uyguluyordu, yani üç katman üç farklı cevap\n * veriyordu (gözcü C-2): tip kabul, motor çözüyor, kodlayıcı REDDEDİYOR — ve\n * reddin metni değer-yuvalama vakasını anlatıyor, filtrede olmayan bir şeyi.\n *\n * İFADE TUTAMAĞI ve SATIR TUTAMAĞI filtrede HÂLÂ reddediliyor: onları motor\n * filtrede çözmüyor ve çözmemeli — `increment()` bir yazma ifadesi, bir\n * karşılaştırma değil.\n */\nfunction encodeFilterValue(value: unknown, column: string): unknown {\n const ref = refDescriptor(value);\n if (ref) return brandRef({ $ref: { op: ref.op, field: ref.field } }, \"ref\") satisfies TxWireRef;\n\n const expr = exprOf(value);\n if (expr) {\n throw new TxPlanError(\n `\\`${column}\\`: ${expr.fn}() bir YAZMA ifadesi, karşılaştırma değil — ` +\n `filtrede kullanılamaz. Kolonu bir değerle ya da col() ile karşılaştırın.`,\n );\n }\n if (rowOpIndex(value) !== null) {\n throw new TxPlanError(\n `\\`${column}\\`: a row handle is not a value. Read the column you meant (e.g. \\`row.id\\`).`,\n );\n }\n if (isRowsHandle(value)) {\n throw new TxPlanError(\n `\\`${column}\\`: an operation result is not a value. Declare an expectation ` +\n `first (\\`.expectOne(err)\\`) and read a column from the row.`,\n );\n }\n if (Array.isArray(value)) return value.map((v) => encodeFilterValue(v, column));\n // `col()` ve `sqlFragment` OLDUĞU GİBİ geçer: markaları süreç içinde korunur\n // ve derleyici ikisini de kendi tanıyor.\n if (value !== null && typeof value === \"object\" && !(value instanceof Date) && !isColRef(value) && !isSqlFragment(value)) {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n out[k] = encodeFilterValue(v, column);\n }\n return out;\n }\n return value;\n}\n\n/** Filtre haritası — anahtarlar SIRALI (aynı geri çağrı bayt-özdeş JSON üretsin). */\nfunction encodeFilterMap(map: Record<string, unknown>): Record<string, TxWireValue> {\n const out: Record<string, TxWireValue> = {};\n for (const key of Object.keys(map).sort()) {\n const value = map[key];\n if (value === undefined) continue;\n out[key] = encodeFilterValue(value, key) as TxWireValue;\n }\n return out;\n}\n\nfunction assertNoNestedHandles(value: unknown, column: string): void {\n if (typeof value !== \"object\" || value === null) return;\n if (value instanceof Date) return;\n if (refDescriptor(value) || exprOf(value) || rowOpIndex(value) !== null || isRowsHandle(value)) {\n throw new TxPlanError(\n `\\`${column}\\`: a plan handle is nested inside a value. The server would ` +\n `store it as literal JSON, not resolve it. Put the reference directly in ` +\n `the column.`,\n );\n }\n if (Array.isArray(value)) {\n for (const item of value) assertNoNestedHandles(item, column);\n return;\n }\n for (const item of Object.values(value as Record<string, unknown>)) {\n assertNoNestedHandles(item, column);\n }\n}\n\n/**\n * Encode a column map, dropping `undefined` and emitting keys SORTED.\n *\n * Sorting is what makes the same callback produce byte-identical JSON every\n * time, which is what lets the Go decoder be locked to goldens this SDK emits.\n * Dropping `undefined` mirrors what `JSON.stringify` would do anyway, but does\n * it where the resulting column list is still checkable.\n */\nfunction encodeMap(\n map: Record<string, unknown>,\n allowColumnExpr: boolean,\n): Record<string, TxWireValue> {\n const out: Record<string, TxWireValue> = {};\n for (const key of Object.keys(map).sort()) {\n const value = map[key];\n // AÇIK `undefined` REDDEDİLİR (D-017 kapandı).\n //\n // \"Kolon varsayılanını al\" demenin yolu anahtarı HİÇ KOYMAMAK; bu döngü\n // zaten yalnız var olan anahtarları geziyor, yani o niyet bozulmadan\n // çalışıyor. Ayırt edilen şey başka: anahtarın DURDUĞU ama değerinin\n // `undefined` olduğu hâl — yani `{ title: req.body.title }` gövdede\n // `title` yokken. O ölçülmüş bir olaydı: kolon sessizce yazılmadı ve\n // istek 200 döndü.\n //\n // Doğrudan yol bunu baştan beri adıyla reddediyordu; plan yolu sessizce\n // düşürüyordu. Aynı girdiye zıt iki cevap, \"tek filtre dili, tek cevap\"\n // iddiasını yazma tarafında boşa çıkarıyordu.\n if (value === undefined) {\n throw new TxPlanError(\n `${key} değeri undefined — bu bir yazma değeri değil. Anahtar duruyor ` +\n `ama değeri yok, yani kolon sessizce YAZILMAZDI (istek gövdesinden ` +\n `gelen bir alanın eksik olması bu şekilde görünür). Kolon ` +\n `varsayılanını istiyorsanız anahtarı hiç koymayın; NULL yazmak ` +\n `istiyorsanız açıkça null yazın.`,\n );\n }\n out[key] = encodeValue(value, key, allowColumnExpr);\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — the builder\n// ---------------------------------------------------------------------------\n\n/** How many rows an op can produce, as far as the CLIENT can tell before it\n * runs. Only the empty `insertMany` is knowable, and knowing it is what lets a\n * doomed expectation fail on the line that declared it. */\nconst SKIPPED_OP = -1;\n\nclass TxRowsImpl<Row> implements TxRows<Row> {\n // Present so `isRowsHandle` recognises the object; never read for its value.\n readonly [ROWS] = true;\n // Phantom: the type brand that stops a bare object passing as a TxRows. Never\n // present at run time, which is what `declare` says.\n declare readonly [rowsBrand]: Row;\n private guarded = false;\n\n constructor(\n private readonly builder: TxPlanBuilder,\n private readonly opIndex: number,\n private readonly what: string,\n ) {}\n\n // The type-level `await` guard made real: TS rejects `await rows` at compile\n // time, and reaching this means someone called `.then(...)` by hand.\n then(): never {\n throw new TxRefError(\n `${this.what} cannot be awaited: a transaction callback builds a plan, it ` +\n `does not run statements. Remove the \\`await\\`.`,\n );\n }\n\n expectOne(error: Error): TxRow<Row> {\n this.declareGuard(\"one\", 1, error);\n if (this.opIndex === SKIPPED_OP) throw error;\n return makeRowHandle(this.opIndex) as TxRow<Row>;\n }\n\n expectNone(error: Error): void {\n this.declareGuard(\"none\", 0, error);\n }\n\n expectAtLeast(n: number, error: Error): void {\n assertGuardCount(n, \"expectAtLeast\");\n this.declareGuard(\"atLeast\", n, error);\n if (this.opIndex === SKIPPED_OP && n > 0) throw error;\n }\n\n expectAtMost(n: number, error: Error): void {\n assertGuardCount(n, \"expectAtMost\");\n this.declareGuard(\"atMost\", n, error);\n }\n\n private declareGuard(kind: TxWireGuard[\"kind\"], n: number, error: Error): void {\n if (!(error instanceof Error)) {\n // The error object is the ONLY thing that describes this failure to the\n // caller — the server sends back an index, never a message.\n throw new TxPlanError(\n `${this.what}: an expectation needs the Error to throw when it does not ` +\n `hold (e.g. \\`.expect…(new Conflict(\"already accepted\"))\\`).`,\n );\n }\n if (this.guarded) {\n throw new TxPlanError(\n `${this.what} already has an expectation. One operation carries one ` +\n `expectation; declare the second one on its own operation.`,\n );\n }\n this.guarded = true;\n if (this.opIndex === SKIPPED_OP) return;\n this.builder.attachGuard(this.opIndex, kind, n, error);\n }\n}\n\nfunction assertGuardCount(n: number, fn: string): void {\n if (!Number.isInteger(n) || n < 0) {\n throw new TxPlanError(`${fn}(n) needs a non-negative integer, got ${String(n)}`);\n }\n}\n\n/** Bounds mirrored from the plan executor so an over-sized plan is named here rather\n * than rejected as an opaque 400 after it has crossed the network. */\nconst MAX_OPS = 1000;\nconst MAX_ROWS = 5000;\n\n/**\n * Accumulates ops and the client-side error table while the callback runs.\n *\n * Exported for the runtime and for tests that need the serialised plan without\n * a server; author code never sees it.\n */\nexport class TxPlanBuilder {\n private readonly ops: TxWireOp[] = [];\n /** Errors handed to expectations, indexed by the `slot` the server echoes. */\n private readonly slots: Error[] = [];\n\n /** The table surface handed to the callback. Untyped here; the public\n * `transaction()` signatures put the schema types on top. */\n table(name: string): TxTable<Record<string, unknown>, Record<string, unknown>> {\n return {\n insert: (values) => {\n const encoded = encodeMap(values as Record<string, unknown>, false);\n if (Object.keys(encoded).length === 0) {\n throw new TxPlanError(`${name}.insert() needs at least one column`);\n }\n return this.push({ op: \"insert\", table: name, values: encoded }, `${name}.insert()`);\n },\n\n put: (values, options) => {\n const encoded = encodeMap(values as Record<string, unknown>, false);\n if (Object.keys(encoded).length === 0) {\n throw new TxPlanError(`${name}.put() needs at least one column`);\n }\n if (options.onConflict.length === 0) {\n throw new TxPlanError(`${name}.put() needs at least one onConflict column`);\n }\n return this.push(\n { op: \"upsert\", table: name, values: encoded, onConflict: options.onConflict },\n `${name}.upsert()`,\n );\n },\n\n insertMany: (rows, opts) => {\n if (rows.length === 0) {\n // Nothing to write. Emitting an op would be a guaranteed 400 (the\n // server requires rows), and refusing outright would punish the\n // ordinary \"filtered every candidate out\" case.\n return new TxRowsImpl(this, SKIPPED_OP, `${name}.insertMany()`);\n }\n if (rows.length > MAX_ROWS) {\n throw new TxPlanError(\n `${name}.insertMany() has ${rows.length} rows; the limit is ${MAX_ROWS}. ` +\n `Split the write across requests.`,\n );\n }\n const encoded = rows.map((row) => encodeMap(row as Record<string, unknown>, false));\n assertUniformRows(encoded, name);\n if (opts !== undefined && opts.onConflict.length === 0) {\n throw new TxPlanError(\n `${name}.insertMany() was given a conflict action with no onConflict ` +\n `columns. Postgres matches a collision on columns, so name them.`,\n );\n }\n return this.push(\n {\n op: \"insertMany\",\n table: name,\n rows: encoded,\n // Omitted entirely when no options were given, so the op a plain\n // insertMany produces is byte-identical to the one it produced\n // before this option existed.\n ...(opts !== undefined\n ? { onConflict: opts.onConflict, action: opts.action ?? \"ignore\" }\n : {}),\n },\n `${name}.insertMany()`,\n );\n },\n\n updateWhere: (where, set) => {\n const encodedWhere = encodeFilterMap(where as Record<string, unknown>);\n const encodedSet = encodeMap(set as Record<string, unknown>, true);\n if (Object.keys(encodedWhere).length === 0) {\n throw new TxPlanError(\n `${name}.updateWhere() needs a filter. An update with no filter ` +\n `rewrites the whole table.`,\n );\n }\n if (Object.keys(encodedSet).length === 0) {\n throw new TxPlanError(`${name}.updateWhere() needs at least one column to set`);\n }\n return this.push(\n { op: \"update\", table: name, set: encodedSet, where: encodedWhere },\n `${name}.updateWhere()`,\n );\n },\n\n deleteWhere: (where) => {\n const encodedWhere = encodeFilterMap(where as Record<string, unknown>);\n if (Object.keys(encodedWhere).length === 0) {\n throw new TxPlanError(\n `${name}.deleteWhere() needs a filter. A delete with no filter empties ` +\n `the table.`,\n );\n }\n return this.push(\n { op: \"delete\", table: name, where: encodedWhere },\n `${name}.deleteWhere()`,\n );\n },\n\n select: (where, options) => {\n const op: TxWireOp = { op: \"select\", table: name };\n const encodedWhere = encodeFilterMap((where ?? {}) as Record<string, unknown>);\n if (Object.keys(encodedWhere).length > 0) op.where = encodedWhere;\n if (options?.limit !== undefined) {\n if (!Number.isInteger(options.limit) || options.limit < 0) {\n throw new TxPlanError(\n `${name}.select(): limit needs a non-negative integer, got ${String(options.limit)}`,\n );\n }\n op.limit = options.limit;\n }\n if (options?.lock !== undefined) op.lock = options.lock;\n return this.push(op, `${name}.select()`);\n },\n };\n }\n\n private push(op: TxWireOp, what: string): TxRows<Record<string, unknown>> {\n if (this.ops.length >= MAX_OPS) {\n throw new TxPlanError(\n `this transaction has ${MAX_OPS} operations, which is the limit. Use ` +\n `insertMany() for bulk writes, or split the work across requests.`,\n );\n }\n const index = this.ops.length;\n this.ops.push(op);\n return new TxRowsImpl(this, index, what);\n }\n\n /** Attach an expectation to an op and record its error in the slot table. */\n attachGuard(opIndex: number, kind: TxWireGuard[\"kind\"], n: number, error: Error): void {\n const op = this.ops[opIndex];\n // Unreachable: the index came from `push`. A loud failure beats a silently\n // unguarded write if that ever stops being true.\n if (!op) throw new TxPlanError(`internal: expectation on unknown operation ${opIndex}`);\n const slot = this.slots.length;\n this.slots.push(error);\n op.guard = { kind, n, slot };\n }\n\n /** The serialisable plan. Empty when the callback described no writes. */\n body(): TxPlanBody {\n return { ops: this.ops };\n }\n\n /** The error the server's `slot` selects, or `null` when it names one this\n * plan never declared (a server/client disagreement, not a tenant error). */\n errorForSlot(slot: number): Error | null {\n return this.slots[slot] ?? null;\n }\n}\n\nfunction assertUniformRows(rows: Record<string, TxWireValue>[], table: string): void {\n const first = rows[0];\n if (!first) return;\n const want = Object.keys(first);\n const wantKey = want.join(\",\");\n for (let i = 1; i < rows.length; i++) {\n const got = Object.keys(rows[i] as Record<string, TxWireValue>);\n if (got.join(\",\") !== wantKey) {\n // One statement, one column list. A ragged row would take the DB default\n // for the column it omitted — a write that succeeds and is wrong.\n throw new TxPlanError(\n `${table}.insertMany(): every row must set the same columns. Row 0 sets ` +\n `[${want.join(\", \")}] but row ${i} sets [${got.join(\", \")}]. ` +\n `(A property set to \\`undefined\\` counts as absent — use \\`null\\`.)`,\n );\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — materialisation\n// ---------------------------------------------------------------------------\n\n/**\n * Replace every handle in the callback's return value with what the server\n * actually produced.\n *\n * Walks arrays and PLAIN objects only. Class instances (a Date, a Zod schema, a\n * domain object) are returned untouched — recursing into them would rebuild them\n * as bare objects, and nothing inside one can be a handle that this SDK created.\n */\nexport function materializeResult(value: unknown, results: TxPlanOpResult[]): unknown {\n const ref = refDescriptor(value);\n if (ref) {\n const row = rowOf(results, ref.op, `\\`${ref.field}\\``);\n if (!(ref.field in row)) {\n throw new TxPlanError(\n `the transaction's operation ${ref.op} returned no column \\`${ref.field}\\`.`,\n );\n }\n return row[ref.field];\n }\n\n const rowOp = rowOpIndex(value);\n if (rowOp !== null) return rowOf(results, rowOp, \"a row\");\n\n if (isRowsHandle(value)) {\n throw new TxPlanError(\n \"an operation result cannot be returned from a transaction callback: its \" +\n \"row count is not known until the plan runs. Declare an expectation \" +\n \"(`.expectOne(err)`) and return the row, or a column of it.\",\n );\n }\n\n if (Array.isArray(value)) return value.map((item) => materializeResult(item, results));\n\n if (isPlainObject(value)) {\n const out: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(value)) out[key] = materializeResult(item, results);\n return out;\n }\n\n return value;\n}\n\nfunction rowOf(results: TxPlanOpResult[], opIndex: number, what: string): Record<string, unknown> {\n const result = results[opIndex];\n if (!result) {\n throw new TxPlanError(\n `the transaction returned no result for operation ${opIndex}, so ${what} ` +\n `cannot be read.`,\n );\n }\n const row = result.rows[0];\n if (!row) {\n // Unreachable through the public API: a handle only exists behind an\n // `expectOne`, and the server rolls back rather than answering 200 with a\n // guard unmet. Loud, because the alternative is `undefined` in tenant data.\n throw new TxPlanError(\n `the transaction's operation ${opIndex} returned no row, so ${what} cannot ` +\n `be read.`,\n );\n }\n return row;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== \"object\" || value === null) return false;\n const proto: unknown = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — the driver\n// ---------------------------------------------------------------------------\n\n/** What {@link runTxPlan} needs from the runtime: one call, one transaction. */\nexport interface TxPlanTransport {\n txPlan(plan: TxPlanBody): Promise<TxPlanResponse>;\n}\n\n/**\n * Build the plan, send it, and resolve the callback's return value.\n *\n * A callback that throws never reaches the network: there is nothing to roll\n * back because nothing was sent. A callback that describes no writes also skips\n * the round trip entirely.\n *\n * The RETURN type is `unknown` here on purpose. `Materialized<T>` is a compile-\n * time rewrite of the callback's return type, and it belongs on the public\n * `transaction()` signatures where `T` is inferred from the author's callback;\n * threading it through this driver as well would mean inferring `T` twice, from\n * two different positions, and reconciling them. The public wrappers narrow\n * once, at the seam where the value types were erased anyway.\n */\nexport async function runTxPlan<THandle>(\n transport: TxPlanTransport,\n // TUTAMAĞIN TAMAMI, yalnız `tables` DEĞİL. Tutamak artık şema yüzeyini de\n // taşıyor (`tx.public.x`, `tx.<şema>.x`), ve onu BURADA `{ tables }` diye\n // yeniden kurmak o yüzeyi sessizce düşürürdü.\n handle: THandle,\n builder: TxPlanBuilder,\n fn: (tx: THandle) => unknown,\n): Promise<unknown> {\n const returned = fn(handle);\n const body = builder.body();\n if (body.ops.length === 0) {\n return materializeResult(returned, []);\n }\n\n let response: TxPlanResponse;\n try {\n response = await transport.txPlan(body);\n } catch (err) {\n throw translateRejection(err, builder);\n }\n return materializeResult(returned, response.results);\n}\n\n/**\n * Turn the broker's rejection back into the tenant's own error.\n *\n * The server never sees the `Error` an expectation was given — only its slot\n * index — so this is the only place the intended error can be produced. A\n * rejection this SDK does not recognise passes through untouched: inventing an\n * error for it would hide the real failure.\n */\nfunction translateRejection(err: unknown, builder: TxPlanBuilder): unknown {\n if (typeof err !== \"object\" || err === null) return err;\n const rejection = err as TxPlanRejection;\n if (rejection.error_code !== \"tx_guard_failed\" || typeof rejection.slot !== \"number\") {\n return err;\n }\n return builder.errorForSlot(rejection.slot) ?? err;\n}\n","// The wire shape of a declared schema — what the deploy reads.\n//\n// `defineSchema(...)` produces a value full of builders and phantom types, which\n// is the right shape for authoring and the wrong shape for anything outside this\n// process. The deploy is Go: it introspects the live database, diffs it against\n// the declaration, and applies the difference. So the declaration has to leave\n// TypeScript as data, and this file is where that happens.\n//\n// It lives in the SDK because the SDK owns the DSL. The alternative — a script\n// beside the deploy that reaches into `._def` — is a second reading of a private\n// shape, and it drifts the moment a column gains a property: the DSL keeps\n// working, the emitter silently omits it, and the database is missing something\n// nobody can see in the source.\n//\n// The field names below are a CONTRACT with Go's `schema.SchemaJSON`. Renaming\n// one here without renaming it there produces a declaration that parses to\n// something emptier than it was — the failure mode being a column, a policy, or\n// a whole table that quietly never gets created.\n// Politika ifadesinin tel şekli `policy.ts`'te TEK kez bildiriliyor. İki kopya\n// olsaydı biri `exists` düğümünü alır, diğeri almaz ve fark ancak Go tarafı\n// bilmediği bir `kind` gördüğünde ortaya çıkardı.\nimport type { PolicyExpr as PolicyExprJSON } from \"./policy.js\";\nexport type { PolicyExpr as PolicyExprJSON } from \"./policy.js\";\nimport type { ColumnBuilder, ColumnDef } from \"./columns.js\";\nimport type { PolicyDef } from \"./policy.js\";\nimport type { MemoryDecl, SchemaDef, SearchDecl, TableDef } from \"./schema.js\";\n\n/** One column, flattened. Mirrors Go's `schema.ColumnJSON`. */\nexport interface ColumnJSON {\n type: string;\n nullable: boolean;\n primaryKey: boolean;\n defaultValue?: unknown;\n defaultRandom?: boolean;\n defaultNow?: boolean;\n renamedFrom?: string;\n /** See Go's `schema.ColumnJSON.Ignored` — the contraction gate's only signal. */\n ignored?: boolean;\n owns?: boolean;\n references?: { table: string; column: string };\n onDeleteAction?: string;\n /** FR-044: türev FK index'i kapatılmışsa `false`. Bildirilmemişse alan YOK. */\n index?: boolean;\n /** FR-049: kolon increment() ile güncelleniyorsa `true`. Aksi hâlde alan YOK. */\n counter?: boolean;\n enumName?: string;\n enumValues?: string[];\n unique?: boolean;\n dimensions?: number;\n}\n\n/** One RLS policy. Mirrors Go's `schema.PolicyJSON`. */\nexport interface PolicyJSON {\n name: string;\n command: string;\n roles: string[];\n /**\n * `USING (...)` — ham string (kaçış kapağı, FR-028) ya da YAPI (FR-022).\n *\n * Go tarafı ikisini de okur: string olan verbatim emit edilir, yapı olan\n * `generator.go`'da SQL'e çevrilir (C-6). Yapı hâli InitPlan sarmalamasını\n * ve `TO <rol>` daraltmasını GÜVENLE yapılabilir kılan şey — string üstünde\n * regex'le denemek yorum içindeki bir `auth.uid()`'yi de sarmalardı.\n */\n using: string | PolicyExprJSON | null;\n withCheck: string | PolicyExprJSON | null;\n permissive: boolean;\n}\n\n\n/** One table. Mirrors Go's `schema.TableJSON`. */\nexport interface TableJSON {\n /**\n * The schema this table lives in. `public` unless declared otherwise.\n *\n * The table carries it because the diff iterates over KEYS but passes the\n * VALUE around: a bare name inside a qualified key space writes the migration\n * into the wrong schema, silently.\n */\n schema: string;\n name: string;\n columns: Record<string, ColumnJSON>;\n rls: boolean;\n policies: PolicyJSON[];\n primaryKey?: string[];\n uniqueConstraints?: { name: string; columns: string[] }[];\n rawConstraints?: { name: string; up: string; down: string | null }[];\n checks?: { name: string; expr: string }[];\n indexes?: IndexJSON[];\n /**\n * appendOnly (FR-030): tablo yalnız INSERT kabul eder. Sıfır değerde OMIT —\n * bildirmeyen tablolar wire'da bayt-aynı kalır.\n */\n appendOnly?: boolean;\n search?: SearchJSON;\n memory?: MemoryJSON;\n}\n\n/**\n * Bir index'in wire şekli — Go'nun `IndexJSON`'ıyla ALAN-ADI SÖZLEŞMESİ.\n *\n * `name` + `columns` bugünkü hâl; kalanı FR-041…043'ün taşıyıcısı. Hepsi sıfır\n * değerde OMIT edilir: bildirmeyen bir index wire'da eskisiyle bayt-aynı kalır,\n * yoksa dokunulmamış her şema diff'te değişmiş görünür ve her deploy churn üretir.\n */\nexport interface IndexJSON {\n name: string;\n columns: string[];\n /** Partial index koşulu (FR-042) — filtre şekli `WhereFilter` ile aynı. */\n where?: unknown;\n /** İfade index'i (FR-043), ör. `lower(email)`. `columns` ile birlikte kullanılmaz. */\n expression?: string;\n /** Kolon sırası (FR-043). */\n sort?: \"asc\" | \"desc\";\n /** NULL sırası (FR-043). */\n nulls?: \"first\" | \"last\";\n /** Covering index — `INCLUDE (...)` (FR-043). */\n include?: string[];\n}\n\n/** C-11 wire şekli — Go'nun MemoryJSON'ıyla alan-adı sözleşmesi (D-019).\n * Beyansız tablolarda alan OMIT — eski şemalar bayt-aynı (NFR-B1). */\nexport interface MemoryJSON {\n from: string[];\n into: string;\n subject?: string;\n extract: { provider: string; model: string };\n}\n\n/** A whole declaration. Mirrors Go's `schema.SchemaJSON`. */\nexport interface SchemaJSON {\n tables: Record<string, TableJSON>;\n extensions: string[];\n /**\n * Every declared schema, with its HTTP reachability.\n *\n * The flag has nowhere else to live: `/v1/db` must know which schemas are\n * reachable, and introspection must know which schemas the project DECLARED —\n * a live database also contains internal module schemas that are none of the\n * diff's business.\n */\n schemas: SchemaMetaJSON[];\n}\n\nexport interface SchemaMetaJSON {\n name: string;\n exposed: boolean;\n}\n\n/** The definition behind a column, whichever side of the builder it arrives on. */\nfunction defOf(column: ColumnBuilder | ColumnDef): ColumnDef {\n return \"_def\" in column ? column._def : column;\n}\n\nfunction columnToJSON(column: ColumnBuilder | ColumnDef): ColumnJSON {\n const def = defOf(column);\n const out: ColumnJSON = {\n type: def.type,\n nullable: def.nullable,\n primaryKey: def.primaryKey,\n };\n // Every optional field is omitted rather than emitted as undefined: Go\n // distinguishes \"absent\" from \"present and empty\" on several of these, and a\n // `defaultValue: null` is a real default that says NULL.\n if (def.defaultValue !== undefined) out.defaultValue = def.defaultValue;\n if (def.defaultRandom === true) out.defaultRandom = true;\n if (def.defaultNow === true) out.defaultNow = true;\n if (def.renamedFrom !== undefined) out.renamedFrom = def.renamedFrom;\n // Go'daki schema.ColumnJSON'un aynası. `omitempty` karşılığı: yalnız TRUE ise yazılır,\n // böylece işaretsiz bir şemanın JSON'u bu alandan önceki hâliyle byte-eş kalır.\n if (def.ignored === true) out.ignored = true;\n // OWNERSHIP HAS TO CROSS THE WIRE, because the gate that enforces it is on the\n // other side. `ownedByUser()` sets `owns` on the column, and Go's\n // `validateOwnership` reads `ColumnJSON.Owns` to refuse a table that declares\n // two owners — but nothing was carrying the flag between them.\n //\n // Measured on the live cluster: a table with TWO `ownedByUser()` columns\n // pushed clean and both foreign keys landed on `auth.users` ON DELETE CASCADE.\n // The rule existed in the DSL and in the generator; the wire in between said\n // nothing, so the generator saw ZERO ownership columns and had nothing to\n // refuse. A flag with a reader and no writer is a dead wire.\n if (def.owns === true) out.owns = true;\n if (def.references !== undefined) {\n out.references = { table: def.references.table, column: def.references.column };\n }\n if (def.onDeleteAction !== undefined) out.onDeleteAction = def.onDeleteAction;\n // Yalnız `false` taşınıyor: \"bildirilmedi\" ile \"açık\" aynı şey ve wire'a\n // yazmak bildirmeyen her kolonu diff'te değişmiş gösterirdi.\n if (def.index === false) out.index = false;\n if (def.counter === true) out.counter = true;\n if (def.enumName !== undefined) out.enumName = def.enumName;\n if (def.enumValues !== undefined) out.enumValues = [...def.enumValues];\n if (def.unique === true) out.unique = true;\n if (def.dimensions !== undefined) out.dimensions = def.dimensions;\n return out;\n}\n\nfunction policyToJSON(policy: PolicyDef): PolicyJSON {\n return {\n name: policy.name,\n command: policy.command ?? \"all\",\n roles: policy.roles ? [...policy.roles] : [],\n // null rather than omitted: a policy with no USING clause is a different\n // thing from one whose clause the emitter forgot, and Go reads the\n // difference.\n using: policy.using ?? null,\n withCheck: policy.withCheck ?? null,\n permissive: policy.permissive !== false,\n };\n}\n\n/** C-4 wire şekli — Go'nun SearchJSON'ıyla ALAN ADI sözleşmesi (C-5).\n * `mode`/`chunks` yalnız yeni-biçim chunk-modunda emit edilir (D-010);\n * satır-modu ve eski biçim bayt-aynı kalır (NFR-B1). */\nexport interface SearchJSON {\n text?: { columns: string[] };\n vector?: {\n column?: string;\n metric: string;\n embed?: { provider: string; model: string; from: string[]; apiKeyName?: string; dimensions?: number; baseURL?: string };\n staleness?: \"null\" | \"keep\";\n mode?: \"row\" | \"chunks\";\n chunks?: { sizeChars?: number; overlapChars?: number };\n }[];\n /** FR-026: sorgu-yeniden-yazımı haritası — beyan yoksa OMIT (NFR-B1). */\n synonyms?: Record<string, string[]>;\n /** C-1: sonuç yeniden-sıralama beyanı — beyan yoksa OMIT. */\n /** FR-029: geçerlilik türevleri — beyan yoksa OMIT. */\n validity?: boolean;\n}\n\n/** T020 (C-1): iki biçimin de üst-düzey ortak alanları — beyan yoksa OMIT,\n * boş synonyms haritası da OMIT (NFR-B1 baytları kımıldamaz). */\nfunction commonSearchFields(search: SearchDecl, out: SearchJSON): void {\n if (search.synonyms !== undefined && Object.keys(search.synonyms).length > 0) {\n out.synonyms = Object.fromEntries(\n Object.entries(search.synonyms).map(([word, alts]) => [word, [...alts]]),\n );\n }\n if (search.validity === true) out.validity = true;\n}\n\n/** Beyanı normalize eder: vector her zaman DİZİ, metric her zaman dolu (vars. cosine),\n * authoring'deki `from`/`model` wire'da `embed` altında toplanır. Alan yoksa OMIT —\n * search'süz şema bayt-aynı kalır (NFR-006). */\nfunction searchToJSON(search: SearchDecl, vectorColumn: string | undefined): SearchJSON {\n if (search.from !== undefined && search.model !== undefined) {\n // YENİ biçim (D-007): from tek listedir — FTS'i de embed'i de besler.\n // Mod ŞEMADAN türer (D-010): tabloda vector kolonu varsa satır-modu\n // (column yazılır, mode OMIT — eski davranışla aynı wire), yoksa\n // chunk-modu (mode:\"chunks\", column yok — vektörler türev tabloda).\n const out: SearchJSON = {};\n const textCols =\n search.text === false ? undefined : Array.isArray(search.text) && search.text.length > 0 ? search.text : search.from;\n if (textCols !== undefined) out.text = { columns: [...textCols] };\n const v: NonNullable<SearchJSON[\"vector\"]>[number] = { metric: search.metric ?? \"cosine\" };\n if (vectorColumn !== undefined) v.column = vectorColumn;\n v.embed = {\n provider: search.model.provider,\n model: search.model.model,\n from: [...search.from],\n ...(search.model.apiKeyName !== undefined ? { apiKeyName: search.model.apiKeyName } : {}),\n ...(search.model.dimensions !== undefined ? { dimensions: search.model.dimensions } : {}),\n ...(search.model.baseURL !== undefined ? { baseURL: search.model.baseURL } : {}),\n };\n if (search.staleness !== undefined) v.staleness = search.staleness;\n if (vectorColumn === undefined) {\n v.mode = \"chunks\";\n if (search.chunks !== undefined) {\n const c: NonNullable<typeof v.chunks> = {};\n if (search.chunks.size !== undefined && search.chunks.size > 0) c.sizeChars = search.chunks.size;\n if (search.chunks.overlap !== undefined && search.chunks.overlap > 0) c.overlapChars = search.chunks.overlap;\n if (Object.keys(c).length > 0) v.chunks = c;\n }\n }\n out.vector = [v];\n commonSearchFields(search, out);\n return out;\n }\n const out: SearchJSON = {};\n // Eski biçimde text yalnız dizi olabilir (boolean'ı defineSchema zaten\n // reddediyor); Array.isArray hem tipi daraltır hem o sözleşmeyi belgeler.\n if (Array.isArray(search.text) && search.text.length > 0) out.text = { columns: [...search.text] };\n const legs = search.vector === undefined ? []\n : Array.isArray(search.vector) ? search.vector : [search.vector];\n if (legs.length > 0) {\n out.vector = legs.map((leg) => {\n const v: NonNullable<SearchJSON[\"vector\"]>[number] = { metric: leg.metric ?? \"cosine\" };\n if (leg.column !== undefined) v.column = leg.column;\n if (leg.staleness !== undefined) v.staleness = leg.staleness;\n if (leg.model !== undefined) {\n v.embed = {\n provider: leg.model.provider,\n model: leg.model.model,\n from: [...(leg.from ?? [])],\n ...(leg.model.apiKeyName !== undefined ? { apiKeyName: leg.model.apiKeyName } : {}),\n ...(leg.model.dimensions !== undefined ? { dimensions: leg.model.dimensions } : {}),\n ...(leg.model.baseURL !== undefined ? { baseURL: leg.model.baseURL } : {}),\n };\n }\n return v;\n });\n }\n commonSearchFields(search, out);\n return out;\n}\n\nfunction memoryToJSON(m: MemoryDecl): MemoryJSON {\n return {\n from: [...m.from],\n into: m.into,\n ...(m.subject !== undefined ? { subject: m.subject } : {}),\n extract: { provider: m.extract.provider, model: m.extract.model },\n };\n}\n\nfunction tableToJSON(table: TableDef, schemaName: string): TableJSON {\n const columns: Record<string, ColumnJSON> = {};\n for (const [name, column] of Object.entries(table.columns)) {\n columns[name] = columnToJSON(column);\n }\n\n const out: TableJSON = {\n name: table.name,\n schema: schemaName,\n columns,\n // Read, not re-derived. `defineSchema` already resolves the fail-closed\n // default (RLS on unless the author wrote `rls: false`, and forced on by any\n // policy), and a second copy of a SECURITY default is exactly the thing that\n // drifts — the direction it drifted last time was \"expose everything\", and\n // the live proof was one user reading another's rows.\n rls: table.rls,\n // KOŞAN SÜRÜMÜN SÖZÜ TELE ÇIKAR — yoksa daralma kapısı onu göremez.\n // `ColumnJSON.ignored` ile aynı sözleşme: işaretlenmemişse alan YOK.\n ...(table.ignored === true ? { ignored: true } : {}),\n policies: (table.policies ?? []).map(policyToJSON),\n };\n\n if (table.primaryKey !== undefined && table.primaryKey.length > 0) {\n out.primaryKey = [...table.primaryKey];\n }\n if (table.unique !== undefined && table.unique.length > 0) {\n out.uniqueConstraints = table.unique.map((u) => ({ name: u.name, columns: [...u.columns] }));\n }\n if (table.raw !== undefined && table.raw.length > 0) {\n out.rawConstraints = table.raw.map((r) => ({\n name: r.name,\n up: r.up,\n down: r.down ?? null,\n }));\n }\n if (table.checks !== undefined && table.checks.length > 0) {\n out.checks = table.checks.map((c) => ({ name: c.name, expr: c.expr }));\n }\n if (table.indexes !== undefined && table.indexes.length > 0) {\n out.indexes = table.indexes.map((i) => {\n // `columns` expression-index'te YOKTUR (ikisi birbirinin alternatifi).\n // Boş dizi ile taşınır: Go tarafı `expression` doluysa onu kullanır.\n const ix: IndexJSON = { name: i.name, columns: i.columns ? [...i.columns] : [] };\n if (i.where !== undefined) ix.where = i.where;\n if (i.expression !== undefined) ix.expression = i.expression;\n if (i.sort !== undefined) ix.sort = i.sort;\n if (i.nulls !== undefined) ix.nulls = i.nulls;\n if (i.include !== undefined) ix.include = [...i.include];\n return ix;\n });\n }\n // Sıfır değerde YAZILMAZ: `appendOnly: false` ile \"bildirilmemiş\" wire'da\n // ayırt edilemez olmalı, yoksa her eski şema diff'te değişmiş görünür.\n if (table.appendOnly === true) out.appendOnly = true;\n if (table.search !== undefined) {\n // D-010 mod kararının tek girdisi: tabloda dimensions'lı (vector) kolon\n // adı. Birden çoksa ilkini yazmak YANLIŞ olurdu — o durum eski biçimin\n // işidir ve yeni biçim + çoklu vector kolonu apply'da reddedilir.\n const vectorColumn = Object.entries(columns).find(([, c]) => c.dimensions !== undefined)?.[0];\n const sj = searchToJSON(table.search, vectorColumn);\n if (sj.text !== undefined || sj.vector !== undefined) out.search = sj;\n }\n if (table.memory !== undefined) {\n out.memory = memoryToJSON(table.memory);\n }\n return out;\n}\n\n/**\n * The key a table answers to in `SchemaJSON.tables`.\n *\n * A public table is BARE, anything else is schema-qualified. This is not a new\n * convention: `RefJSON.Table` already carries `auth.users`, and introspection\n * already returns a public referent bare and a non-public one qualified. Adding\n * a second key space would make two interpreters of the same database.\n */\nexport function qualifiedTableKey(schemaName: string, tableName: string): string {\n // An ABSENT schema means public, exactly as Go's `isPublicSchema` says. This\n // branch used to be missing here and present in the engine's private copy, so\n // the two writers of one rule answered DIFFERENTLY for `\"\"`: one qualified it\n // into a schema literally named the empty string, the other left it bare.\n return schemaName === \"\" || schemaName === \"public\" ? tableName : `${schemaName}.${tableName}`;\n}\n\n/**\n * Serialize declared schemas into the JSON the deploy applies.\n *\n * Takes every schema the project declares — one file per schema — because a\n * cross-schema foreign key can only be checked when both ends are in hand.\n */\nexport function toSchemaJSON(schemas: readonly SchemaDef[]): SchemaJSON {\n const tables: Record<string, TableJSON> = {};\n const extensions: string[] = [];\n const meta: SchemaMetaJSON[] = [];\n const seen = new Set<string>();\n for (const schema of schemas) {\n if (seen.has(schema.name)) {\n throw new Error(`two schemas declare the name \"${schema.name}\" — schema names must be unique`);\n }\n seen.add(schema.name);\n for (const table of Object.values(schema.tables)) {\n const json = tableToJSON(table, schema.name);\n tables[qualifiedTableKey(schema.name, json.name)] = json;\n }\n extensions.push(...(schema.extensions ?? []));\n // The schema list travels because the flag has nowhere else to live: without\n // it /v1/db cannot know which schemas are reachable over HTTP, and nothing\n // downstream can read the DECLARED schema set that introspection needs.\n meta.push({ name: schema.name, exposed: schema.exposed });\n }\n return { tables, extensions: [...new Set(extensions)], schemas: meta };\n}\n","/** A PostgreSQL isolation level supported by the explicit root transaction. */\nexport type TransactionIsolation = \"read committed\" | \"repeatable read\" | \"serializable\";\n\nexport interface AtomicOptions {\n /** Each retry opens a fresh transaction and reruns the complete callback.\n * Defaults to zero. Keep external effects outside it; persist an outbox instead. */\n retry?: number;\n isolation?: TransactionIsolation;\n readOnly?: boolean;\n /** Maximum wait for a PostgreSQL lock. Defaults to 5000 ms. */\n lockTimeoutMs?: number;\n /** PostgreSQL statement timeout; applies to every statement in this scope. */\n statementTimeoutMs?: number;\n /** Total work deadline including queueing and retries. Active Bun queries are\n * cancelled; rollback settles before release. An in-flight COMMIT is awaited. */\n timeoutMs?: number;\n signal?: AbortSignal;\n\n}\n\nexport function retryBudget(value: number | undefined): number {\n const n = value ?? 0;\n if (!Number.isInteger(n) || n < 0 || n > 10) {\n throw new Error(\"transaction retry must be an integer between 0 and 10\");\n }\n return n;\n}\n\nexport function validateAtomicOptions(options: AtomicOptions): void {\n retryBudget(options.retry);\n if (options.isolation !== undefined && ![\"read committed\", \"repeatable read\", \"serializable\"].includes(options.isolation)) {\n throw new Error(\"transaction isolation must be read committed, repeatable read or serializable\");\n }\n if (options.readOnly !== undefined && typeof options.readOnly !== \"boolean\") {\n throw new Error(\"transaction readOnly must be a boolean\");\n }\n for (const name of [\"lockTimeoutMs\", \"statementTimeoutMs\", \"timeoutMs\"] as const) {\n const n = options[name];\n if (n !== undefined && (!Number.isInteger(n) || n < 1 || n > 2_147_483_647)) {\n throw new Error(`transaction ${name} must be a positive integer in milliseconds`);\n }\n }\n if (options.signal !== undefined && (typeof options.signal.aborted !== \"boolean\" || typeof options.signal.addEventListener !== \"function\")) {\n throw new Error(\"transaction signal must be an AbortSignal\");\n }\n}\n\n/** A savepoint cannot replace the enclosing transaction's snapshot or retry COMMIT. */\nexport function assertPlanRetry(options: { retry?: number } | undefined): void {\n if (retryBudget(options?.retry) !== 0) {\n throw new Error(\n \"Database.$transaction is a savepoint plan on the request transaction and cannot retry its snapshot or COMMIT. \" +\n \"Use Database.$atomic(async tx => { ... }, { retry, isolation }) and put all decision reads and writes inside that callback.\",\n );\n }\n}\n"],"mappings":"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","names":["REF_BRAND","Symbol","for","brandRef","v","kind","Object","defineProperty","value","enumerable","brandOf","undefined","hasOwn","looksLikeUnbrandedRef","isColumnExpr","o","$col","$sql","$expr","isColRef","isPlanRef","r","$ref","op","field","looksLikeUnbrandedPlanRef","isSqlFragment","f","Array","isArray","text","values","TX_EXPR","isNowExpr","e","fn","assertNoExpressionHandles","caller","table","cols","data","c","Error","KNOWN_OPS","Set","REFUSED_OPS","eq","assertUsableFilter","where","COMPOSITES","col","cond","entries","has","branches","b","rel","inner","length","some","x","assertUsableWriteValues","TxRefError","Error","message","name","TxPlanError","EXPR","Symbol","for","REF","ROW","ROWS","TRAPPED_PROPS","toPrimitive","trap","prop","what","hint","description","String","now","makeExpr","fn","increment","by","assertAmount","inc","decrement","dec","test","Number","isFinite","negative","trimStart","startsWith","other","columnExprOf","v","exprOf","expr","Proxy","get","target","includes","undefined","makeRef","op","field","t","makeRowHandle","refDescriptor","d","isRefDescriptor","rowOpIndex","e","isRowsHandle","encodeValue","value","column","allowColumnExpr","ref","brandRef","$ref","isNowExpr","$expr","assertNoNestedHandles","encodeFilterValue","Array","isArray","map","Date","isColRef","isSqlFragment","out","k","Object","entries","encodeFilterMap","key","keys","sort","item","values","encodeMap","SKIPPED_OP","TxRowsImpl","guarded","builder","opIndex","then","expectOne","error","declareGuard","expectNone","expectAtLeast","n","assertGuardCount","expectAtMost","kind","attachGuard","isInteger","MAX_OPS","MAX_ROWS","TxPlanBuilder","ops","slots","table","insert","encoded","length","push","put","options","onConflict","insertMany","rows","opts","row","assertUniformRows","action","updateWhere","where","set","encodedWhere","encodedSet","deleteWhere","select","limit","lock","index","slot","guard","body","errorForSlot","first","want","wantKey","join","i","got","materializeResult","results","rowOf","rowOp","isPlainObject","result","proto","getPrototypeOf","prototype","runTxPlan","transport","handle","returned","response","txPlan","err","translateRejection","rejection","error_code","defOf","column","_def","columnToJSON","def","out","type","nullable","primaryKey","defaultValue","undefined","defaultRandom","defaultNow","renamedFrom","ignored","owns","references","table","onDeleteAction","index","counter","enumName","enumValues","unique","dimensions","policyToJSON","policy","name","command","roles","using","withCheck","permissive","commonSearchFields","search","synonyms","Object","keys","length","fromEntries","entries","map","word","alts","validity","searchToJSON","vectorColumn","from","model","textCols","text","Array","isArray","columns","v","metric","embed","provider","apiKeyName","baseURL","staleness","mode","chunks","c","size","sizeChars","overlap","overlapChars","vector","legs","leg","memoryToJSON","m","into","subject","extract","tableToJSON","schemaName","schema","rls","policies","uniqueConstraints","u","raw","rawConstraints","r","up","down","checks","expr","indexes","i","ix","where","expression","sort","nulls","include","appendOnly","find","sj","memory","qualifiedTableKey","tableName","toSchemaJSON","schemas","tables","extensions","meta","seen","Set","has","Error","add","values","json","push","exposed","retryBudget","value","n","Number","isInteger","Error","validateAtomicOptions","options","retry","isolation","undefined","includes","readOnly","name","signal","aborted","addEventListener","assertPlanRetry"]}
1
+ {"version":3,"sources":["../src/db/input-guards.ts","../src/db/tx-plan.ts","../src/db/schema-json.ts","../src/db/transaction-options.ts"],"sourcesContent":["/**\n * The refusals a Database call gets BEFORE any SQL exists — written once, so the\n * engine and the test double cannot disagree about them.\n *\n * WHY THIS FILE EXISTS. `fakeDatabase()` is a second implementation of the same\n * surface (`__tests__/helpers/mock-db.ts`), and it never touched `compileWhere`\n * or `asBindParams`. Measured against the published 24.1.0: all four of the\n * calls that release had just started refusing went through the fake SILENTLY —\n * `update{title:undefined}`, `insert{title:undefined}`, `findMany{done:{}}`,\n * `deleteMany{owner,created_at:{}}`.\n *\n * The scaffold tells authors to test the service layer against exactly that\n * fake. So a test went green on a call production would throw on, and the\n * author found out in production instead — the same \"the surface does not match\n * the engine\" shape these refusals exist to end, arriving through the door the\n * SDK hands people for testing.\n *\n * These are pure and SQL-free on purpose: an in-memory store can run them as\n * easily as the driver path can.\n */\n\n/**\n * İşaretçilerin MARKASI — `col()` ve `sqlFragment()` ürünlerini bu süreçte\n * üretilmiş olmakla tanımlar.\n *\n * NEDEN ŞEKİL DEĞİL DE MARKA (gözcü W2-A/C1 ve W2-B/C3, ikisi de ÖLÇTÜ):\n * şekil kontrolü, işaretçiyi güvenilmeyen bir istek gövdesinden UYDURULABİLİR\n * kılıyordu. Ölçülen iki sonuç:\n *\n * findMany(\"docs\", { owner_id: JSON.parse('{\"$col\":\"owner_id\"}') })\n * → WHERE true AND t.\"owner_id\" = t.\"owner_id\" ← kiracılık predikatı totoloji\n * findMany(\"todos\", JSON.parse('{\"$sql\":{\"text\":[\"1=1 -- pwned\"],\"values\":[]}}'))\n * → WHERE true AND 1=1 -- pwned ← saldırganın metni SQL'e HARFİYEN\n *\n * `{ where: { tenant_id: tid, ...req.body.filter } }` bu SDK'nın öğrettiği\n * desen; T010/T014 öncesinde aynı anahtarlar \"bilinmeyen operatör\" diye\n * REDDEDİLİYORDU. Marka o reddi geri getiriyor.\n *\n * Sembol GLOBAL kayıttan (`Symbol.for`) ve ENUMERABLE DEĞİL. İkisi de kasıtlı:\n * global kayıt paketin iki kopyası arasında da eşleşir; enumerable olmaması ise\n * `JSON.stringify` ve `{...ref, gt: 5}` yayılımının markayı DÜŞÜRMESİNİ sağlar —\n * yani telden geçen ya da elle karıştırılan hiçbir şey işaretçi sayılmaz.\n * Kardeş özellik (`increment`) zaten `Symbol.for(\"palbase.tx.expr\")` kullanıyor;\n * bu onun aynısı.\n */\nconst REF_BRAND = Symbol.for(\"palbase.db.ref\");\n\n/** İşaretçiyi markalar. Yalnız `col()` ve `sqlFragment()` çağırır. */\nexport function brandRef<T extends object>(v: T, kind: \"col\" | \"sql\" | \"ref\"): T {\n Object.defineProperty(v, REF_BRAND, { value: kind, enumerable: false });\n return v;\n}\n\nfunction brandOf(v: unknown): unknown {\n if (typeof v !== \"object\" || v === null) return undefined;\n // KENDİ özelliği olmalı, prototip zincirinden MİRAS ALINMIŞ değil:\n // `Object.create(col(\"x\"))` markayı zincirden okuyup işaretçi sayılıyordu\n // (gözcü ölçtü). Telden erişilemez — JSON `__proto__` üstünden sembol\n // yazamaz — ama daraltmak bedava ve \"işaretçi bu süreçte ÜRETİLDİ\"\n // iddiasının tam karşılığı budur.\n return Object.hasOwn(v, REF_BRAND) ? (v as Record<symbol, unknown>)[REF_BRAND] : undefined;\n}\n\n/**\n * Bir değer, MARKASIZ bir işaretçi taklidi mi? (`{$col:…}` / `{$sql:…}`)\n *\n * Üst düzeyde bunlar zaten \"bilinmeyen operatör\" diye reddediliyor. Ama\n * operatörün SAĞINDA — `{ amount: { gt: {\"$col\":\"other\"} } }` — sessizce\n * PARAMETRE olarak bağlanıyorlardı: sayısal kolonda sürücünün 22P02'si,\n * jsonb/text kolonunda ise HİÇBİR SATIR, hatasız (gözcü ölçtü).\n *\n * `in` listesindeki aynı kusur adıyla reddediliyor; bu onun bir seviye\n * yanındaki hâli ve aynı cevabı hak ediyor.\n */\nexport function looksLikeUnbrandedRef(v: unknown): \"col\" | \"sql\" | \"expr\" | null {\n if (typeof v !== \"object\" || v === null) return null;\n if (brandOf(v) !== undefined) return null; // gerçek işaretçi\n if (isColumnExpr(v)) return null; // gerçek ifade tutamağı (kendi markası var)\n const o = v as { $col?: unknown; $sql?: unknown; $expr?: unknown };\n if (typeof o.$col === \"string\") return \"col\";\n if (o.$sql !== undefined && typeof o.$sql === \"object\" && o.$sql !== null) return \"sql\";\n // `$expr` `now()`/`increment()`'in TEL BİÇİMİ. `now()` filtrede geçerli bir\n // değer olduğu andan itibaren bu şekil de uydurulabilir hâle geldi: ÖLÇÜLDÜ,\n // gövdeden gelen `{\"$expr\":{\"fn\":\"now\"}}` sessizce PARAMETRE olarak bağlanıp\n // sorguyu hatasız biçimde boş sonuca çeviriyordu. `$col`/`$sql`/`$ref` ile\n // aynı kapı, aynı gerekçe.\n if (o.$expr !== undefined && typeof o.$expr === \"object\" && o.$expr !== null) return \"expr\";\n return null;\n}\n\n/**\n * `col()` ürünü mü? (FR-011)\n *\n * Burada, çünkü bu dosya \"iki uygulamanın da okuduğu kurallar\" dosyası: motor,\n * `fakeDatabase` ve guard AYNI cevabı vermek zorunda.\n */\nexport function isColRef(v: unknown): v is { readonly $col: string } {\n return brandOf(v) === \"col\" && typeof (v as { $col?: unknown }).$col === \"string\";\n}\n\n/**\n * `sqlFragment` ürünü mü? (FR-018)\n *\n * `isColRef` ile aynı gerekçeyle burada: motor, guard ve `fakeDatabase` üçü de\n * aynı cevabı vermek zorunda — biri fragment'i \"kolon haritası\" sanarsa filtre\n * sessizce düşer.\n */\n/**\n * Plan REFERANSI mı? (`{ $ref: { op, field } }`)\n *\n * `$ref` bu dilin MARKASIZ KALAN TEK işaretçisiydi — `engine/db.ts` onu\n * `\"$ref\" in v` diye tanıyordu — ve SDK'nın öğrettiği desen\n * `{ where: { tenant_id: tid, ...req.body.filter } }`. Ölçüldü (gözcü):\n * istek gövdesinden gelen `{\"id\":{\"$ref\":{\"op\":0,\"field\":\"id\"}}}` filtreyi\n * ÖNCEKİ bir işlemin satır değeriyle karşılaştırtıyor —\n * DELETE … WHERE t.\"tenant_id\" = $1 AND t.\"id\" = $2 PRM [\"t1\",\"SIZAN_DEGER\"]\n * gövdenin hiç görmediği bir değer. Enjeksiyon değil (değerler bound) ama bir\n * ORACLE: `op`/`field` seçip `rows_affected`'tan o değeri öğrenmek.\n *\n * Marka `Symbol.for` olduğu için SDK'nın İKİ KOPYASI arasında da eşleşiyor —\n * kontrolcü bundle'ı kendi kopyasını inline ediyor, planı çalıştıran ise\n * runtime'ınki. Ve plan gövdesi JSON'lanmıyor: tek üretim `txPlan` uygulaması\n * süreç içi (`engine/db.ts`), doğrulandı.\n */\nexport function isPlanRef(v: unknown): v is { readonly $ref: { op: number; field: string } } {\n if (brandOf(v) !== \"ref\") return false;\n const r = (v as { $ref?: { op?: unknown; field?: unknown } }).$ref;\n return r !== undefined && typeof r.op === \"number\" && typeof r.field === \"string\";\n}\n\n/** Markasız bir `{ $ref: … }` taklidi mi? Adıyla reddedilmesi için. */\nexport function looksLikeUnbrandedPlanRef(v: unknown): boolean {\n if (typeof v !== \"object\" || v === null || brandOf(v) !== undefined) return false;\n const r = (v as { $ref?: unknown }).$ref;\n return r !== undefined && typeof r === \"object\" && r !== null;\n}\n\nexport function isSqlFragment(v: unknown): v is { readonly $sql: { text: string[]; values: unknown[] } } {\n if (brandOf(v) !== \"sql\") return false;\n const f = (v as { $sql?: { text?: unknown; values?: unknown } }).$sql;\n return f !== undefined && Array.isArray(f.text) && Array.isArray(f.values);\n}\n\n/**\n * İFADE TUTAMAĞI DEĞER DEĞİLDİR — değer bekleyen yollarda adıyla reddedilir.\n *\n * `increment()` / `decrement()` / `now()` bir Proxy döndürür ve yalnız\n * `updateMany` ile plan yolunun `updateWhere`'i onu SQL'e derler. `insert` /\n * `update` / `put` / `supersede` derlemez; oralarda tutamak bound parametre\n * olarak sürücüye gidiyordu ve reddi SÜRÜCÜ veriyordu (\"Unknown object is not\n * a valid PostgreSQL type\") — yazarın yazdığı hiçbir şeyi adlandırmayan bir\n * mesaj (inceleme I-2/I8, ölçüldü). Plan yolu aynı hatayı kendi diliyle\n * reddediyor; bu, doğrudan yolun karşılığı.\n *\n * Sembol `tx-plan.ts`'in markasıyla AYNI global kayıttan okunuyor; bu dosya\n * kural dosyası olduğu için oraya bağımlılık kurmuyor.\n */\nconst TX_EXPR = Symbol.for(\"palbase.tx.expr\");\n\n/**\n * `now()` — SUNUCU SAATİ, karşılaştırma değeri olarak.\n *\n * `increment()`/`decrement()` bir YAZMA ifadesidir ve filtrede anlamsızdır;\n * `now()` öyle değil: `expires_at > now()` sıradan bir karşılaştırma ve her\n * backend'in en sık yazdığı yüklemlerden biri. Filtrede TÜM ifade tutamaklarını\n * reddetmek, yazarı bunun için `sqlFragment`e düşürüyordu — yani sorgunun\n * içine giren parça, en sıradan koşul için gerekiyordu.\n *\n * Ayrım MARKAYLA: bir istek gövdesinden gelen `{\"$expr\":{\"fn\":\"now\"}}` bu\n * süreçte `now()` ile üretilmediği için marka taşımaz ve reddedilir.\n */\nexport function isNowExpr(v: unknown): boolean {\n if (!isColumnExpr(v)) return false;\n try {\n const e = (v as Record<symbol, unknown>)[TX_EXPR];\n return typeof e === \"object\" && e !== null && (e as { fn?: unknown }).fn === \"now\";\n } catch {\n return false;\n }\n}\n\nexport function isColumnExpr(v: unknown): boolean {\n if (typeof v !== \"object\" && typeof v !== \"function\") return false;\n if (v === null) return false;\n try {\n return (v as Record<symbol, unknown>)[TX_EXPR] !== undefined;\n } catch {\n // Tutamak bir Proxy; bilinmeyen bir prop'ta trap fırlatabilir.\n return false;\n }\n}\n\n/**\n * Değer bekleyen bir yazma yolunda ifade tutamağı ya da `col()` var mı?\n *\n * Motor ve `fakeDatabase` AYNI cevabı vermek zorunda: fake tutamağı satıra\n * YAZIYORDU (`row[k] = proxy`) ve satır artık JSON'a bile çevrilemiyordu, motor\n * ise sürücüde patlıyordu. İki farklı yanlış, tek doğru.\n */\nexport function assertNoExpressionHandles(\n caller: string,\n table: string,\n cols: readonly string[],\n data: Record<string, unknown>,\n): void {\n for (const c of cols) {\n const v = data[c];\n // `now()` ile sayaç ifadeleri AYRI cevaplar hak ediyor: ikisinin de\n // çalışan alternatifi var ama farklı (P6 — hata çalışan bir alternatifi\n // ADIYLA söyler). Tek bir \"ifade tutamağı\" mesajı, `now()` yazan kişiye\n // `increment()` öneriyordu.\n if (isNowExpr(v)) {\n throw new Error(\n `${caller}(${table}): \"${c}\" now() aldı — bu yolda değer beklenir. ` +\n `Satır EKLENİRKEN sunucu saatini yazmanın yolu kolonu defaultNow() ile ` +\n `bildirmek (varsayılan kolonun yanında durur, her çağrıda tekrarlanmaz); ` +\n `var olan bir satırı damgalamak için updateMany({ where, set: { ${c}: now() } }) ` +\n `ya da $transaction içinde tx.public.${table}.updateWhere(where, { ${c}: now() }).`,\n );\n }\n if (isColumnExpr(v)) {\n throw new Error(\n `${caller}(${table}): \"${c}\" bir ifade tutamağı aldı (increment()/decrement()). ` +\n `Bu yolda değer beklenir. Sayaç artışı için updateMany({ where, set: { ${c}: increment(n) } }) ` +\n `ya da $transaction içinde tx.public.${table}.updateWhere(where, { ${c}: increment(n) }) kullanın.`,\n );\n }\n if (isColRef(v)) {\n throw new Error(\n `${caller}(${table}): \"${c}\" bir col() aldı. Kolon referansı yalnız FİLTREDE durabilir; ` +\n `bir kolonun değerini başka bir kolona yazmak için $query kullanın.`,\n );\n }\n }\n}\n\n/** The comparison operators a filter value may carry. Kept here because the\n * guard has to tell an operator object from a plain value. */\nconst KNOWN_OPS = new Set([\n \"gt\", \"gte\", \"lt\", \"lte\", \"neq\", \"in\",\n // K1 metin operatörleri (FR-005) ve null testi (FR-006). Bu küme\n // `fakeDatabase()` ile ORTAK kaynaktır: fake bir çağrıyı motorun reddettiği\n // yerde kabul ederse, yazarın testi üretimde patlayan koda karşı yeşil verir.\n \"contains\", \"icontains\", \"startsWith\", \"endsWith\", \"isNull\",\n]);\n\n/**\n * `eq` ADIYLA reddedilir, ve reddi buradadır çünkü guard'ı motor da fake de\n * okuyor.\n *\n * Eşitliğin yazımı ÇIPLAK DEĞERDİR: `{ owner: \"u1\" }`. `eq`'i ikinci bir yazım\n * olarak eklemek, bu run'ın kapatmak için var olduğu şeyi — aynı iş için iki\n * uyumsuz yazım — filtre dilinin İÇİNDE yeniden açardı. Ve eskiden kabul eden\n * ile reddeden ayrışıyordu: guard `eq`'i geçiriyor, derleyici\n * `bilinmeyen operatör \"eq\"` diyordu (gözcü ölçtü).\n */\nconst REFUSED_OPS: Record<string, string> = {\n eq: 'eşitlik ÇIPLAK yazılır: { <kolon>: <değer> } (ya da kolon karşılaştırması için { <kolon>: col(\"…\") })',\n};\n\n/**\n * Refuse a filter that would compile to something other than what it reads like.\n *\n * Three shapes, each measured in production before it was closed:\n *\n * `{ col: undefined }` binds NULL; `= NULL` matches no row, so the query\n * answered \"no records\" and said nothing.\n * `{ col: {} }` produces no term at all — every row on the read\n * path, a dropped condition on the write path.\n * `{ col: { gte: undefined } }` and an `undefined` inside `in`: the same NULL,\n * one level down.\n */\nexport function assertUsableFilter(\n caller: string,\n table: string,\n where: Record<string, unknown> | undefined,\n): void {\n // Bileşim anahtarları (FR-007) bir KOLON adı değildir; kolon doğrulamasından\n // ve operatör kontrolünden muaftır, kendi dalları özyinelemeli olarak aynı\n // kurallardan geçer.\n const COMPOSITES = new Set([\"OR\", \"AND\", \"NOT\"]);\n\n if (!where) return;\n // Fragment bir kolon haritası DEĞİLDİR (FR-018): içeriği SQL'dir, kolon\n // doğrulaması ona uygulanamaz. Değerleri zaten bound gidiyor.\n if (isSqlFragment(where)) return;\n for (const [col, cond] of Object.entries(where)) {\n // Bileşim anahtarları (FR-007) kolon DEĞİLDİR: dalları aynı kurallardan\n // özyinelemeli geçer, ama kendileri operatör kontrolüne girmez.\n if (COMPOSITES.has(col)) {\n const branches = col === \"NOT\" ? [cond] : cond;\n if (!Array.isArray(branches) && col !== \"NOT\") {\n throw new Error(`${caller}(${table}): where.${col} bir dizi olmalı`);\n }\n for (const b of branches as unknown[]) {\n if (b === null || typeof b !== \"object\") {\n throw new Error(`${caller}(${table}): where.${col} dalları filtre nesnesi olmalı`);\n }\n assertUsableFilter(caller, table, b as Record<string, unknown>);\n }\n continue;\n }\n // `has` de kolon DEĞİLDİR: anahtarları İLİŞKİ adları, değerleri BİR TABLO\n // ÖTESİNİN filtresi. İç filtre aynı kurallardan geçiyor — `has` ikinci bir\n // filtre dili değil, aynı dilin bir tablo ötesi.\n //\n // İlişki ADI burada doğrulanMIYOR: grafiği yalnız motor tanıyor (ve tip,\n // derleme anında). Guard'ın onu bilmesi ilişki grafiğinin İKİNCİ bir\n // yorumcusu demekti — `buildRelations`'ın yorumunun adıyla yasakladığı şey.\n if (col === \"has\") {\n if (cond === null || typeof cond !== \"object\" || Array.isArray(cond)) {\n throw new Error(`${caller}(${table}): where.has bir ilişki haritası olmalı ({ <ilişki>: { … } })`);\n }\n for (const [rel, inner] of Object.entries(cond as Record<string, unknown>)) {\n if (inner === null || typeof inner !== \"object\" || Array.isArray(inner)) {\n throw new Error(`${caller}(${table}): where.has.${rel} bir filtre nesnesi olmalı`);\n }\n assertUsableFilter(caller, table, inner as Record<string, unknown>);\n }\n continue;\n }\n if (cond === undefined) {\n throw new Error(\n `${caller}(${table}): where.${col} değeri undefined — bu bir filtre değeri değil. ` +\n `Bağlanınca NULL olur ve '= NULL' hiçbir satıra uymaz, yani sorgu sessizce ` +\n `boş sonuç dönerdi. Değer yoksa anahtarı filtreye hiç koymayın.`,\n );\n }\n if (cond === null || typeof cond !== \"object\" || Array.isArray(cond)) continue;\n // `col()` ürünü bir DEĞER'dir, operatör nesnesi değil (FR-011). Ayırt\n // edilmezse `{ $col: \"x\" }` bir operatör haritası sanılır ve \"bilinmeyen\n // operatör $col\" diye reddedilirdi.\n if (isColRef(cond)) continue;\n // `now()` de bir DEĞER'dir, aynı gerekçeyle — ve tutamak bir Proxy olduğu\n // için `Object.entries` BOŞ döner: ayırt edilmezse \"boş operatör nesnesi\"\n // diye reddedilirdi, yani doğru yazım yanlış bir hatayla karşılanırdı.\n if (isNowExpr(cond)) continue;\n\n const entries = Object.entries(cond as Record<string, unknown>);\n if (entries.length === 0) {\n throw new Error(\n `${caller}(${table}): where.${col} boş bir operatör nesnesi ({}) — hiçbir koşul ` +\n `üretmez, yani bu alan filtreden sessizce DÜŞERDİ. Koşul kurulmayacaksa ` +\n `anahtarı filtreye hiç koymayın (D-21).`,\n );\n }\n for (const [op, v] of entries) {\n if (op === \"in\") {\n if (!Array.isArray(v)) throw new Error(`${caller}(${table}): where.${col}.in bir dizi olmalı`);\n if (v.some((x) => x === undefined)) {\n throw new Error(\n `${caller}(${table}): where.${col}.in listesinde undefined var — sessizce NULL'a ` +\n `bağlanır ve o eleman hiçbir satırla eşleşmez. Listeyi kurarken eleyin.`,\n );\n }\n continue;\n }\n // Sağ tarafta kolon durabilir: `{ total: { gt: col(\"amount_paid\") } }`.\n // Değer kontrolleri (undefined) ona da uygulanır, ama `in` gibi şekil\n // kontrolleri değil — o dal aşağıda zaten ayrı.\n if (REFUSED_OPS[op] !== undefined) {\n // Bilinmeyen değil — BİLİNEREK reddedilen. Hata çalışan yazımı söylüyor.\n throw new Error(`${caller}(${table}): where.${col}.${op} bu filtre dilinde yok — ${REFUSED_OPS[op]}`);\n }\n if (!KNOWN_OPS.has(op)) {\n throw new Error(\n `${caller}(${table}): where.${col} bilinmeyen operatör \"${op}\" (gt/gte/lt/lte/neq/in/contains/icontains/startsWith/endsWith/isNull)`,\n );\n }\n if (v === undefined) {\n throw new Error(\n `${caller}(${table}): where.${col}.${op} değeri undefined — karşılaştırmanın ` +\n `sağ tarafı NULL olur ve sonuç hiçbir satıra uymaz. Koşulu kurmayın.`,\n );\n }\n }\n }\n}\n\n/**\n * Refuse a write whose value never arrived.\n *\n * `{ title: req.body.title }` with no `title` in the body bound NULL and\n * answered 200 — the column was ERASED. `null` is untouched, and the difference\n * is the whole point: null is an author SAYING \"empty this column\"; undefined is\n * nobody saying anything.\n */\nexport function assertUsableWriteValues(\n caller: string,\n table: string,\n cols: readonly string[],\n data: Record<string, unknown>,\n): void {\n for (const c of cols) {\n if (data[c] === undefined) {\n throw new Error(\n `${caller}(${table}): \"${c}\" değeri undefined — bu bir yazma değeri değil. ` +\n `Kolonu boşaltmak istiyorsan null yaz; kolonu değiştirmek istemiyorsan nesneye hiç koyma ` +\n `(bir eksik istek alanı sessizce NULL yazıyordu — FR-016).`,\n );\n }\n }\n}\n","/**\n * tx-plan.ts — `Database.$transaction()` as a PLAN, not a pinned session.\n *\n * A transaction used to be a conversation: BEGIN, then one network round trip\n * per operation, then COMMIT. Each of those round trips cost ~4 ms and, because\n * the pooler runs in transaction mode, an open transaction pinned a Postgres\n * backend for the whole conversation. A 121-operation statement upload pinned\n * one backend for ~490 ms.\n *\n * So the callback no longer TALKS to the database. It DESCRIBES what should\n * happen; the description is serialised and sent once; the broker runs the whole\n * thing inside one transaction and answers once. Committing on return and\n * rolling back on throw is unchanged — that is the only property tenant code\n * actually asked for.\n *\n * The consequences, stated plainly, because they are the whole design:\n *\n * - The callback is SYNCHRONOUS. There is nothing to await: no statement has\n * run yet when it returns. `async` on the callback and `await` inside it are\n * both compile errors (see {@link TxPlan} and {@link NotAwaitable}).\n * - `insert()` does not hand back a row, it hands back {@link TxRows}. Reading\n * a field requires `.expectOne(err)` first, which makes \"what if the row\n * isn't there\" a question you cannot route around: it is the argument.\n * - A field read from a row is a {@link Ref} — a PROMISE OF A VALUE THE SERVER\n * WILL PRODUCE, not the value. It can be written into a later operation and\n * it can be returned from the callback (it is substituted for the real value\n * before `transaction()` resolves). It cannot be branched on. See the\n * \"Truthiness\" note below — this is the sharp edge of the whole design.\n * - Control flow that needs a real value must move OUT of the callback: read\n * before the transaction, or express the condition as a guard\n * (`updateWhere({ id, accepted_at: null }, …).expectOne(new Conflict(…))`)\n * which the server evaluates and which rolls the whole plan back.\n *\n * # Truthiness — the hole this file CANNOT close\n *\n * JavaScript does not let a Proxy trap truthiness. `if (ref)` takes the true\n * branch, always, for every Ref, and no `get` handler ever runs. `tsc` is silent\n * because a Ref is a perfectly good object. So:\n *\n * const pot = tx.tables.pots.select({ id }, { limit: 1 }).expectOne(e);\n * if (!pot.balance) { … } // ← ALWAYS false. Silently wrong data.\n *\n * What this file does close: coercion (`Symbol.toPrimitive`/`valueOf`/\n * `toString`), awaiting (`then` is a callable member with a non-thenable\n * signature, which is a *compile* error), serialisation (`toJSON`), and nesting\n * a Ref inside a literal value where the server would store it as data. What it\n * cannot close is a bare truthiness test. The real defence is the build-time\n * static analysis (`tx_analysis.js`, phase P4); until that ships, this hole is\n * open and this comment is the only warning.\n *\n * # Wire contract\n *\n * The JSON this file emits is consumed by\n * the plan executor in `engine/db.ts`. That executor rejects\n * unknown fields at every level, so an op carries EXACTLY the fields its kind\n * takes. Everything here that looks like a needless restriction is one of the\n * server's rules made visible early:\n *\n * - `$ref` only points BACKWARDS, and only at an op statically known to yield\n * at most one row (insert, or a `one`/`atMost 1` guard, or `select limit 1`).\n * `.expectOne()` is what this file uses to satisfy that, always.\n * - `$expr` is a closed set: `inc`/`dec` (update only — they read the column's\n * current value) and `now()`.\n * - `update`/`delete` require a `where`; `insert` refuses one.\n * - `insertMany` rows must all set the same columns.\n * - ≤1000 ops, ≤5000 rows per insertMany, ≤8 MiB of JSON.\n *\n * Column keys are emitted SORTED, so the same callback always produces byte-\n * identical JSON. That is what lets the Go decoder be locked to golden files\n * this SDK emits (`testdata/tx_plan_golden/`).\n */\n\n// ---------------------------------------------------------------------------\n// Errors\n// ---------------------------------------------------------------------------\n\n/**\n * A plan handle was used as if it were a value: awaited, coerced to a string or\n * number, serialised, or nested inside another value.\n *\n * Thrown while the callback is still BUILDING the plan, so nothing has been sent\n * and nothing has been written.\n */\n// TİP-ONLY, ve döngü kasıtlı: `typed-db.ts` bu dosyadan tip alıyor, bu dosya\n// ondan `WhereOp` alıyor. Çalışma zamanında hiçbir şey ithal edilmiyor (import\n// type), yani modül döngüsü yok — paylaşılan olan şey TEK FİLTRE DİLİ, ve onu\n// iki yerde ayrı ayrı tanımlamak bu run'ın kapattığı \"iki yazım\"ın tipteki\n// hâli olurdu.\nimport type { WhereOpWith, ColRefOf, HasOnly, SqlFragment } from \"./typed-db.js\";\nimport { isColRef, isSqlFragment, brandRef, isNowExpr } from \"./input-guards.js\";\n\nexport class TxRefError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"TxRefError\";\n }\n}\n\n/**\n * The plan the callback described cannot be sent: it breaks a rule the server\n * would reject, and rejecting it here names the line that wrote it instead of\n * returning a 400 about an op index.\n */\nexport class TxPlanError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"TxPlanError\";\n }\n}\n\n// ---------------------------------------------------------------------------\n// Wire types — mirror the plan executor in `engine/db.ts` exactly.\n// ---------------------------------------------------------------------------\n\n/** A backwards reference to an earlier op's single-row result. */\nexport interface TxWireRef {\n $ref: { op: number; field: string };\n}\n\n/** A call from the server's closed function set. */\nexport interface TxWireExpr {\n $expr: { fn: \"inc\" | \"dec\"; by: number | string } | { fn: \"now\" };\n}\n\n/** One value in a `values`/`set`/`where` map: a literal, a `$ref` or a `$expr`. */\nexport type TxWireValue = TxWireRef | TxWireExpr | unknown;\n\n/** The tenant's declared expectation about an op's row count. `slot` indexes the\n * client-side error table — the error OBJECT never travels. */\nexport interface TxWireGuard {\n kind: \"one\" | \"none\" | \"atLeast\" | \"atMost\";\n n: number;\n slot: number;\n}\n\n/** One operation in the wire plan. Fields are omitted, never null: the decoder\n * rejects a field that does not belong to the op's kind. */\nexport interface TxWireOp {\n /** upsert and insertMany: the columns Postgres matches on. */\n onConflict?: readonly string[];\n /** insertMany only: what a collision does. Absent means no ON CONFLICT clause\n * at all, which is what every insertMany did before this option existed. */\n action?: \"ignore\" | \"update\";\n op: \"insert\" | \"insertMany\" | \"upsert\" | \"update\" | \"delete\" | \"select\";\n table: string;\n values?: Record<string, TxWireValue>;\n rows?: Record<string, TxWireValue>[];\n set?: Record<string, TxWireValue>;\n where?: Record<string, TxWireValue>;\n limit?: number;\n lock?: \"update\";\n guard?: TxWireGuard;\n}\n\n/** The plan the engine executes on the request's own transaction. */\nexport interface TxPlanBody {\n ops: TxWireOp[];\n}\n\n/** One op's outcome, positionally matched to the plan's ops. */\nexport interface TxPlanOpResult {\n rows: Record<string, unknown>[];\n rows_affected: number;\n}\n\n/** One result per op, in plan order. */\nexport interface TxPlanResponse {\n results: TxPlanOpResult[];\n}\n\n/**\n * The fields the runtime must copy from the broker's error envelope onto the\n * rejection it throws out of {@link DBClient.txPlan}.\n *\n * `slot` is the whole point: on a guard failure the server answers with the\n * INDEX of the expectation that did not hold, never with an error message of its\n * own, and this SDK maps that index back to the `Error` the callback handed to\n * `.expectOne(…)`. Without `slot` a guard failure degrades to a generic 409.\n */\nexport interface TxPlanRejection {\n status?: number;\n /** `tx_plan_invalid` | `tx_guard_failed` | `tx_ref_unresolved` | a pg class. */\n error_code?: string;\n /** Present only for `tx_guard_failed`: the client-side error table index. */\n slot?: number;\n /** Present on a database error: which op failed. */\n op?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Handle types\n// ---------------------------------------------------------------------------\n\ndeclare const refBrand: unique symbol;\ndeclare const rowBrand: unique symbol;\ndeclare const rowsBrand: unique symbol;\n\n/**\n * Makes a handle a compile error to `await`.\n *\n * `then` is declared as a CALLABLE member whose signature is not `PromiseLike`,\n * which is precisely the shape TypeScript rejects: `await handle` is TS1320 and\n * `async () => handle` is TS1058. A non-callable `then` would not do it — the\n * compiler simply ignores those.\n */\nexport interface NotAwaitable {\n /** Not a promise. Nothing here has run yet; there is nothing to await. */\n then(doNotAwaitAPlanHandle: \"a transaction plan is built synchronously\"): never;\n}\n\n/**\n * A value the SERVER will produce, standing in for a column of a row this plan\n * writes or reads.\n *\n * Legal uses: write it into a later operation's `values`/`set`/`where`, or\n * return it from the callback (it is replaced by the real value before\n * `transaction()` resolves).\n *\n * Illegal, and caught: `await`, `String(ref)`, `` `${ref}` ``, `ref + 1`,\n * `JSON.stringify(ref)`, burying it inside a jsonb object.\n *\n * Illegal, and NOT caught: `if (ref)`. See the truthiness note at the top.\n */\nexport interface Ref<T> extends NotAwaitable {\n readonly [refBrand]: T;\n}\n\n/** The brand carried by a single-row handle, and the seam `Materialized` reads\n * to turn `return st` into the whole row. */\nexport interface TxRowHandle<Row> extends NotAwaitable {\n readonly [rowBrand]: Row;\n}\n\n/**\n * A row this plan is known to produce exactly one of. Every property is a\n * {@link Ref}; returning the handle itself yields the whole row.\n *\n * Only `.expectOne(err)` produces one — which is the design: a row you can read\n * fields from is a row whose absence you have already answered for.\n */\nexport type TxRow<Row> = { readonly [K in keyof Row]: Ref<Row[K]> } & TxRowHandle<Row>;\n\n/**\n * The result of one operation, before any expectation is declared about it.\n *\n * Deliberately not a row and not a list: an operation's row count is not known\n * until the server runs it, so the only thing that can be said about it here is\n * an EXPECTATION. Declaring one is also the only way to get a readable row.\n *\n * At most one expectation per operation — the wire carries one guard per op, and\n * a second call throws rather than silently dropping the first.\n */\nexport interface TxRows<Row> extends NotAwaitable {\n readonly [rowsBrand]: Row;\n /**\n * Require exactly one row, and read it. On any other count the server rolls\n * the whole transaction back and this `error` is thrown to the caller.\n *\n * This is the only way to reach a row's fields, and the only shape a `$ref`\n * may point at.\n */\n expectOne(error: Error): TxRow<Row>;\n /** Require zero rows (e.g. \"this membership must not already exist\"). */\n expectNone(error: Error): void;\n /** Require at least `n` rows. */\n expectAtLeast(n: number, error: Error): void;\n /** Require at most `n` rows. */\n expectAtMost(n: number, error: Error): void;\n}\n\n/** `now()` — the server's clock, usable wherever a value is. */\nexport interface TxNow extends NotAwaitable {\n readonly $expr: { fn: \"now\" };\n}\n\n/** `inc(n)` / `dec(n)` — read the column's CURRENT value and write it back\n * changed. Only meaningful in an update's `set`, which is where the types allow\n * it and where the server allows it. */\nexport interface TxColumnExpr extends NotAwaitable {\n readonly $expr: { fn: \"inc\" | \"dec\"; by: number | string };\n}\n\n/**\n * Resolve a callback's return type against what actually comes back: every\n * {@link Ref} becomes its value, every {@link TxRow} becomes its row, and\n * anything else keeps its shape.\n *\n * A {@link TxRows} resolves to an explanatory string type rather than a row\n * list: it has no single answer to give, and saying so in the type is louder\n * than a runtime throw.\n */\nexport type Materialized<T> = T extends Ref<infer U>\n ? U\n : T extends TxRowHandle<infer R>\n ? R\n : T extends TxRows<unknown>\n ? \"a TxRows cannot leave the transaction callback — read a row with .expectOne(err) first\"\n : T extends Date\n ? T\n : T extends object\n ? { [K in keyof T]: Materialized<T[K]> }\n : T;\n\n// ---------------------------------------------------------------------------\n// Author-facing value types\n// ---------------------------------------------------------------------------\n\n/** A value written by an INSERT: a literal, an earlier row's field, or `now()`.\n * `inc`/`dec` are absent on purpose — they read a current value, and an inserted\n * row has none. */\nexport type TxInsertValue<V> = V | Ref<V> | TxNow;\n\n/** A value written by an UPDATE's `set`: everything an insert takes, plus the\n * read-modify-write expressions. */\n/**\n * TEK KURAL: ifade tutamağı yalnız sayısal-benzeri kolonlarda.\n *\n * Bu tip KOŞULSUZDU ve doğrudan yolun `SetValue<V>`'si koşulluydu, yani aynı\n * nesne için İKİ tip kuralı vardı: `tx.tables.todos.updateWhere({id}, { done:\n * increment(1) })` (boolean kolon!) DERLENİYOR, `updateMany`'nin aynısı derleme\n * hatası veriyordu. Bu run'ın kapatmak için var olduğu şey \"aynı iş için iki\n * uyumsuz yazım\"dı; tip kuralı ikinci yazımın kendisi olmuştu (gözcü I6/I-1).\n */\nexport type TxSetValue<V> =\n | V\n | Ref<V>\n | TxNow\n | (NonNullable<V> extends number | string ? TxColumnExpr : never);\n\n/** An insert payload: the table's insert shape, with refs and `now()` allowed. */\nexport type TxInsertShape<Insert> = { [K in keyof Insert]: TxInsertValue<Insert[K]> };\n\n/** An update's `set`: any subset of the insert shape, with expressions allowed. */\nexport type TxSetShape<Insert> = { [K in keyof Insert]?: TxSetValue<Insert[K]> };\n\n/**\n * A filter. Every entry is an equality test and they are AND-ed; a `null`\n * becomes `IS NULL`, which is what makes `{ accepted_at: null }` a usable\n * \"not yet accepted\" guard rather than a clause that matches nothing.\n */\n/**\n * Plan filtresinin tipi — `WhereFilter<Row>` ile AYNI sözlük, artı `Ref`.\n *\n * Eskiden yalnız eşitlikti (`Row[K] | Ref<Row[K]>`), ve iki şeye mal oluyordu:\n * FR-014'ün amiral deseni (`{ balance: { gte: amount } }`) `$transaction`\n * İÇİNDE yazılamıyordu — koşullu bir yazmayı plana koyamayan yazar `$query`'ye\n * düşüyordu — ve motor tarafında tip atlandığında aynı nesne SESSİZCE parametre\n * olarak bağlanıyordu.\n *\n * `Ref` fazladan üye ve öyle kalmalı: bir plan filtresi ÖNCEKİ bir işlemin\n * döndürdüğü değere bakabilir, `findMany` bakamaz — plan dışında böyle bir\n * \"önceki işlem\" yok.\n */\ntype TxWhereField<Row, K extends keyof Row> = WhereOpWith<\n Row[K],\n // `Ref` KOLON REFERANSININ YANINDA duruyor, `V`'nin içinde DEĞİL: `V`'ye\n // eklenseydi `TextOps<V>`'nin `V extends string` sorusu HAYIR olur ve\n // `contains`/`startsWith` sessizce kaybolurdu (ölçüldü).\n ColRefOf<Row, Row[K]> | Ref<Row[K]>\n>;\n\nexport type TxWhere<Row, Rels = unknown> = {\n [K in keyof Row]?: TxWhereField<Row, K>;\n} & {\n // Düz op'lardaki `WhereFilter` ile AYNI: dal bir `sqlFragment` de olabilir.\n // İki filtre dilinin bir dalda ayrışması, \"tek dil\" iddiasını tam da bileşim\n // anında boşa çıkarırdı — ve motor plan yolunda da fragment'i derliyor\n // (ölçüldü: `SELECT t.* FROM \"crew\" t WHERE true AND (((a > 1)) AND (…))`).\n OR?: (TxWhere<Row, Rels> | SqlFragment)[];\n AND?: (TxWhere<Row, Rels> | SqlFragment)[];\n NOT?: TxWhere<Row, Rels> | SqlFragment;\n} & HasOnly<Rels>;\n\n/** Options for a plan `select`. */\nexport interface TxSelectOptions {\n /** Cap the rows read. */\n limit?: number;\n /** Take a real `FOR UPDATE` row lock for the rest of the transaction. */\n lock?: \"update\";\n}\n\n/** One table, as the plan sees it. */\nexport interface TxTable<Row, Insert, Rels = unknown> {\n /** Insert one row. Returns a handle — call `.expectOne(err)` to read fields. */\n insert(values: TxInsertShape<Insert>): TxRows<Row>;\n /**\n * Insert many rows in ONE statement. Every row must set the same columns\n * (a row that omits one would silently take the column's default).\n *\n * An empty list writes nothing and sends nothing.\n */\n /**\n * Insert many rows in ONE statement, optionally choosing what a collision does.\n *\n * Without `opts` this is a plain multi-row INSERT and a collision aborts the\n * transaction — the behaviour every call had before the option existed.\n *\n * `action: \"ignore\"` emits `ON CONFLICT DO NOTHING`, which is how \"insert the\n * ones that are new\" becomes one round-trip instead of one per row with a\n * 23505 caught around each. **The returned rows are the ones actually\n * INSERTED**: a row that collided is skipped, so it is absent from the result\n * — Postgres does not return what it did not write.\n *\n * `action: \"update\"` emits `ON CONFLICT DO UPDATE`, setting every non-conflict\n * column from the incoming row, and every row comes back.\n */\n insertMany(\n rows: readonly TxInsertShape<Insert>[],\n opts?: {\n onConflict: readonly Extract<keyof Row, string>[];\n action?: \"ignore\" | \"update\";\n },\n ): TxRows<Row>;\n /**\n * Satırı yaz, `onConflict` kolonlarında çakışırsa üzerine yaz — planın\n * savepoint'i içinde, `Database.<şema>.<tablo>.put()` ile AYNI anlamda.\n *\n * Adı bilerek aynı: aynı iş için transaction içinde ve dışında iki farklı\n * yazım, bu run'ın kapatmak için var olduğu şeydir (P1). TEL şekli\n * (`op: \"upsert\"`) değişmedi — o iç sözleşme, yazarın gördüğü ad değil.\n *\n * Bir operasyon olmasının sebebi: alternatifi burada yazılamaz — başarısız\n * bir insert tüm transaction'ı abort eder, yani \"dene, sonra geri düş\" iki\n * plan adımı olamaz.\n */\n put(\n values: TxInsertShape<Insert>,\n options: { onConflict: readonly Extract<keyof Row, string>[] },\n ): TxRows<Row>;\n /**\n * Update every row matching `where`. The filter comes first because it is the\n * dangerous half: an update whose `where` you got wrong rewrites rows you\n * never looked at. The server refuses an update with no `where` at all.\n */\n updateWhere(where: TxWhere<Row, Rels>, set: TxSetShape<Insert>): TxRows<Row>;\n /** Delete every row matching `where`. The server refuses an unfiltered delete. */\n deleteWhere(where: TxWhere<Row, Rels>): TxRows<Row>;\n /** Read rows, optionally locking them for the rest of the transaction. */\n select(where?: TxWhere<Row, Rels>, options?: TxSelectOptions): TxRows<Row>;\n}\n\n/**\n * The handle a transaction callback receives.\n *\n * It carries tables and nothing else: no `query`, no `findById`, no `asService`.\n * A read whose value the plan does not write belongs OUTSIDE the transaction,\n * where it costs one round trip and can be branched on like an ordinary value.\n */\nexport interface TxPlanHandle<TTables> {\n /**\n * @deprecated `tx.public` kullanın. Bu ad public'in takma adı olarak DURUYOR\n * (göç notu onu öğretiyor ve her mevcut çağrı onu kullanıyor), ama ARTIK\n * ÖĞRETİLMİYOR: doğrudan yüzeyde `Database.tables` FR-001 ile kaldırıldı, ve\n * plan yüzeyinin onu öğretmeye devam etmesi yazarı bir yüzeyde çalışıp\n * diğerinde derlenmeyen bir yazıma alıştırıyordu (gözcü M-6).\n */\n tables: TTables;\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — expressions\n// ---------------------------------------------------------------------------\n\n/** Internal marker read by the serialiser. */\nconst EXPR = Symbol.for(\"palbase.tx.expr\");\nconst REF = Symbol.for(\"palbase.tx.ref\");\nconst ROW = Symbol.for(\"palbase.tx.row\");\nconst ROWS = Symbol.for(\"palbase.tx.rows\");\n\ninterface RefDescriptor {\n op: number;\n field: string;\n}\n\n/** Property reads that must not silently produce a value on a plan handle.\n * `then` is the one that matters for correctness (it makes `await` a compile\n * error AND stops a handle from being adopted by a promise); the rest turn a\n * silent wrong answer — `\"[object Object]\"`, `NaN`, `{}` — into a thrown one. */\nconst TRAPPED_PROPS: readonly (string | symbol)[] = [\n \"then\",\n \"valueOf\",\n \"toString\",\n \"toJSON\",\n Symbol.toPrimitive,\n];\n\nfunction trap(prop: string | symbol, what: string, hint: string): never {\n const name = typeof prop === \"symbol\" ? prop.description ?? String(prop) : prop;\n throw new TxRefError(\n `${what} was used as a value (via \\`${name}\\`). Nothing in a transaction ` +\n `callback has run yet, so there is no value to read. ${hint}`,\n );\n}\n\n/** The server's `now()`. */\nexport function now(): TxNow {\n return makeExpr({ fn: \"now\" }) as TxNow;\n}\n\n/** Add `by` to the column's current value. Only valid in an update's `set`. */\nexport function increment(by: number | string): TxColumnExpr {\n assertAmount(by, \"increment\");\n return makeExpr({ fn: \"inc\", by }) as TxColumnExpr;\n}\n\n/**\n * `increment`'in eski adı. AYNI fabrikadır — iki uygulama değil, iki ad.\n *\n * @deprecated `increment()` kullanın; bu ad geriye dönük uyumluluk için duruyor.\n */\nexport const inc = increment;\n\n/** Subtract `by` from the column's current value. Only valid in an update's `set`. */\nexport function decrement(by: number | string): TxColumnExpr {\n assertAmount(by, \"decrement\");\n return makeExpr({ fn: \"dec\", by }) as TxColumnExpr;\n}\n\n/**\n * `decrement`'in eski adı. AYNI fabrikadır.\n *\n * @deprecated `decrement()` kullanın.\n */\nexport const dec = decrement;\n\n/**\n * Miktarın taşınabilir olduğunu doğrular.\n *\n * String kabul edilir ve KASITLIDIR (D-007): `numeric` bir kolonda miktar JS\n * `number`'a uğrarsa 0.1 + 0.2 orada 0.30000000000000004'tür ve para hesabı\n * sessizce kayar. String hem burada hem `renderValue`'da bound parametre olarak\n * taşınır — Postgres onu tam ondalık olarak okur.\n */\nfunction assertAmount(by: number | string, fn: string): void {\n if (typeof by === \"string\") {\n // Metin SQL'e girmiyor (bound parametre), ama şekli yine de doğrulanır:\n // \"abc\" bind edilirse hata Postgres'ten gelir, çağıranın diliyle değil.\n if (!/^-?\\d+(\\.\\d+)?$/.test(by)) {\n throw new TxPlanError(\n `${fn}() ondalık bir sayı metni bekliyor, \"${by}\" aldı — kabul edilen biçim: \"12\", \"-12\", \"12.50\"`,\n );\n }\n } else if (typeof by !== \"number\" || !Number.isFinite(by)) {\n // JSON has no NaN/Infinity: they would serialise to `null` and the server\n // would reject the plan with an unhelpful decode error.\n throw new TxPlanError(`${fn}() needs a finite number, got ${String(by)}`);\n }\n // NEGATİF MİKTAR REDDEDİLİR — ve bu şekil kontrolünden çok daha fazlası.\n // `decrement(\"-5\")` `SET c = c - $1` derliyordu, `$1 = -5`, yani beş EKLİYORDU.\n // FR-014'ün amiral deseninde (`where: { balance: { gte: amount } }`) miktar\n // istek gövdesinden geliyorsa `balance >= -5` her zaman doğru: hesap\n // KREDİLENDİRİLİR ve çağrı bunu 1 satırla \"başarı\" diye raporlar. Guard\n // okunduğunda işaret kontrol edilmiş gibi duruyordu (gözcü I9, ölçüldü).\n const negative = typeof by === \"string\" ? by.trimStart().startsWith(\"-\") : by < 0;\n if (negative) {\n const other = fn === \"increment\" ? \"decrement\" : \"increment\";\n throw new TxPlanError(\n `${fn}() negatif miktar almaz (\"${String(by)}\"). Ters yön için ${other}() kullanın — ` +\n `işaretin miktarda saklanması, yönü okuyan hiçbir kod tarafından görülmezdi.`,\n );\n }\n}\n\n/**\n * Bir değer `increment()`/`decrement()` ürünü mü? Öyleyse tel şekli.\n *\n * DOĞRUDAN yol (`updateMany`) da bu ifadeyi anlamak zorunda: aynı nesnenin iki\n * yerde çalışması, \"kolona ekle\"nin tek yazımı olmasının şartı (P1).\n */\nexport function columnExprOf(v: unknown): TxWireExpr[\"$expr\"] | null {\n return exprOf(v);\n}\n\nfunction makeExpr(expr: TxWireExpr[\"$expr\"]): unknown {\n return new Proxy(\n { [EXPR]: expr } as Record<string | symbol, unknown>,\n {\n get(target, prop) {\n if (prop === EXPR) return target[EXPR];\n if (TRAPPED_PROPS.includes(prop)) {\n trap(prop, \"A plan expression\", \"Write it into an operation instead.\");\n }\n return undefined;\n },\n },\n );\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — refs and row handles\n// ---------------------------------------------------------------------------\n\nfunction makeRef(op: number, field: string): unknown {\n const target: Record<string | symbol, unknown> = { [REF]: { op, field } satisfies RefDescriptor };\n return new Proxy(target, {\n get(t, prop) {\n if (prop === REF) return t[REF];\n if (TRAPPED_PROPS.includes(prop)) {\n trap(\n prop,\n `\\`${field}\\` of a row this transaction has not written yet`,\n \"Pass it to another operation in the same plan, or return it from the \" +\n \"callback and read it after `transaction()` resolves.\",\n );\n }\n return undefined;\n },\n });\n}\n\nfunction makeRowHandle(op: number): unknown {\n const target: Record<string | symbol, unknown> = { [ROW]: op };\n return new Proxy(target, {\n get(t, prop) {\n if (prop === ROW) return t[ROW];\n if (TRAPPED_PROPS.includes(prop)) {\n trap(\n prop,\n \"A row this transaction has not written yet\",\n \"Read one of its columns to reference it, or return the row from the \" +\n \"callback and read it after `transaction()` resolves.\",\n );\n }\n if (typeof prop === \"symbol\") return undefined;\n return makeRef(op, prop);\n },\n });\n}\n\nfunction refDescriptor(v: unknown): RefDescriptor | null {\n if (typeof v !== \"object\" || v === null) return null;\n const d = (v as Record<symbol, unknown>)[REF];\n return isRefDescriptor(d) ? d : null;\n}\n\nfunction isRefDescriptor(d: unknown): d is RefDescriptor {\n return (\n typeof d === \"object\" &&\n d !== null &&\n typeof (d as RefDescriptor).op === \"number\" &&\n typeof (d as RefDescriptor).field === \"string\"\n );\n}\n\nfunction rowOpIndex(v: unknown): number | null {\n if (typeof v !== \"object\" || v === null) return null;\n const op = (v as Record<symbol, unknown>)[ROW];\n return typeof op === \"number\" ? op : null;\n}\n\nfunction exprOf(v: unknown): TxWireExpr[\"$expr\"] | null {\n if (typeof v !== \"object\" || v === null) return null;\n const e = (v as Record<symbol, unknown>)[EXPR];\n return typeof e === \"object\" && e !== null ? (e as TxWireExpr[\"$expr\"]) : null;\n}\n\nfunction isRowsHandle(v: unknown): boolean {\n return typeof v === \"object\" && v !== null && (v as Record<symbol, unknown>)[ROWS] !== undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — value encoding\n// ---------------------------------------------------------------------------\n\n/**\n * Encode one value of a `values`/`set`/`where` map.\n *\n * The nesting check is not defensive tidiness. The server treats `$ref` as a\n * tagged value only at the TOP of a column's value; a ref buried inside a jsonb\n * payload is just data, and would be stored as the literal object\n * `{\"$ref\":{...}}` — a write that succeeds, commits, and is wrong. So a nested\n * handle is a hard error here, where the line that wrote it is still on the\n * stack.\n */\nfunction encodeValue(value: unknown, column: string, allowColumnExpr: boolean): TxWireValue {\n const ref = refDescriptor(value);\n if (ref) return brandRef({ $ref: { op: ref.op, field: ref.field } }, \"ref\") satisfies TxWireRef;\n\n // `now()` bir KARŞILAŞTIRMA değeri olarak geçer — sunucu saati. Diğer\n // ifadeler (increment/decrement) yazma ifadesidir ve aşağıda adıyla\n // reddediliyor. Düz op yolu ile aynı ayrım, aynı gerekçe.\n if (isNowExpr(value)) return { $expr: { fn: \"now\" } };\n const expr = exprOf(value);\n if (expr) {\n if (expr.fn !== \"now\" && !allowColumnExpr) {\n throw new TxPlanError(\n `\\`${column}\\`: ${expr.fn}() reads the column's current value, so it is ` +\n `only valid in updateWhere(where, set).`,\n );\n }\n return { $expr: expr } satisfies TxWireExpr;\n }\n\n if (rowOpIndex(value) !== null) {\n throw new TxPlanError(\n `\\`${column}\\`: a row handle is not a value. Read the column you meant ` +\n `(e.g. \\`row.id\\`).`,\n );\n }\n if (isRowsHandle(value)) {\n throw new TxPlanError(\n `\\`${column}\\`: an operation result is not a value. Declare an expectation ` +\n `first (\\`.expectOne(err)\\`) and read a column from the row.`,\n );\n }\n\n assertNoNestedHandles(value, column);\n return value;\n}\n\n/**\n * Encode a FİLTRE — `values`/`set` ile AYNI kodlayıcı değil, ve olmaması bir\n * düzeltme.\n *\n * `encodeValue` bir `$ref`'i yalnız kolonun EN ÜSTÜNDE kabul ediyor, çünkü bir\n * insert değerinin İÇİNE gömülü ref sunucuda çözülmez, literal JSON olarak\n * SAKLANIR — \"başarıyla commit olan ve yanlış olan bir yazma\". O kural DEĞER\n * yolu için doğru.\n *\n * FİLTREDE öyle değil: motorun `resolveRefsDeep`'i bir ref'i filtrenin HER\n * yerinde çözüyor — operatörün sağında, `OR`/`AND`/`NOT` dallarının içinde. Ama\n * kodlayıcı hâlâ değer kuralını uyguluyordu, yani üç katman üç farklı cevap\n * veriyordu (gözcü C-2): tip kabul, motor çözüyor, kodlayıcı REDDEDİYOR — ve\n * reddin metni değer-yuvalama vakasını anlatıyor, filtrede olmayan bir şeyi.\n *\n * İFADE TUTAMAĞI ve SATIR TUTAMAĞI filtrede HÂLÂ reddediliyor: onları motor\n * filtrede çözmüyor ve çözmemeli — `increment()` bir yazma ifadesi, bir\n * karşılaştırma değil.\n */\nfunction encodeFilterValue(value: unknown, column: string): unknown {\n const ref = refDescriptor(value);\n if (ref) return brandRef({ $ref: { op: ref.op, field: ref.field } }, \"ref\") satisfies TxWireRef;\n\n const expr = exprOf(value);\n if (expr) {\n throw new TxPlanError(\n `\\`${column}\\`: ${expr.fn}() bir YAZMA ifadesi, karşılaştırma değil — ` +\n `filtrede kullanılamaz. Kolonu bir değerle ya da col() ile karşılaştırın.`,\n );\n }\n if (rowOpIndex(value) !== null) {\n throw new TxPlanError(\n `\\`${column}\\`: a row handle is not a value. Read the column you meant (e.g. \\`row.id\\`).`,\n );\n }\n if (isRowsHandle(value)) {\n throw new TxPlanError(\n `\\`${column}\\`: an operation result is not a value. Declare an expectation ` +\n `first (\\`.expectOne(err)\\`) and read a column from the row.`,\n );\n }\n if (Array.isArray(value)) return value.map((v) => encodeFilterValue(v, column));\n // `col()` ve `sqlFragment` OLDUĞU GİBİ geçer: markaları süreç içinde korunur\n // ve derleyici ikisini de kendi tanıyor.\n if (value !== null && typeof value === \"object\" && !(value instanceof Date) && !isColRef(value) && !isSqlFragment(value)) {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n out[k] = encodeFilterValue(v, column);\n }\n return out;\n }\n return value;\n}\n\n/** Filtre haritası — anahtarlar SIRALI (aynı geri çağrı bayt-özdeş JSON üretsin). */\nfunction encodeFilterMap(map: Record<string, unknown>): Record<string, TxWireValue> {\n const out: Record<string, TxWireValue> = {};\n for (const key of Object.keys(map).sort()) {\n const value = map[key];\n if (value === undefined) continue;\n out[key] = encodeFilterValue(value, key) as TxWireValue;\n }\n return out;\n}\n\nfunction assertNoNestedHandles(value: unknown, column: string): void {\n if (typeof value !== \"object\" || value === null) return;\n if (value instanceof Date) return;\n if (refDescriptor(value) || exprOf(value) || rowOpIndex(value) !== null || isRowsHandle(value)) {\n throw new TxPlanError(\n `\\`${column}\\`: a plan handle is nested inside a value. The server would ` +\n `store it as literal JSON, not resolve it. Put the reference directly in ` +\n `the column.`,\n );\n }\n if (Array.isArray(value)) {\n for (const item of value) assertNoNestedHandles(item, column);\n return;\n }\n for (const item of Object.values(value as Record<string, unknown>)) {\n assertNoNestedHandles(item, column);\n }\n}\n\n/**\n * Encode a column map, dropping `undefined` and emitting keys SORTED.\n *\n * Sorting is what makes the same callback produce byte-identical JSON every\n * time, which is what lets the Go decoder be locked to goldens this SDK emits.\n * Dropping `undefined` mirrors what `JSON.stringify` would do anyway, but does\n * it where the resulting column list is still checkable.\n */\nfunction encodeMap(\n map: Record<string, unknown>,\n allowColumnExpr: boolean,\n): Record<string, TxWireValue> {\n const out: Record<string, TxWireValue> = {};\n for (const key of Object.keys(map).sort()) {\n const value = map[key];\n // AÇIK `undefined` REDDEDİLİR (D-017 kapandı).\n //\n // \"Kolon varsayılanını al\" demenin yolu anahtarı HİÇ KOYMAMAK; bu döngü\n // zaten yalnız var olan anahtarları geziyor, yani o niyet bozulmadan\n // çalışıyor. Ayırt edilen şey başka: anahtarın DURDUĞU ama değerinin\n // `undefined` olduğu hâl — yani `{ title: req.body.title }` gövdede\n // `title` yokken. O ölçülmüş bir olaydı: kolon sessizce yazılmadı ve\n // istek 200 döndü.\n //\n // Doğrudan yol bunu baştan beri adıyla reddediyordu; plan yolu sessizce\n // düşürüyordu. Aynı girdiye zıt iki cevap, \"tek filtre dili, tek cevap\"\n // iddiasını yazma tarafında boşa çıkarıyordu.\n if (value === undefined) {\n throw new TxPlanError(\n `${key} değeri undefined — bu bir yazma değeri değil. Anahtar duruyor ` +\n `ama değeri yok, yani kolon sessizce YAZILMAZDI (istek gövdesinden ` +\n `gelen bir alanın eksik olması bu şekilde görünür). Kolon ` +\n `varsayılanını istiyorsanız anahtarı hiç koymayın; NULL yazmak ` +\n `istiyorsanız açıkça null yazın.`,\n );\n }\n out[key] = encodeValue(value, key, allowColumnExpr);\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — the builder\n// ---------------------------------------------------------------------------\n\n/** How many rows an op can produce, as far as the CLIENT can tell before it\n * runs. Only the empty `insertMany` is knowable, and knowing it is what lets a\n * doomed expectation fail on the line that declared it. */\nconst SKIPPED_OP = -1;\n\nclass TxRowsImpl<Row> implements TxRows<Row> {\n // Present so `isRowsHandle` recognises the object; never read for its value.\n readonly [ROWS] = true;\n // Phantom: the type brand that stops a bare object passing as a TxRows. Never\n // present at run time, which is what `declare` says.\n declare readonly [rowsBrand]: Row;\n private guarded = false;\n\n constructor(\n private readonly builder: TxPlanBuilder,\n private readonly opIndex: number,\n private readonly what: string,\n ) {}\n\n // The type-level `await` guard made real: TS rejects `await rows` at compile\n // time, and reaching this means someone called `.then(...)` by hand.\n then(): never {\n throw new TxRefError(\n `${this.what} cannot be awaited: a transaction callback builds a plan, it ` +\n `does not run statements. Remove the \\`await\\`.`,\n );\n }\n\n expectOne(error: Error): TxRow<Row> {\n this.declareGuard(\"one\", 1, error);\n if (this.opIndex === SKIPPED_OP) throw error;\n return makeRowHandle(this.opIndex) as TxRow<Row>;\n }\n\n expectNone(error: Error): void {\n this.declareGuard(\"none\", 0, error);\n }\n\n expectAtLeast(n: number, error: Error): void {\n assertGuardCount(n, \"expectAtLeast\");\n this.declareGuard(\"atLeast\", n, error);\n if (this.opIndex === SKIPPED_OP && n > 0) throw error;\n }\n\n expectAtMost(n: number, error: Error): void {\n assertGuardCount(n, \"expectAtMost\");\n this.declareGuard(\"atMost\", n, error);\n }\n\n private declareGuard(kind: TxWireGuard[\"kind\"], n: number, error: Error): void {\n if (!(error instanceof Error)) {\n // The error object is the ONLY thing that describes this failure to the\n // caller — the server sends back an index, never a message.\n throw new TxPlanError(\n `${this.what}: an expectation needs the Error to throw when it does not ` +\n `hold (e.g. \\`.expect…(new Conflict(\"already accepted\"))\\`).`,\n );\n }\n if (this.guarded) {\n throw new TxPlanError(\n `${this.what} already has an expectation. One operation carries one ` +\n `expectation; declare the second one on its own operation.`,\n );\n }\n this.guarded = true;\n if (this.opIndex === SKIPPED_OP) return;\n this.builder.attachGuard(this.opIndex, kind, n, error);\n }\n}\n\nfunction assertGuardCount(n: number, fn: string): void {\n if (!Number.isInteger(n) || n < 0) {\n throw new TxPlanError(`${fn}(n) needs a non-negative integer, got ${String(n)}`);\n }\n}\n\n/** Bounds mirrored from the plan executor so an over-sized plan is named here rather\n * than rejected as an opaque 400 after it has crossed the network. */\nconst MAX_OPS = 1000;\nconst MAX_ROWS = 5000;\n\n/**\n * Accumulates ops and the client-side error table while the callback runs.\n *\n * Exported for the runtime and for tests that need the serialised plan without\n * a server; author code never sees it.\n */\nexport class TxPlanBuilder {\n private readonly ops: TxWireOp[] = [];\n /** Errors handed to expectations, indexed by the `slot` the server echoes. */\n private readonly slots: Error[] = [];\n\n /** The table surface handed to the callback. Untyped here; the public\n * `transaction()` signatures put the schema types on top. */\n table(name: string): TxTable<Record<string, unknown>, Record<string, unknown>> {\n return {\n insert: (values) => {\n const encoded = encodeMap(values as Record<string, unknown>, false);\n if (Object.keys(encoded).length === 0) {\n throw new TxPlanError(`${name}.insert() needs at least one column`);\n }\n return this.push({ op: \"insert\", table: name, values: encoded }, `${name}.insert()`);\n },\n\n put: (values, options) => {\n const encoded = encodeMap(values as Record<string, unknown>, false);\n if (Object.keys(encoded).length === 0) {\n throw new TxPlanError(`${name}.put() needs at least one column`);\n }\n if (options.onConflict.length === 0) {\n throw new TxPlanError(`${name}.put() needs at least one onConflict column`);\n }\n return this.push(\n { op: \"upsert\", table: name, values: encoded, onConflict: options.onConflict },\n `${name}.upsert()`,\n );\n },\n\n insertMany: (rows, opts) => {\n if (rows.length === 0) {\n // Nothing to write. Emitting an op would be a guaranteed 400 (the\n // server requires rows), and refusing outright would punish the\n // ordinary \"filtered every candidate out\" case.\n return new TxRowsImpl(this, SKIPPED_OP, `${name}.insertMany()`);\n }\n if (rows.length > MAX_ROWS) {\n throw new TxPlanError(\n `${name}.insertMany() has ${rows.length} rows; the limit is ${MAX_ROWS}. ` +\n `Split the write across requests.`,\n );\n }\n const encoded = rows.map((row) => encodeMap(row as Record<string, unknown>, false));\n assertUniformRows(encoded, name);\n if (opts !== undefined && opts.onConflict.length === 0) {\n throw new TxPlanError(\n `${name}.insertMany() was given a conflict action with no onConflict ` +\n `columns. Postgres matches a collision on columns, so name them.`,\n );\n }\n return this.push(\n {\n op: \"insertMany\",\n table: name,\n rows: encoded,\n // Omitted entirely when no options were given, so the op a plain\n // insertMany produces is byte-identical to the one it produced\n // before this option existed.\n ...(opts !== undefined\n ? { onConflict: opts.onConflict, action: opts.action ?? \"ignore\" }\n : {}),\n },\n `${name}.insertMany()`,\n );\n },\n\n updateWhere: (where, set) => {\n const encodedWhere = encodeFilterMap(where as Record<string, unknown>);\n const encodedSet = encodeMap(set as Record<string, unknown>, true);\n if (Object.keys(encodedWhere).length === 0) {\n throw new TxPlanError(\n `${name}.updateWhere() needs a filter. An update with no filter ` +\n `rewrites the whole table.`,\n );\n }\n if (Object.keys(encodedSet).length === 0) {\n throw new TxPlanError(`${name}.updateWhere() needs at least one column to set`);\n }\n return this.push(\n { op: \"update\", table: name, set: encodedSet, where: encodedWhere },\n `${name}.updateWhere()`,\n );\n },\n\n deleteWhere: (where) => {\n const encodedWhere = encodeFilterMap(where as Record<string, unknown>);\n if (Object.keys(encodedWhere).length === 0) {\n throw new TxPlanError(\n `${name}.deleteWhere() needs a filter. A delete with no filter empties ` +\n `the table.`,\n );\n }\n return this.push(\n { op: \"delete\", table: name, where: encodedWhere },\n `${name}.deleteWhere()`,\n );\n },\n\n select: (where, options) => {\n const op: TxWireOp = { op: \"select\", table: name };\n const encodedWhere = encodeFilterMap((where ?? {}) as Record<string, unknown>);\n if (Object.keys(encodedWhere).length > 0) op.where = encodedWhere;\n if (options?.limit !== undefined) {\n if (!Number.isInteger(options.limit) || options.limit < 0) {\n throw new TxPlanError(\n `${name}.select(): limit needs a non-negative integer, got ${String(options.limit)}`,\n );\n }\n op.limit = options.limit;\n }\n if (options?.lock !== undefined) op.lock = options.lock;\n return this.push(op, `${name}.select()`);\n },\n };\n }\n\n private push(op: TxWireOp, what: string): TxRows<Record<string, unknown>> {\n if (this.ops.length >= MAX_OPS) {\n throw new TxPlanError(\n `this transaction has ${MAX_OPS} operations, which is the limit. Use ` +\n `insertMany() for bulk writes, or split the work across requests.`,\n );\n }\n const index = this.ops.length;\n this.ops.push(op);\n return new TxRowsImpl(this, index, what);\n }\n\n /** Attach an expectation to an op and record its error in the slot table. */\n attachGuard(opIndex: number, kind: TxWireGuard[\"kind\"], n: number, error: Error): void {\n const op = this.ops[opIndex];\n // Unreachable: the index came from `push`. A loud failure beats a silently\n // unguarded write if that ever stops being true.\n if (!op) throw new TxPlanError(`internal: expectation on unknown operation ${opIndex}`);\n const slot = this.slots.length;\n this.slots.push(error);\n op.guard = { kind, n, slot };\n }\n\n /** The serialisable plan. Empty when the callback described no writes. */\n body(): TxPlanBody {\n return { ops: this.ops };\n }\n\n /** The error the server's `slot` selects, or `null` when it names one this\n * plan never declared (a server/client disagreement, not a tenant error). */\n errorForSlot(slot: number): Error | null {\n return this.slots[slot] ?? null;\n }\n}\n\nfunction assertUniformRows(rows: Record<string, TxWireValue>[], table: string): void {\n const first = rows[0];\n if (!first) return;\n const want = Object.keys(first);\n const wantKey = want.join(\",\");\n for (let i = 1; i < rows.length; i++) {\n const got = Object.keys(rows[i] as Record<string, TxWireValue>);\n if (got.join(\",\") !== wantKey) {\n // One statement, one column list. A ragged row would take the DB default\n // for the column it omitted — a write that succeeds and is wrong.\n throw new TxPlanError(\n `${table}.insertMany(): every row must set the same columns. Row 0 sets ` +\n `[${want.join(\", \")}] but row ${i} sets [${got.join(\", \")}]. ` +\n `(A property set to \\`undefined\\` counts as absent — use \\`null\\`.)`,\n );\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — materialisation\n// ---------------------------------------------------------------------------\n\n/**\n * Replace every handle in the callback's return value with what the server\n * actually produced.\n *\n * Walks arrays and PLAIN objects only. Class instances (a Date, a Zod schema, a\n * domain object) are returned untouched — recursing into them would rebuild them\n * as bare objects, and nothing inside one can be a handle that this SDK created.\n */\nexport function materializeResult(value: unknown, results: TxPlanOpResult[]): unknown {\n const ref = refDescriptor(value);\n if (ref) {\n const row = rowOf(results, ref.op, `\\`${ref.field}\\``);\n if (!(ref.field in row)) {\n throw new TxPlanError(\n `the transaction's operation ${ref.op} returned no column \\`${ref.field}\\`.`,\n );\n }\n return row[ref.field];\n }\n\n const rowOp = rowOpIndex(value);\n if (rowOp !== null) return rowOf(results, rowOp, \"a row\");\n\n if (isRowsHandle(value)) {\n throw new TxPlanError(\n \"an operation result cannot be returned from a transaction callback: its \" +\n \"row count is not known until the plan runs. Declare an expectation \" +\n \"(`.expectOne(err)`) and return the row, or a column of it.\",\n );\n }\n\n if (Array.isArray(value)) return value.map((item) => materializeResult(item, results));\n\n if (isPlainObject(value)) {\n const out: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(value)) out[key] = materializeResult(item, results);\n return out;\n }\n\n return value;\n}\n\nfunction rowOf(results: TxPlanOpResult[], opIndex: number, what: string): Record<string, unknown> {\n const result = results[opIndex];\n if (!result) {\n throw new TxPlanError(\n `the transaction returned no result for operation ${opIndex}, so ${what} ` +\n `cannot be read.`,\n );\n }\n const row = result.rows[0];\n if (!row) {\n // Unreachable through the public API: a handle only exists behind an\n // `expectOne`, and the server rolls back rather than answering 200 with a\n // guard unmet. Loud, because the alternative is `undefined` in tenant data.\n throw new TxPlanError(\n `the transaction's operation ${opIndex} returned no row, so ${what} cannot ` +\n `be read.`,\n );\n }\n return row;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== \"object\" || value === null) return false;\n const proto: unknown = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — the driver\n// ---------------------------------------------------------------------------\n\n/** What {@link runTxPlan} needs from the runtime: one call, one transaction. */\nexport interface TxPlanTransport {\n txPlan(plan: TxPlanBody): Promise<TxPlanResponse>;\n}\n\n/**\n * Build the plan, send it, and resolve the callback's return value.\n *\n * A callback that throws never reaches the network: there is nothing to roll\n * back because nothing was sent. A callback that describes no writes also skips\n * the round trip entirely.\n *\n * The RETURN type is `unknown` here on purpose. `Materialized<T>` is a compile-\n * time rewrite of the callback's return type, and it belongs on the public\n * `transaction()` signatures where `T` is inferred from the author's callback;\n * threading it through this driver as well would mean inferring `T` twice, from\n * two different positions, and reconciling them. The public wrappers narrow\n * once, at the seam where the value types were erased anyway.\n */\nexport async function runTxPlan<THandle>(\n transport: TxPlanTransport,\n // TUTAMAĞIN TAMAMI, yalnız `tables` DEĞİL. Tutamak artık şema yüzeyini de\n // taşıyor (`tx.public.x`, `tx.<şema>.x`), ve onu BURADA `{ tables }` diye\n // yeniden kurmak o yüzeyi sessizce düşürürdü.\n handle: THandle,\n builder: TxPlanBuilder,\n fn: (tx: THandle) => unknown,\n): Promise<unknown> {\n const returned = fn(handle);\n const body = builder.body();\n if (body.ops.length === 0) {\n return materializeResult(returned, []);\n }\n\n let response: TxPlanResponse;\n try {\n response = await transport.txPlan(body);\n } catch (err) {\n throw translateRejection(err, builder);\n }\n return materializeResult(returned, response.results);\n}\n\n/**\n * Turn the broker's rejection back into the tenant's own error.\n *\n * The server never sees the `Error` an expectation was given — only its slot\n * index — so this is the only place the intended error can be produced. A\n * rejection this SDK does not recognise passes through untouched: inventing an\n * error for it would hide the real failure.\n */\nfunction translateRejection(err: unknown, builder: TxPlanBuilder): unknown {\n if (typeof err !== \"object\" || err === null) return err;\n const rejection = err as TxPlanRejection;\n if (rejection.error_code !== \"tx_guard_failed\" || typeof rejection.slot !== \"number\") {\n return err;\n }\n return builder.errorForSlot(rejection.slot) ?? err;\n}\n","// The wire shape of a declared schema — what the deploy reads.\n//\n// `defineSchema(...)` produces a value full of builders and phantom types, which\n// is the right shape for authoring and the wrong shape for anything outside this\n// process. The deploy is Go: it introspects the live database, diffs it against\n// the declaration, and applies the difference. So the declaration has to leave\n// TypeScript as data, and this file is where that happens.\n//\n// It lives in the SDK because the SDK owns the DSL. The alternative — a script\n// beside the deploy that reaches into `._def` — is a second reading of a private\n// shape, and it drifts the moment a column gains a property: the DSL keeps\n// working, the emitter silently omits it, and the database is missing something\n// nobody can see in the source.\n//\n// The field names below are a CONTRACT with Go's `schema.SchemaJSON`. Renaming\n// one here without renaming it there produces a declaration that parses to\n// something emptier than it was — the failure mode being a column, a policy, or\n// a whole table that quietly never gets created.\n// Politika ifadesinin tel şekli `policy.ts`'te TEK kez bildiriliyor. İki kopya\n// olsaydı biri `exists` düğümünü alır, diğeri almaz ve fark ancak Go tarafı\n// bilmediği bir `kind` gördüğünde ortaya çıkardı.\nimport type { PolicyExpr as PolicyExprJSON } from \"./policy.js\";\nexport type { PolicyExpr as PolicyExprJSON } from \"./policy.js\";\nimport type { ColumnBuilder, ColumnDef } from \"./columns.js\";\nimport type { PolicyDef } from \"./policy.js\";\nimport type { MemoryDecl, SchemaDef, SearchDecl, TableDef } from \"./schema.js\";\n\n/** One column, flattened. Mirrors Go's `schema.ColumnJSON`. */\nexport interface ColumnJSON {\n type: string;\n nullable: boolean;\n primaryKey: boolean;\n defaultValue?: unknown;\n defaultRandom?: boolean;\n defaultNow?: boolean;\n renamedFrom?: string;\n /** See Go's `schema.ColumnJSON.Ignored` — the contraction gate's only signal. */\n ignored?: boolean;\n owns?: boolean;\n references?: { table: string; column: string };\n onDeleteAction?: string;\n /** FR-044: türev FK index'i kapatılmışsa `false`. Bildirilmemişse alan YOK. */\n index?: boolean;\n /** FR-049: kolon increment() ile güncelleniyorsa `true`. Aksi hâlde alan YOK. */\n counter?: boolean;\n enumName?: string;\n enumValues?: string[];\n unique?: boolean;\n dimensions?: number;\n}\n\n/** One RLS policy. Mirrors Go's `schema.PolicyJSON`. */\nexport interface PolicyJSON {\n name: string;\n command: string;\n roles: string[];\n /**\n * `USING (...)` — ham string (kaçış kapağı, FR-028) ya da YAPI (FR-022).\n *\n * Go tarafı ikisini de okur: string olan verbatim emit edilir, yapı olan\n * `generator.go`'da SQL'e çevrilir (C-6). Yapı hâli InitPlan sarmalamasını\n * ve `TO <rol>` daraltmasını GÜVENLE yapılabilir kılan şey — string üstünde\n * regex'le denemek yorum içindeki bir `auth.uid()`'yi de sarmalardı.\n */\n using: string | PolicyExprJSON | null;\n withCheck: string | PolicyExprJSON | null;\n permissive: boolean;\n}\n\n\n/** One table. Mirrors Go's `schema.TableJSON`. */\nexport interface TableJSON {\n /**\n * The schema this table lives in. `public` unless declared otherwise.\n *\n * The table carries it because the diff iterates over KEYS but passes the\n * VALUE around: a bare name inside a qualified key space writes the migration\n * into the wrong schema, silently.\n */\n schema: string;\n name: string;\n columns: Record<string, ColumnJSON>;\n rls: boolean;\n policies: PolicyJSON[];\n primaryKey?: string[];\n uniqueConstraints?: { name: string; columns: string[] }[];\n rawConstraints?: { name: string; up: string }[];\n checks?: { name: string; expr: string }[];\n indexes?: IndexJSON[];\n /** Canlıdan düşürülecek constraint adları (FR-008). Sıfır değerde OMIT. */\n dropConstraints?: string[];\n /** Tablo düzeyi çok sütunlu FOREIGN KEY'ler (FR-001). Sıfır değerde OMIT. */\n foreignKeys?: ForeignKeyJSON[];\n /** Koşullu FK'lar — donan demetler (FR-012). Sıfır değerde OMIT. */\n freeze?: FreezeJSON[];\n /** Guard'lar — bildirimsel kısıtın yetişemediği yazma redleri (FR-015). Sıfır değerde OMIT. */\n guards?: GuardJSON[];\n /** Bir kez koşacak veri düzeltmeleri (FR-033). Sıfır değerde OMIT. */\n backfills?: BackfillJSON[];\n /**\n * appendOnly (FR-030): tablo yalnız INSERT kabul eder. Sıfır değerde OMIT —\n * bildirmeyen tablolar wire'da bayt-aynı kalır.\n */\n appendOnly?: boolean;\n search?: SearchJSON;\n memory?: MemoryJSON;\n}\n\n/**\n * Bir index'in wire şekli — Go'nun `IndexJSON`'ıyla ALAN-ADI SÖZLEŞMESİ.\n *\n * `name` + `columns` bugünkü hâl; kalanı FR-041…043'ün taşıyıcısı. Hepsi sıfır\n * değerde OMIT edilir: bildirmeyen bir index wire'da eskisiyle bayt-aynı kalır,\n * yoksa dokunulmamış her şema diff'te değişmiş görünür ve her deploy churn üretir.\n */\nexport interface IndexJSON {\n name: string;\n /** `CREATE UNIQUE INDEX` (FR-007). Sıfır değerde OMIT. */\n unique?: boolean;\n columns: string[];\n /** Partial index koşulu (FR-042) — filtre şekli `WhereFilter` ile aynı. */\n where?: unknown;\n /** İfade index'i (FR-043), ör. `lower(email)`. `columns` ile birlikte kullanılmaz. */\n expression?: string;\n /** Kolon sırası (FR-043). */\n sort?: \"asc\" | \"desc\";\n /** NULL sırası (FR-043). */\n nulls?: \"first\" | \"last\";\n /** Covering index — `INCLUDE (...)` (FR-043). */\n include?: string[];\n}\n\n/**\n * Tablo düzeyi çok sütunlu FOREIGN KEY'in wire şekli — Go'nun `ForeignKeyJSON`'ı\n * ile ALAN-ADI SÖZLEŞMESİ (FR-001). Bir ad değişirse wire sessizce kopar.\n *\n * `onUpdate`/`onDelete`/`match` sıfır değerinde OMIT: bildirmeyen bir FK\n * Postgres'in varsayılanını (NO ACTION / MATCH SIMPLE) alır ve telde yer\n * kaplamaz (NFR-006).\n */\nexport interface ForeignKeyJSON {\n name: string;\n columns: string[];\n refTable: string;\n refColumns: string[];\n onUpdate?: string;\n onDelete?: string;\n match?: string;\n}\n\n/**\n * Koşullu FK'nın (\"donan demet\") wire şekli — Go'nun `FreezeJSON`'ı ile\n * ALAN-ADI SÖZLEŞMESİ (C-8, FR-012).\n *\n * `when` politika ifade yapısının ta kendisi — `IndexJSON.where` ile aynı\n * duruş: üçüncü bir yüklem lehçesi açmak, aynı sorunun iki yazımı demekti.\n * Alanların hiçbiri opsiyonel değil: bir freeze'in koşulu, donan sütunları ve\n * hedefi olmadan anlamı yok ve `toFreezeDef` bunları bildirim anında şart\n * koşuyor. Sıfır değerde OMIT edilen şey DİZİNİN KENDİSİ (`TableJSON.freeze`).\n */\nexport interface FreezeJSON {\n name: string;\n when: unknown;\n columns: string[];\n refTable: string;\n refColumns: string[];\n}\n\n/**\n * Bir guard'ın wire şekli — Go'nun `GuardJSON`'ı ile ALAN-ADI SÖZLEŞMESİ\n * (C-4/C-8, FR-015).\n *\n * `when` ile `exists` AYRI alanlar: Postgres bir trigger'ın `WHEN` yan\n * tümcesinde alt sorguya izin vermiyor (`cannot use subquery in trigger WHEN\n * condition`), yani çapraz satır yüklemi gövdedeki `EXISTS` bloğuna inmek\n * zorunda (FR-019). Ayrımı emitter'ın yükleme bakıp tahmin etmesi yerine wire'da\n * taşımak, o kuralı bildirimin kendi şekline yazar.\n *\n * `detail`/`hint`/`column` sıfır değerde OMIT — bildirmeyen bir guard telde yer\n * kaplamaz (NFR-006). `message` her zaman var: reddin kullanıcıya ulaşan tek\n * çıktısı o.\n */\nexport interface GuardJSON {\n name: string;\n event: string;\n when?: unknown;\n exists?: unknown;\n message: string;\n detail?: string;\n hint?: string;\n column?: string;\n}\n\n/**\n * Bir backfill'in wire şekli — Go'nun `BackfillJSON`'ı ile ALAN-ADI SÖZLEŞMESİ\n * (C-8, FR-033).\n *\n * `name` kimliğin TAMAMI: \"koştu mu\" sorusu ona göre cevaplanıyor, `sql`'e göre\n * değil. Aynı adın altında değişen bir gövde ikinci bir koşu üretmez.\n */\nexport interface BackfillJSON {\n name: string;\n sql: string;\n}\n\n/** C-11 wire şekli — Go'nun MemoryJSON'ıyla alan-adı sözleşmesi (D-019).\n * Beyansız tablolarda alan OMIT — eski şemalar bayt-aynı (NFR-B1). */\nexport interface MemoryJSON {\n from: string[];\n into: string;\n subject?: string;\n extract: { provider: string; model: string };\n}\n\n/** A whole declaration. Mirrors Go's `schema.SchemaJSON`. */\nexport interface SchemaJSON {\n tables: Record<string, TableJSON>;\n extensions: string[];\n /**\n * Every declared schema, with its HTTP reachability.\n *\n * The flag has nowhere else to live: `/v1/db` must know which schemas are\n * reachable, and introspection must know which schemas the project DECLARED —\n * a live database also contains internal module schemas that are none of the\n * diff's business.\n */\n schemas: SchemaMetaJSON[];\n}\n\nexport interface SchemaMetaJSON {\n name: string;\n exposed: boolean;\n}\n\n/** The definition behind a column, whichever side of the builder it arrives on. */\nfunction defOf(column: ColumnBuilder | ColumnDef): ColumnDef {\n return \"_def\" in column ? column._def : column;\n}\n\nfunction columnToJSON(column: ColumnBuilder | ColumnDef): ColumnJSON {\n const def = defOf(column);\n const out: ColumnJSON = {\n type: def.type,\n nullable: def.nullable,\n primaryKey: def.primaryKey,\n };\n // Every optional field is omitted rather than emitted as undefined: Go\n // distinguishes \"absent\" from \"present and empty\" on several of these, and a\n // `defaultValue: null` is a real default that says NULL.\n if (def.defaultValue !== undefined) out.defaultValue = def.defaultValue;\n if (def.defaultRandom === true) out.defaultRandom = true;\n if (def.defaultNow === true) out.defaultNow = true;\n if (def.renamedFrom !== undefined) out.renamedFrom = def.renamedFrom;\n // Go'daki schema.ColumnJSON'un aynası. `omitempty` karşılığı: yalnız TRUE ise yazılır,\n // böylece işaretsiz bir şemanın JSON'u bu alandan önceki hâliyle byte-eş kalır.\n if (def.ignored === true) out.ignored = true;\n // OWNERSHIP HAS TO CROSS THE WIRE, because the gate that enforces it is on the\n // other side. `ownedByUser()` sets `owns` on the column, and Go's\n // `validateOwnership` reads `ColumnJSON.Owns` to refuse a table that declares\n // two owners — but nothing was carrying the flag between them.\n //\n // Measured on the live cluster: a table with TWO `ownedByUser()` columns\n // pushed clean and both foreign keys landed on `auth.users` ON DELETE CASCADE.\n // The rule existed in the DSL and in the generator; the wire in between said\n // nothing, so the generator saw ZERO ownership columns and had nothing to\n // refuse. A flag with a reader and no writer is a dead wire.\n if (def.owns === true) out.owns = true;\n if (def.references !== undefined) {\n out.references = { table: def.references.table, column: def.references.column };\n }\n if (def.onDeleteAction !== undefined) out.onDeleteAction = def.onDeleteAction;\n // Yalnız `false` taşınıyor: \"bildirilmedi\" ile \"açık\" aynı şey ve wire'a\n // yazmak bildirmeyen her kolonu diff'te değişmiş gösterirdi.\n if (def.index === false) out.index = false;\n if (def.counter === true) out.counter = true;\n if (def.enumName !== undefined) out.enumName = def.enumName;\n if (def.enumValues !== undefined) out.enumValues = [...def.enumValues];\n if (def.unique === true) out.unique = true;\n if (def.dimensions !== undefined) out.dimensions = def.dimensions;\n return out;\n}\n\nfunction policyToJSON(policy: PolicyDef): PolicyJSON {\n return {\n name: policy.name,\n command: policy.command ?? \"all\",\n roles: policy.roles ? [...policy.roles] : [],\n // null rather than omitted: a policy with no USING clause is a different\n // thing from one whose clause the emitter forgot, and Go reads the\n // difference.\n using: policy.using ?? null,\n withCheck: policy.withCheck ?? null,\n permissive: policy.permissive !== false,\n };\n}\n\n/** C-4 wire şekli — Go'nun SearchJSON'ıyla ALAN ADI sözleşmesi (C-5).\n * `mode`/`chunks` yalnız yeni-biçim chunk-modunda emit edilir (D-010);\n * satır-modu ve eski biçim bayt-aynı kalır (NFR-B1). */\nexport interface SearchJSON {\n text?: { columns: string[] };\n vector?: {\n column?: string;\n metric: string;\n embed?: { provider: string; model: string; from: string[]; apiKeyName?: string; dimensions?: number; baseURL?: string };\n staleness?: \"null\" | \"keep\";\n mode?: \"row\" | \"chunks\";\n chunks?: { sizeChars?: number; overlapChars?: number };\n }[];\n /** FR-026: sorgu-yeniden-yazımı haritası — beyan yoksa OMIT (NFR-B1). */\n synonyms?: Record<string, string[]>;\n /** C-1: sonuç yeniden-sıralama beyanı — beyan yoksa OMIT. */\n /** FR-029: geçerlilik türevleri — beyan yoksa OMIT. */\n validity?: boolean;\n}\n\n/** T020 (C-1): iki biçimin de üst-düzey ortak alanları — beyan yoksa OMIT,\n * boş synonyms haritası da OMIT (NFR-B1 baytları kımıldamaz). */\nfunction commonSearchFields(search: SearchDecl, out: SearchJSON): void {\n if (search.synonyms !== undefined && Object.keys(search.synonyms).length > 0) {\n out.synonyms = Object.fromEntries(\n Object.entries(search.synonyms).map(([word, alts]) => [word, [...alts]]),\n );\n }\n if (search.validity === true) out.validity = true;\n}\n\n/** Beyanı normalize eder: vector her zaman DİZİ, metric her zaman dolu (vars. cosine),\n * authoring'deki `from`/`model` wire'da `embed` altında toplanır. Alan yoksa OMIT —\n * search'süz şema bayt-aynı kalır (NFR-006). */\nfunction searchToJSON(search: SearchDecl, vectorColumn: string | undefined): SearchJSON {\n if (search.from !== undefined && search.model !== undefined) {\n // YENİ biçim (D-007): from tek listedir — FTS'i de embed'i de besler.\n // Mod ŞEMADAN türer (D-010): tabloda vector kolonu varsa satır-modu\n // (column yazılır, mode OMIT — eski davranışla aynı wire), yoksa\n // chunk-modu (mode:\"chunks\", column yok — vektörler türev tabloda).\n const out: SearchJSON = {};\n const textCols =\n search.text === false ? undefined : Array.isArray(search.text) && search.text.length > 0 ? search.text : search.from;\n if (textCols !== undefined) out.text = { columns: [...textCols] };\n const v: NonNullable<SearchJSON[\"vector\"]>[number] = { metric: search.metric ?? \"cosine\" };\n if (vectorColumn !== undefined) v.column = vectorColumn;\n v.embed = {\n provider: search.model.provider,\n model: search.model.model,\n from: [...search.from],\n ...(search.model.apiKeyName !== undefined ? { apiKeyName: search.model.apiKeyName } : {}),\n ...(search.model.dimensions !== undefined ? { dimensions: search.model.dimensions } : {}),\n ...(search.model.baseURL !== undefined ? { baseURL: search.model.baseURL } : {}),\n };\n if (search.staleness !== undefined) v.staleness = search.staleness;\n if (vectorColumn === undefined) {\n v.mode = \"chunks\";\n if (search.chunks !== undefined) {\n const c: NonNullable<typeof v.chunks> = {};\n if (search.chunks.size !== undefined && search.chunks.size > 0) c.sizeChars = search.chunks.size;\n if (search.chunks.overlap !== undefined && search.chunks.overlap > 0) c.overlapChars = search.chunks.overlap;\n if (Object.keys(c).length > 0) v.chunks = c;\n }\n }\n out.vector = [v];\n commonSearchFields(search, out);\n return out;\n }\n const out: SearchJSON = {};\n // Eski biçimde text yalnız dizi olabilir (boolean'ı defineSchema zaten\n // reddediyor); Array.isArray hem tipi daraltır hem o sözleşmeyi belgeler.\n if (Array.isArray(search.text) && search.text.length > 0) out.text = { columns: [...search.text] };\n const legs = search.vector === undefined ? []\n : Array.isArray(search.vector) ? search.vector : [search.vector];\n if (legs.length > 0) {\n out.vector = legs.map((leg) => {\n const v: NonNullable<SearchJSON[\"vector\"]>[number] = { metric: leg.metric ?? \"cosine\" };\n if (leg.column !== undefined) v.column = leg.column;\n if (leg.staleness !== undefined) v.staleness = leg.staleness;\n if (leg.model !== undefined) {\n v.embed = {\n provider: leg.model.provider,\n model: leg.model.model,\n from: [...(leg.from ?? [])],\n ...(leg.model.apiKeyName !== undefined ? { apiKeyName: leg.model.apiKeyName } : {}),\n ...(leg.model.dimensions !== undefined ? { dimensions: leg.model.dimensions } : {}),\n ...(leg.model.baseURL !== undefined ? { baseURL: leg.model.baseURL } : {}),\n };\n }\n return v;\n });\n }\n commonSearchFields(search, out);\n return out;\n}\n\nfunction memoryToJSON(m: MemoryDecl): MemoryJSON {\n return {\n from: [...m.from],\n into: m.into,\n ...(m.subject !== undefined ? { subject: m.subject } : {}),\n extract: { provider: m.extract.provider, model: m.extract.model },\n };\n}\n\nfunction tableToJSON(table: TableDef, schemaName: string): TableJSON {\n const columns: Record<string, ColumnJSON> = {};\n for (const [name, column] of Object.entries(table.columns)) {\n columns[name] = columnToJSON(column);\n }\n\n const out: TableJSON = {\n name: table.name,\n schema: schemaName,\n columns,\n // Read, not re-derived. `defineSchema` already resolves the fail-closed\n // default (RLS on unless the author wrote `rls: false`, and forced on by any\n // policy), and a second copy of a SECURITY default is exactly the thing that\n // drifts — the direction it drifted last time was \"expose everything\", and\n // the live proof was one user reading another's rows.\n rls: table.rls,\n // KOŞAN SÜRÜMÜN SÖZÜ TELE ÇIKAR — yoksa daralma kapısı onu göremez.\n // `ColumnJSON.ignored` ile aynı sözleşme: işaretlenmemişse alan YOK.\n ...(table.ignored === true ? { ignored: true } : {}),\n policies: (table.policies ?? []).map(policyToJSON),\n };\n\n if (table.primaryKey !== undefined && table.primaryKey.length > 0) {\n out.primaryKey = [...table.primaryKey];\n }\n if (table.unique !== undefined && table.unique.length > 0) {\n out.uniqueConstraints = table.unique.map((u) => ({ name: u.name, columns: [...u.columns] }));\n }\n if (table.raw !== undefined && table.raw.length > 0) {\n out.rawConstraints = table.raw.map((r) => ({ name: r.name, up: r.up }));\n }\n if (table.checks !== undefined && table.checks.length > 0) {\n out.checks = table.checks.map((c) => ({ name: c.name, expr: c.expr }));\n }\n if (table.indexes !== undefined && table.indexes.length > 0) {\n out.indexes = table.indexes.map((i) => {\n // `columns` expression-index'te YOKTUR (ikisi birbirinin alternatifi).\n // Boş dizi ile taşınır: Go tarafı `expression` doluysa onu kullanır.\n const ix: IndexJSON = { name: i.name, columns: i.columns ? [...i.columns] : [] };\n if (i.unique === true) ix.unique = true;\n if (i.where !== undefined) ix.where = i.where;\n if (i.expression !== undefined) ix.expression = i.expression;\n if (i.sort !== undefined) ix.sort = i.sort;\n if (i.nulls !== undefined) ix.nulls = i.nulls;\n if (i.include !== undefined) ix.include = [...i.include];\n return ix;\n });\n }\n if (table.dropConstraints !== undefined && table.dropConstraints.length > 0) {\n out.dropConstraints = [...table.dropConstraints];\n }\n if (table.foreignKeys !== undefined && table.foreignKeys.length > 0) {\n out.foreignKeys = table.foreignKeys.map((fk) => {\n const j: ForeignKeyJSON = {\n name: fk.name,\n columns: [...fk.columns],\n refTable: fk.refTable,\n refColumns: [...fk.refColumns],\n };\n if (fk.onUpdate !== undefined) j.onUpdate = fk.onUpdate;\n if (fk.onDelete !== undefined) j.onDelete = fk.onDelete;\n if (fk.match !== undefined) j.match = fk.match;\n return j;\n });\n }\n if (table.freeze !== undefined && table.freeze.length > 0) {\n out.freeze = table.freeze.map((f) => ({\n name: f.name,\n when: f.when,\n columns: [...f.columns],\n refTable: f.refTable,\n refColumns: [...f.refColumns],\n }));\n }\n if (table.guards !== undefined && table.guards.length > 0) {\n out.guards = table.guards.map((g) => ({\n name: g.name,\n event: g.event,\n ...(g.when !== undefined ? { when: g.when } : {}),\n ...(g.exists !== undefined ? { exists: g.exists } : {}),\n message: g.message,\n ...(g.detail !== undefined ? { detail: g.detail } : {}),\n ...(g.hint !== undefined ? { hint: g.hint } : {}),\n ...(g.column !== undefined ? { column: g.column } : {}),\n }));\n }\n if (table.backfills !== undefined && table.backfills.length > 0) {\n out.backfills = table.backfills.map((b) => ({ name: b.name, sql: b.sql }));\n }\n // Sıfır değerde YAZILMAZ: `appendOnly: false` ile \"bildirilmemiş\" wire'da\n // ayırt edilemez olmalı, yoksa her eski şema diff'te değişmiş görünür.\n if (table.appendOnly === true) out.appendOnly = true;\n if (table.search !== undefined) {\n // D-010 mod kararının tek girdisi: tabloda dimensions'lı (vector) kolon\n // adı. Birden çoksa ilkini yazmak YANLIŞ olurdu — o durum eski biçimin\n // işidir ve yeni biçim + çoklu vector kolonu apply'da reddedilir.\n const vectorColumn = Object.entries(columns).find(([, c]) => c.dimensions !== undefined)?.[0];\n const sj = searchToJSON(table.search, vectorColumn);\n if (sj.text !== undefined || sj.vector !== undefined) out.search = sj;\n }\n if (table.memory !== undefined) {\n out.memory = memoryToJSON(table.memory);\n }\n return out;\n}\n\n/**\n * The key a table answers to in `SchemaJSON.tables`.\n *\n * A public table is BARE, anything else is schema-qualified. This is not a new\n * convention: `RefJSON.Table` already carries `auth.users`, and introspection\n * already returns a public referent bare and a non-public one qualified. Adding\n * a second key space would make two interpreters of the same database.\n */\nexport function qualifiedTableKey(schemaName: string, tableName: string): string {\n // An ABSENT schema means public, exactly as Go's `isPublicSchema` says. This\n // branch used to be missing here and present in the engine's private copy, so\n // the two writers of one rule answered DIFFERENTLY for `\"\"`: one qualified it\n // into a schema literally named the empty string, the other left it bare.\n return schemaName === \"\" || schemaName === \"public\" ? tableName : `${schemaName}.${tableName}`;\n}\n\n/**\n * Serialize declared schemas into the JSON the deploy applies.\n *\n * Takes every schema the project declares — one file per schema — because a\n * cross-schema foreign key can only be checked when both ends are in hand.\n */\nexport function toSchemaJSON(schemas: readonly SchemaDef[]): SchemaJSON {\n const tables: Record<string, TableJSON> = {};\n const extensions: string[] = [];\n const meta: SchemaMetaJSON[] = [];\n const seen = new Set<string>();\n for (const schema of schemas) {\n if (seen.has(schema.name)) {\n throw new Error(`two schemas declare the name \"${schema.name}\" — schema names must be unique`);\n }\n seen.add(schema.name);\n for (const table of Object.values(schema.tables)) {\n const json = tableToJSON(table, schema.name);\n tables[qualifiedTableKey(schema.name, json.name)] = json;\n }\n extensions.push(...(schema.extensions ?? []));\n // The schema list travels because the flag has nowhere else to live: without\n // it /v1/db cannot know which schemas are reachable over HTTP, and nothing\n // downstream can read the DECLARED schema set that introspection needs.\n meta.push({ name: schema.name, exposed: schema.exposed });\n }\n return { tables, extensions: [...new Set(extensions)], schemas: meta };\n}\n","/** A PostgreSQL isolation level supported by the explicit root transaction. */\nexport type TransactionIsolation = \"read committed\" | \"repeatable read\" | \"serializable\";\n\nexport interface AtomicOptions {\n /** Each retry opens a fresh transaction and reruns the complete callback.\n * Defaults to zero. Keep external effects outside it; persist an outbox instead. */\n retry?: number;\n isolation?: TransactionIsolation;\n readOnly?: boolean;\n /** Maximum wait for a PostgreSQL lock. Defaults to 5000 ms. */\n lockTimeoutMs?: number;\n /** PostgreSQL statement timeout; applies to every statement in this scope. */\n statementTimeoutMs?: number;\n /** Total work deadline including queueing and retries. Active Bun queries are\n * cancelled; rollback settles before release. An in-flight COMMIT is awaited. */\n timeoutMs?: number;\n signal?: AbortSignal;\n\n}\n\nexport function retryBudget(value: number | undefined): number {\n const n = value ?? 0;\n if (!Number.isInteger(n) || n < 0 || n > 10) {\n throw new Error(\"transaction retry must be an integer between 0 and 10\");\n }\n return n;\n}\n\nexport function validateAtomicOptions(options: AtomicOptions): void {\n retryBudget(options.retry);\n if (options.isolation !== undefined && ![\"read committed\", \"repeatable read\", \"serializable\"].includes(options.isolation)) {\n throw new Error(\"transaction isolation must be read committed, repeatable read or serializable\");\n }\n if (options.readOnly !== undefined && typeof options.readOnly !== \"boolean\") {\n throw new Error(\"transaction readOnly must be a boolean\");\n }\n for (const name of [\"lockTimeoutMs\", \"statementTimeoutMs\", \"timeoutMs\"] as const) {\n const n = options[name];\n if (n !== undefined && (!Number.isInteger(n) || n < 1 || n > 2_147_483_647)) {\n throw new Error(`transaction ${name} must be a positive integer in milliseconds`);\n }\n }\n if (options.signal !== undefined && (typeof options.signal.aborted !== \"boolean\" || typeof options.signal.addEventListener !== \"function\")) {\n throw new Error(\"transaction signal must be an AbortSignal\");\n }\n}\n\n/** A savepoint cannot replace the enclosing transaction's snapshot or retry COMMIT. */\nexport function assertPlanRetry(options: { retry?: number } | undefined): void {\n if (retryBudget(options?.retry) !== 0) {\n throw new Error(\n \"Database.$transaction is a savepoint plan on the request transaction and cannot retry its snapshot or COMMIT. \" +\n \"Use Database.$atomic(async tx => { ... }, { retry, isolation }) and put all decision reads and writes inside that callback.\",\n );\n }\n}\n"],"mappings":"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","names":["REF_BRAND","Symbol","for","brandRef","v","kind","Object","defineProperty","value","enumerable","brandOf","undefined","hasOwn","looksLikeUnbrandedRef","isColumnExpr","o","$col","$sql","$expr","isColRef","isPlanRef","r","$ref","op","field","looksLikeUnbrandedPlanRef","isSqlFragment","f","Array","isArray","text","values","TX_EXPR","isNowExpr","e","fn","assertNoExpressionHandles","caller","table","cols","data","c","Error","KNOWN_OPS","Set","REFUSED_OPS","eq","assertUsableFilter","where","COMPOSITES","col","cond","entries","has","branches","b","rel","inner","length","some","x","assertUsableWriteValues","TxRefError","Error","message","name","TxPlanError","EXPR","Symbol","for","REF","ROW","ROWS","TRAPPED_PROPS","toPrimitive","trap","prop","what","hint","description","String","now","makeExpr","fn","increment","by","assertAmount","inc","decrement","dec","test","Number","isFinite","negative","trimStart","startsWith","other","columnExprOf","v","exprOf","expr","Proxy","get","target","includes","undefined","makeRef","op","field","t","makeRowHandle","refDescriptor","d","isRefDescriptor","rowOpIndex","e","isRowsHandle","encodeValue","value","column","allowColumnExpr","ref","brandRef","$ref","isNowExpr","$expr","assertNoNestedHandles","encodeFilterValue","Array","isArray","map","Date","isColRef","isSqlFragment","out","k","Object","entries","encodeFilterMap","key","keys","sort","item","values","encodeMap","SKIPPED_OP","TxRowsImpl","guarded","builder","opIndex","then","expectOne","error","declareGuard","expectNone","expectAtLeast","n","assertGuardCount","expectAtMost","kind","attachGuard","isInteger","MAX_OPS","MAX_ROWS","TxPlanBuilder","ops","slots","table","insert","encoded","length","push","put","options","onConflict","insertMany","rows","opts","row","assertUniformRows","action","updateWhere","where","set","encodedWhere","encodedSet","deleteWhere","select","limit","lock","index","slot","guard","body","errorForSlot","first","want","wantKey","join","i","got","materializeResult","results","rowOf","rowOp","isPlainObject","result","proto","getPrototypeOf","prototype","runTxPlan","transport","handle","returned","response","txPlan","err","translateRejection","rejection","error_code","defOf","column","_def","columnToJSON","def","out","type","nullable","primaryKey","defaultValue","undefined","defaultRandom","defaultNow","renamedFrom","ignored","owns","references","table","onDeleteAction","index","counter","enumName","enumValues","unique","dimensions","policyToJSON","policy","name","command","roles","using","withCheck","permissive","commonSearchFields","search","synonyms","Object","keys","length","fromEntries","entries","map","word","alts","validity","searchToJSON","vectorColumn","from","model","textCols","text","Array","isArray","columns","v","metric","embed","provider","apiKeyName","baseURL","staleness","mode","chunks","c","size","sizeChars","overlap","overlapChars","vector","legs","leg","memoryToJSON","m","into","subject","extract","tableToJSON","schemaName","schema","rls","policies","uniqueConstraints","u","raw","rawConstraints","r","up","checks","expr","indexes","i","ix","where","expression","sort","nulls","include","dropConstraints","foreignKeys","fk","j","refTable","refColumns","onUpdate","onDelete","match","freeze","f","when","guards","g","event","exists","message","detail","hint","backfills","b","sql","appendOnly","find","sj","memory","qualifiedTableKey","tableName","toSchemaJSON","schemas","tables","extensions","meta","seen","Set","has","Error","add","values","json","push","exposed","retryBudget","value","n","Number","isInteger","Error","validateAtomicOptions","options","retry","isolation","undefined","includes","readOnly","name","signal","aborted","addEventListener","assertPlanRetry"]}