@fitzzero/quickdraw-core 5.1.1 → 5.1.3

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 (152) hide show
  1. package/README.md +1308 -219
  2. package/dist/{admin-DKwkIh5i.d.ts → admin-CS7JB_UH.d.ts} +2 -2
  3. package/dist/{adminSchemas-2DUA_hZ8.d.ts → adminSchemas-29cGgrg5.d.ts} +6 -4
  4. package/dist/{auth-BhWqdyb-.d.ts → auth-DtdYjrZ9.d.ts} +51 -21
  5. package/dist/{caller-CXTFswBO.d.ts → caller-BTwGl7vm.d.ts} +296 -33
  6. package/dist/chunk-2FDSKLBO.js +82 -0
  7. package/dist/chunk-2FDSKLBO.js.map +1 -0
  8. package/dist/{chunk-RT6OILOI.js → chunk-4D2DOGAW.js} +2 -14
  9. package/dist/chunk-4D2DOGAW.js.map +1 -0
  10. package/dist/{chunk-OECZPRPW.js → chunk-64I6MYBC.js} +162 -775
  11. package/dist/chunk-64I6MYBC.js.map +1 -0
  12. package/dist/chunk-7473HK24.js +17 -0
  13. package/dist/chunk-7473HK24.js.map +1 -0
  14. package/dist/chunk-7Y5ROPXL.js +33 -0
  15. package/dist/chunk-7Y5ROPXL.js.map +1 -0
  16. package/dist/chunk-A2RBQD66.js +7 -0
  17. package/dist/chunk-A2RBQD66.js.map +1 -0
  18. package/dist/chunk-AK23XSWD.js +16 -0
  19. package/dist/chunk-AK23XSWD.js.map +1 -0
  20. package/dist/chunk-ASAMUGHG.js +651 -0
  21. package/dist/chunk-ASAMUGHG.js.map +1 -0
  22. package/dist/{chunk-B2P7AZ25.js → chunk-CYE4UBOB.js} +6 -4
  23. package/dist/chunk-CYE4UBOB.js.map +1 -0
  24. package/dist/chunk-DKE6QO26.js +136 -0
  25. package/dist/chunk-DKE6QO26.js.map +1 -0
  26. package/dist/chunk-DNP65TD5.js +832 -0
  27. package/dist/chunk-DNP65TD5.js.map +1 -0
  28. package/dist/{chunk-H23KEFBA.js → chunk-DUBU3BB3.js} +30 -1
  29. package/dist/chunk-DUBU3BB3.js.map +1 -0
  30. package/dist/chunk-GYLWEJHW.js +19 -0
  31. package/dist/chunk-GYLWEJHW.js.map +1 -0
  32. package/dist/{chunk-SHEGLZEP.js → chunk-I3JCFS7H.js} +34 -13
  33. package/dist/chunk-I3JCFS7H.js.map +1 -0
  34. package/dist/{chunk-X5CWPX7H.js → chunk-IIQ3WMJK.js} +13 -2
  35. package/dist/chunk-IIQ3WMJK.js.map +1 -0
  36. package/dist/{chunk-RZTP4IEW.js → chunk-JVTONQFI.js} +6339 -4226
  37. package/dist/chunk-JVTONQFI.js.map +1 -0
  38. package/dist/{chunk-QEKVYG5F.js → chunk-KKQANRLG.js} +2 -2
  39. package/dist/chunk-KKQANRLG.js.map +1 -0
  40. package/dist/{chunk-CDKG4TFA.js → chunk-MPQAT55F.js} +38 -205
  41. package/dist/chunk-MPQAT55F.js.map +1 -0
  42. package/dist/chunk-NO4M6PO5.js +101 -0
  43. package/dist/chunk-NO4M6PO5.js.map +1 -0
  44. package/dist/{chunk-TBMKJ26R.js → chunk-NW6U45HX.js} +3 -1
  45. package/dist/chunk-NW6U45HX.js.map +1 -0
  46. package/dist/chunk-NX2V6SIL.js +202 -0
  47. package/dist/chunk-NX2V6SIL.js.map +1 -0
  48. package/dist/{chunk-ZIVPHYRG.js → chunk-NZHA4TZD.js} +72 -175
  49. package/dist/chunk-NZHA4TZD.js.map +1 -0
  50. package/dist/{chunk-2PWMUVC7.js → chunk-OCZJ4EYV.js} +518 -27
  51. package/dist/chunk-OCZJ4EYV.js.map +1 -0
  52. package/dist/{chunk-REX5YPHX.js → chunk-PHCURHC7.js} +76 -21
  53. package/dist/chunk-PHCURHC7.js.map +1 -0
  54. package/dist/{chunk-4YO5H5ON.js → chunk-Q4OGQM5I.js} +4 -10
  55. package/dist/chunk-Q4OGQM5I.js.map +1 -0
  56. package/dist/chunk-QSU47XEX.js +13 -0
  57. package/dist/chunk-QSU47XEX.js.map +1 -0
  58. package/dist/{chunk-DD4SKCNO.js → chunk-RZXJTDH5.js} +13 -2
  59. package/dist/chunk-RZXJTDH5.js.map +1 -0
  60. package/dist/{chunk-Z2LZ7IZ7.js → chunk-SN3OZVEQ.js} +5 -31
  61. package/dist/chunk-SN3OZVEQ.js.map +1 -0
  62. package/dist/{chunk-4DIQHASK.js → chunk-SQ5VUG77.js} +28 -8
  63. package/dist/chunk-SQ5VUG77.js.map +1 -0
  64. package/dist/chunk-STH5DLQP.js +1192 -0
  65. package/dist/chunk-STH5DLQP.js.map +1 -0
  66. package/dist/{chunk-QCHKWIRS.js → chunk-VZFJTKIW.js} +13 -13
  67. package/dist/{chunk-QCHKWIRS.js.map → chunk-VZFJTKIW.js.map} +1 -1
  68. package/dist/{chunk-VSQBHPWH.js → chunk-X4ZU4QH5.js} +54 -22
  69. package/dist/chunk-X4ZU4QH5.js.map +1 -0
  70. package/dist/chunk-XD7SRDUY.js +188 -0
  71. package/dist/chunk-XD7SRDUY.js.map +1 -0
  72. package/dist/chunk-XH2IZVLT.js +62 -0
  73. package/dist/chunk-XH2IZVLT.js.map +1 -0
  74. package/dist/chunk-Z7I6SONO.js +825 -0
  75. package/dist/chunk-Z7I6SONO.js.map +1 -0
  76. package/dist/cli/quickdraw-docs.js +132 -112
  77. package/dist/cli/quickdraw-docs.js.map +1 -1
  78. package/dist/client/core.d.ts +387 -0
  79. package/dist/client/core.js +109 -0
  80. package/dist/client/index.d.ts +52 -203
  81. package/dist/client/index.js +59 -218
  82. package/dist/client/index.js.map +1 -1
  83. package/dist/{clientTypes-Bc-G8n-U.d.ts → clientTypes-CUUNJwWs.d.ts} +3 -3
  84. package/dist/{connection-Cr1BU07W.d.ts → connection-2EeQ_Et0.d.ts} +22 -11
  85. package/dist/{createServer-CP9eDHZZ.d.ts → createServer-Bx5HOcYK.d.ts} +67 -17
  86. package/dist/{createTestApp-UKVGEmOf.d.ts → createTestApp-DAMANT79.d.ts} +46 -13
  87. package/dist/{envelope-Cp3YcVxC.d.ts → envelope-BMBaxppV.d.ts} +216 -10
  88. package/dist/{http-Djj2Inuu.d.ts → http-YzLAar3w.d.ts} +76 -60
  89. package/dist/index.d.ts +8 -7
  90. package/dist/index.js +82 -25
  91. package/dist/index.js.map +1 -1
  92. package/dist/{infer-Teo1xpsd.d.ts → infer-Br62cnyW.d.ts} +82 -11
  93. package/dist/logger-Yz93KzdV.d.ts +30 -0
  94. package/dist/{metrics-BdBu5o8G.d.ts → metrics-CTVpw0gu.d.ts} +2 -2
  95. package/dist/origins-kvpxnVcW.d.ts +8 -0
  96. package/dist/parser.js +2 -1
  97. package/dist/prisma/index.d.ts +14 -7
  98. package/dist/prisma/index.js +279 -70
  99. package/dist/prisma/index.js.map +1 -1
  100. package/dist/{rateLimit-ZMIZJUZF.js → rateLimit-5RKBFLUR.js} +2 -2
  101. package/dist/rateLimit-5RKBFLUR.js.map +1 -0
  102. package/dist/remote-N7OUAGOW.js +15 -0
  103. package/dist/remote-N7OUAGOW.js.map +1 -0
  104. package/dist/server/auth/index.d.ts +82 -33
  105. package/dist/server/auth/index.js +277 -270
  106. package/dist/server/auth/index.js.map +1 -1
  107. package/dist/server/express/index.d.ts +9 -2
  108. package/dist/server/express/index.js +1 -1
  109. package/dist/server/index.d.ts +268 -84
  110. package/dist/server/index.js +664 -418
  111. package/dist/server/index.js.map +1 -1
  112. package/dist/server/mcp/index.d.ts +89 -27
  113. package/dist/server/mcp/index.js +281 -62
  114. package/dist/server/mcp/index.js.map +1 -1
  115. package/dist/server/otel.d.ts +3 -3
  116. package/dist/{sharing-DVa8W-yR.d.ts → sharing-BrsmlDv_.d.ts} +3 -3
  117. package/dist/testing/client.d.ts +14 -14
  118. package/dist/testing/client.js +19 -10
  119. package/dist/testing/client.js.map +1 -1
  120. package/dist/testing/index.d.ts +50 -13
  121. package/dist/testing/index.js +113 -21
  122. package/dist/testing/index.js.map +1 -1
  123. package/dist/testing/mock.d.ts +5 -5
  124. package/dist/testing/mock.js +17 -9
  125. package/dist/tracked-BR5b2O-U.d.ts +43 -0
  126. package/dist/{types-Cu0vmx7c.d.ts → types-CLRCQGnO.d.ts} +4 -3
  127. package/dist/types-tMagHbjy.d.ts +151 -0
  128. package/dist/utils/index.d.ts +16 -4
  129. package/dist/utils/index.js +6 -3
  130. package/package.json +5 -1
  131. package/dist/chunk-2PWMUVC7.js.map +0 -1
  132. package/dist/chunk-4DIQHASK.js.map +0 -1
  133. package/dist/chunk-4YO5H5ON.js.map +0 -1
  134. package/dist/chunk-B2P7AZ25.js.map +0 -1
  135. package/dist/chunk-CDKG4TFA.js.map +0 -1
  136. package/dist/chunk-DD4SKCNO.js.map +0 -1
  137. package/dist/chunk-H23KEFBA.js.map +0 -1
  138. package/dist/chunk-OECZPRPW.js.map +0 -1
  139. package/dist/chunk-QEKVYG5F.js.map +0 -1
  140. package/dist/chunk-REX5YPHX.js.map +0 -1
  141. package/dist/chunk-RT6OILOI.js.map +0 -1
  142. package/dist/chunk-RZTP4IEW.js.map +0 -1
  143. package/dist/chunk-SHEGLZEP.js.map +0 -1
  144. package/dist/chunk-TBMKJ26R.js.map +0 -1
  145. package/dist/chunk-VSQBHPWH.js.map +0 -1
  146. package/dist/chunk-X5CWPX7H.js.map +0 -1
  147. package/dist/chunk-YSWH776Y.js +0 -13
  148. package/dist/chunk-YSWH776Y.js.map +0 -1
  149. package/dist/chunk-Z2LZ7IZ7.js.map +0 -1
  150. package/dist/chunk-ZIVPHYRG.js.map +0 -1
  151. package/dist/logger-BY28acW-.d.ts +0 -16
  152. /package/dist/{rateLimit-ZMIZJUZF.js.map → client/core.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/prisma/nested.ts","../../src/prisma/operations.ts","../../src/prisma/trackPrisma.ts"],"sourcesContent":["// Nested writes (RFC 0003 section 5.2): a `data` value that writes a related\n// row, such as `{ labels: { create: [...] } }`, reaches Prisma's query hook\n// only as the parent operation, so the related rows' writes are not tracked.\n// They are found by shape and reported as a development warning; the lint\n// rule `no-nested-write` catches them before they run.\n//\n// The check reads shapes, not the schema, so it also looks at each key's\n// value: a relation operation takes rows (an object or a list), and `delete`\n// and `disconnect` on a to-one relation take `true`. A JSON column's value\n// such as `{ create: true, update: false, delete: false }` is therefore not a\n// nested write; one whose keys hold objects still is.\n\n/** The keys of a relation operation, in the order a warning names them. */\nconst NESTED_KEYS = [\n \"create\",\n \"createMany\",\n \"connect\",\n \"connectOrCreate\",\n \"disconnect\",\n \"set\",\n \"update\",\n \"updateMany\",\n \"upsert\",\n \"delete\",\n \"deleteMany\",\n] as const;\n\n/** Relation operations that also take `true` (a to-one relation); the rest take rows. */\nconst FLAG_KEYS: ReadonlySet<string> = new Set([\"delete\", \"disconnect\"]);\n\nfunction isPlainObject(value: unknown): value is Readonly<Record<string, unknown>> {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return false;\n }\n const prototype: unknown = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\nfunction isRows(value: unknown): boolean {\n return Array.isArray(value) || isPlainObject(value);\n}\n\n/**\n * `set` also sets a scalar (`{ title: { set: \"x\" } }`) or a scalar list; on a\n * relation it takes the rows to connect, which are objects.\n */\nfunction isRelationSet(value: unknown): boolean {\n return Array.isArray(value) ? value.some(isPlainObject) : isPlainObject(value);\n}\n\n/**\n * Whether `value[key]` is a relation operation, judged by what the key\n * holds: rows (an object or a list) for every operation, `true` for\n * `delete` and `disconnect`, rows given as objects for `set`.\n */\nfunction writesRelation(value: Readonly<Record<string, unknown>>, key: string): boolean {\n if (!Object.hasOwn(value, key)) {\n return false;\n }\n const operand = value[key];\n if (key === \"set\") {\n return isRelationSet(operand);\n }\n return isRows(operand) || (FLAG_KEYS.has(key) && operand === true);\n}\n\nfunction nestedKey(value: unknown): string | undefined {\n if (!isPlainObject(value)) {\n return undefined;\n }\n return NESTED_KEYS.find((key) => writesRelation(value, key));\n}\n\n/** One nested write found in a write's `data`. */\nexport interface NestedWrite {\n /** The relation field, for example `\"labels\"`. */\n readonly field: string;\n /** The nested operation, for example `\"create\"`. */\n readonly operation: string;\n}\n\n/** The nested writes in `data`, one per relation field that has one. */\nexport function findNestedWrites(data: unknown): NestedWrite[] {\n if (!isPlainObject(data)) {\n return [];\n }\n const found: NestedWrite[] = [];\n for (const [field, value] of Object.entries(data)) {\n const operation = nestedKey(value);\n if (operation !== undefined) {\n found.push({ field, operation });\n }\n }\n return found;\n}\n","// The Prisma operation table (RFC 0003 section 5.2): for each write, how the\n// tracking hook learns the ids it touched, the fields it set, and the\n// interested columns' values before and after, and what that costs.\n//\n// | Operation | Recorded as | Ids and values from | Extra statements |\n// |---------------------|-------------|------------------------------------|------------------------------|\n// | create | create | the result | none |\n// | upsert | create, or | the result; old values from a read | one read, only when `update` |\n// | | update when | that also says the row existed | sets an interested column |\n// | | read found | | |\n// | update | update | the result; old values from a read | one read, only when `data` |\n// | | | | sets an interested column |\n// | delete | delete | the result (the deleted row) | none |\n// | createMany | create | rewritten to createManyAndReturn | none |\n// | updateMany | update | rewritten to updateManyAndReturn | as updateManyAndReturn |\n// | createManyAndReturn | create | the result | none |\n// | updateManyAndReturn | update | the result; old values from a read | one read, only when `data` |\n// | | | | sets an interested column |\n// | deleteMany | delete | a read with the same `where` | one read |\n//\n// `fields` are the keys of `data` (for upsert, of `update` when the row\n// existed, of `create` when it did not, and of both when no read told; such\n// a create is marked `mayHaveExisted`).\n// When a `select` (or `omit`) would hide the `id` or an interested column,\n// the hook adds it and strips it from the result again, so the caller gets\n// exactly what it asked for. Reads go through the open interactive\n// transaction's client, so they see its uncommitted rows. A `deleteMany`\n// with a `limit` deletes exactly the rows its read found.\n//\n// Inside an array-form `$transaction([...])` an operation cannot be replaced\n// by another one, so `createMany` and `updateMany` run as they are there:\n// `updateMany` reads its ids first, and `createMany` is tracked only when\n// every row it creates has an explicit `id`. A batch has no transaction\n// client, so every read made first there (`deleteMany`'s and `updateMany`'s\n// ids, an `update`'s old values) runs on the root client, outside the batch,\n// and misses what the batch's earlier statements changed: a development\n// warning says so once per model and operation.\n//\n// A write that certainly changed nothing records nothing (finding F7.2 of\n// the quickdraw-chat review), so no frame, delta, topic change,\n// `refreshEntry` or `affects` hop follows it. Only the write itself tells:\n//\n// - a write that matched no row (`updateMany`, `updateManyAndReturn` or\n// `deleteMany`; in a batch, an `updateMany` answering count 0);\n// - a `data` (or an upsert's `update`) with nothing to write, `{}` or only\n// `undefined` values, for which Prisma writes nothing at all.\n//\n// A write that sets a column to the value it held is recorded like any\n// other. Comparing the values the hook read before the write with the ones\n// it returned cannot tell: that read is not atomic with the write (in an\n// array-form batch it runs before the whole batch, and elsewhere another\n// write may land between the two), so a real change would be lost and its\n// subscribers left on a value the database no longer holds. rc.5 skipped\n// such writes; the final review of the release candidates showed both.\n//\n// An upsert whose `update` sets nothing changes a row only when it creates\n// one, and nothing it returns tells which it did. Its read replaces it:\n// `findUnique` with its `where` and selection answers for a row that exists\n// (one statement, as the upsert was), and only a missing row runs the upsert\n// after it, recorded as a create (one statement more). In a batch, where no\n// operation can be replaced, it is still recorded as a create that may have\n// found its row.\n\nimport { quietly } from \"../server/devWarnings\";\nimport type { WriteRecord } from \"../server/uow/types\";\nimport type { WriteTracker } from \"../server/uow/unitOfWork\";\nimport { findNestedWrites } from \"./nested\";\n\n/** A Prisma operation's arguments. */\nexport type Args = Readonly<Record<string, unknown>>;\n\n/** A row a Prisma operation returned. */\nexport type Row = Readonly<Record<string, unknown>>;\n\ntype Values = Readonly<Record<string, unknown>>;\n\n/** The model methods the hook's own queries use. */\nexport interface Delegate {\n findMany(args: Args): Promise<Row[]>;\n findUnique(args: Args): Promise<Row | null>;\n count(args: Args): Promise<number>;\n createManyAndReturn(args: Args): Promise<Row[]>;\n updateManyAndReturn(args: Args): Promise<Row[]>;\n}\n\n/** What every operation handler shares. */\nexport interface Runtime {\n readonly tracker: WriteTracker;\n /** The model's delegate on the open interactive transaction's client, or else the root client's. */\n delegate(model: string): Delegate;\n interestOf(model: string): readonly string[];\n /** Models whose writes run untracked: no usable `id` column. */\n readonly untracked: Set<string>;\n}\n\n/** One write operation, as the hook received it. */\nexport interface Operation {\n readonly runtime: Runtime;\n /** The model, named as the client names it: `\"task\"`. */\n readonly model: string;\n /** The Prisma operation: `\"deleteMany\"`. */\n readonly operation: string;\n readonly args: Args;\n readonly query: (args: Args) => Promise<unknown>;\n}\n\n/**\n * Thrown when the hook's own read failed validation before the write ran;\n * the hook then runs the write as the caller wrote it (`runUntracked`).\n */\nexport class Untrackable extends Error {\n override readonly name = \"Untrackable\";\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isValidationError(error: unknown): boolean {\n return error instanceof Error && error.name === \"PrismaClientValidationError\";\n}\n\n/** Stops tracking `model` for the life of the process, and says why once. */\nfunction untrack(op: Operation, reason: string): void {\n if (op.runtime.untracked.has(op.model)) {\n return;\n }\n op.runtime.untracked.add(op.model);\n op.runtime.tracker.logger.warn(\n `Writes to ${op.model} are not tracked: ${reason}. Tracked models need a string id column named \"id\"`,\n { category: \"quickdraw.writes\", model: op.model },\n );\n}\n\n/**\n * Runs the operation as the caller wrote it, after a query the hook built\n * failed validation (a model without an `id` column, or an interested column\n * it does not have). The hook stops tracking the model only when the\n * caller's own query then works: an error in the caller's arguments is\n * theirs, and reaches them.\n */\nexport async function runUntracked(op: Operation, reason: string): Promise<unknown> {\n const result = await op.query(op.args);\n untrack(op, reason);\n return result;\n}\n\nfunction idOf(row: Row): string | undefined {\n const { id } = row;\n if (typeof id === \"string\") {\n return id;\n }\n return typeof id === \"number\" || typeof id === \"bigint\" ? String(id) : undefined;\n}\n\nfunction pick(row: Row, columns: readonly string[]): Values | undefined {\n const present = columns.filter((column) => Object.hasOwn(row, column));\n return present.length === 0\n ? undefined\n : Object.fromEntries(present.map((column) => [column, row[column]]));\n}\n\nfunction keysOf(data: unknown): string[] {\n if (Array.isArray(data)) {\n return [...new Set(data.flatMap((item) => keysOf(item)))];\n }\n return isRecord(data) ? Object.keys(data) : [];\n}\n\nfunction rowsOf(result: unknown): Row[] {\n if (Array.isArray(result)) {\n return result.filter(isRecord);\n }\n return isRecord(result) ? [result] : [];\n}\n\n/** The keys of `data` Prisma writes: those whose value is not `undefined`. */\nfunction writtenKeys(data: unknown): string[] {\n return isRecord(data)\n ? Object.entries(data)\n .filter(([, value]) => value !== undefined)\n .map(([key]) => key)\n : [];\n}\n\n/** True for a `data` Prisma writes nothing for: an object with no key whose value is set. */\nexport function writesNothing(data: unknown): boolean {\n return isRecord(data) && writtenKeys(data).length === 0;\n}\n\n/** Counts a statement the hook runs past itself (`op.query`), and hands it to the development checks. */\nfunction countOwn(op: Operation, operation: string, args: Args): void {\n op.runtime.tracker.countStatement();\n op.runtime.tracker.observe({ model: op.model, operation, args });\n}\n\nfunction warnNested(op: Operation, data: unknown): void {\n for (const { field, operation } of findNestedWrites(data)) {\n op.runtime.tracker.warn({\n kind: \"nested-write\",\n subject: `${op.model}.${field}.${operation}`,\n message: `A nested write (${op.model}.${field}: { ${operation} }) is not tracked; only the ${op.model} row is. Write related rows through their own model`,\n meta: { model: op.model, field, operation },\n });\n }\n}\n\n/** The interested columns `data` sets. */\nfunction touchedInterest(op: Operation, data: unknown): string[] {\n const keys = new Set(keysOf(data));\n return op.runtime.interestOf(op.model).filter((column) => keys.has(column));\n}\n\n/** `args` with `columns` added to its `select`, or no longer omitted, and the columns that were added. */\nfunction widen(args: Args, columns: readonly string[]): { args: Args; added: string[] } {\n const { select, omit } = args;\n if (isRecord(select)) {\n const added = columns.filter((column) => select[column] !== true);\n const widened = { ...select, ...Object.fromEntries(added.map((column) => [column, true])) };\n return { args: added.length === 0 ? args : { ...args, select: widened }, added };\n }\n if (isRecord(omit)) {\n const added = columns.filter((column) => omit[column] === true);\n const widened = { ...omit, ...Object.fromEntries(added.map((column) => [column, false])) };\n return { args: added.length === 0 ? args : { ...args, omit: widened }, added };\n }\n return { args, added: [] };\n}\n\nfunction strip(result: unknown, added: readonly string[]): unknown {\n const without = (row: unknown): unknown =>\n isRecord(row)\n ? Object.fromEntries(Object.entries(row).filter(([key]) => !added.includes(key)))\n : row;\n return Array.isArray(result) ? result.map(without) : without(result);\n}\n\n/**\n * Runs the operation with the `id` and interested columns in its result,\n * and returns the caller's result plus the rows to record. When adding them\n * fails validation (a model without an `id` column), the operation runs as\n * the caller wrote it and its rows are not recorded.\n */\nasync function runWidened(op: Operation): Promise<{ result: unknown; rows: Row[] }> {\n const { args, added } = widen(op.args, [\"id\", ...op.runtime.interestOf(op.model)]);\n if (added.length === 0) {\n const result = await op.query(op.args);\n return { result, rows: rowsOf(result) };\n }\n let result: unknown;\n try {\n result = await op.query(args);\n } catch (error) {\n if (!isValidationError(error)) {\n throw error;\n }\n return { result: await runUntracked(op, \"selecting its id failed\"), rows: [] };\n }\n return { result: strip(result, added), rows: rowsOf(result) };\n}\n\n/**\n * Warns once per model and operation that a read made first inside an\n * array-form `$transaction` runs on the root client: an array-form batch\n * has no transaction client to read through, so the read does not see what\n * the batch's earlier statements changed.\n */\nfunction warnBatchRead(op: Operation): void {\n if (!op.runtime.tracker.inBatch()) {\n return;\n }\n op.runtime.tracker.warn({\n kind: \"batch-read\",\n subject: `${op.model}.${op.operation}`,\n message: `${op.operation} on ${op.model} inside an array-form $transaction reads its rows first on the root client, outside the batch, so rows the batch's earlier statements changed may be missed; use an interactive transaction to read inside it`,\n meta: { model: op.model, operation: op.operation },\n });\n}\n\n/**\n * Reads `columns` of the rows `where` matches, by id, through the transaction\n * when one is open. The read is the tracker's own, not the app's, so the\n * development checks of statements leave it alone.\n */\nasync function readBefore(\n op: Operation,\n where: unknown,\n columns: readonly string[],\n options: { readonly unique: boolean; readonly take?: unknown },\n): Promise<Map<string, Values>> {\n warnBatchRead(op);\n const select = Object.fromEntries([\"id\", ...columns].map((column) => [column, true]));\n const delegate = op.runtime.delegate(op.model);\n let rows: Row[];\n try {\n if (options.unique) {\n const row = await quietly(() => delegate.findUnique({ where, select }));\n rows = row === null ? [] : [row];\n } else {\n rows = await quietly(() =>\n delegate.findMany({\n where,\n select,\n ...(options.take === undefined ? {} : { take: options.take }),\n }),\n );\n }\n } catch (error) {\n if (isValidationError(error)) {\n throw new Untrackable(\"reading its id failed\", { cause: error });\n }\n throw error;\n }\n const before = new Map<string, Values>();\n for (const row of rows) {\n const id = idOf(row);\n if (id !== undefined) {\n before.set(id, pick(row, columns) ?? {});\n }\n }\n return before;\n}\n\nfunction writesOf(\n op: Operation,\n kind: WriteRecord[\"op\"],\n rows: readonly Row[],\n fields: readonly string[],\n before?: ReadonlyMap<string, Values>,\n): WriteRecord[] {\n const interest = op.runtime.interestOf(op.model);\n const writes: WriteRecord[] = [];\n for (const row of rows) {\n const id = idOf(row);\n if (id === undefined) {\n untrack(op, \"its rows have no id\");\n return [];\n }\n const values = pick(row, interest);\n const old = kind === \"delete\" ? values : before?.get(id);\n const after = kind === \"delete\" ? undefined : values;\n writes.push({\n model: op.model,\n id,\n op: kind,\n fields,\n ...(old === undefined || Object.keys(old).length === 0 ? {} : { before: old }),\n ...(after === undefined ? {} : { after }),\n });\n }\n return writes;\n}\n\nfunction record(op: Operation, writes: readonly WriteRecord[]): void {\n op.runtime.tracker.record(writes);\n}\n\nasync function create(op: Operation): Promise<unknown> {\n warnNested(op, op.args.data);\n const { result, rows } = await runWidened(op);\n record(op, writesOf(op, \"create\", rows, keysOf(op.args.data)));\n return result;\n}\n\n/** The selection of a read that returns what `args` (an upsert's) would: its `select`, `include` and `omit`. */\nfunction selectionOf(args: Args): Args {\n return Object.fromEntries(\n [\"select\", \"include\", \"omit\"]\n .filter((key) => args[key] !== undefined)\n .map((key) => [key, args[key]]),\n );\n}\n\n/**\n * An upsert whose `update` sets nothing (see the top of this file): the\n * read that tells whether its row exists takes its place, and answers it\n * when the row is there; only a missing row runs the upsert.\n */\nasync function upsertWithoutUpdate(op: Operation): Promise<unknown> {\n warnNested(op, op.args.create);\n const { args, added } = widen(op.args, [\"id\", ...op.runtime.interestOf(op.model)]);\n let found: Row | null;\n try {\n // Through the hook, which counts it as this call's one statement.\n found = await op.runtime\n .delegate(op.model)\n .findUnique({ where: op.args.where, ...selectionOf(args) });\n } catch (error) {\n if (!isValidationError(error)) {\n throw error;\n }\n // The hook counted the read that failed; the upsert runs in its place.\n return runUntracked(op, \"reading its id failed\");\n }\n if (found !== null) {\n // Prisma writes nothing to a row that exists when `update` sets nothing: no change.\n return strip(found, added);\n }\n countOwn(op, op.operation, op.args);\n const { result, rows } = await runWidened(op);\n // Created, unless another transaction created the row in between: then it may have existed.\n const writes = writesOf(op, \"create\", rows, keysOf(op.args.create));\n record(\n op,\n writes.map((write) => ({ ...write, mayHaveExisted: true as const })),\n );\n return result;\n}\n\nasync function upsert(op: Operation): Promise<unknown> {\n if (writesNothing(op.args.update) && !op.runtime.tracker.inBatch()) {\n return upsertWithoutUpdate(op);\n }\n warnNested(op, op.args.create);\n warnNested(op, op.args.update);\n const touched = touchedInterest(op, op.args.update);\n // Reading the interested columns first also tells whether the row existed.\n const before =\n touched.length === 0\n ? undefined\n : await readBefore(op, op.args.where, touched, { unique: true });\n const { result, rows } = await runWidened(op);\n if (before !== undefined && before.size > 0) {\n record(op, writesOf(op, \"update\", rows, keysOf(op.args.update), before));\n } else if (before === undefined) {\n // Nothing read: the row may have existed, and been updated.\n const writes = writesOf(op, \"create\", rows, keysOf([op.args.create, op.args.update]));\n record(\n op,\n writes.map((write) => ({ ...write, mayHaveExisted: true as const })),\n );\n } else {\n record(op, writesOf(op, \"create\", rows, keysOf(op.args.create)));\n }\n return result;\n}\n\nasync function update(op: Operation): Promise<unknown> {\n if (writesNothing(op.args.data)) {\n // Prisma only reads the row (and answers NOT_FOUND without one): nothing to record.\n return op.query(op.args);\n }\n warnNested(op, op.args.data);\n const touched = touchedInterest(op, op.args.data);\n const before =\n touched.length === 0\n ? undefined\n : await readBefore(op, op.args.where, touched, { unique: true });\n const { result, rows } = await runWidened(op);\n record(op, writesOf(op, \"update\", rows, keysOf(op.args.data), before));\n return result;\n}\n\nasync function remove(op: Operation): Promise<unknown> {\n const { result, rows } = await runWidened(op);\n record(op, writesOf(op, \"delete\", rows, []));\n return result;\n}\n\nasync function createManyAndReturn(op: Operation): Promise<unknown> {\n const { result, rows } = await runWidened(op);\n record(op, writesOf(op, \"create\", rows, keysOf(op.args.data)));\n return result;\n}\n\nasync function updateManyAndReturn(op: Operation): Promise<unknown> {\n if (writesNothing(op.args.data)) {\n // Prisma only reads the rows `where` matches: nothing to record.\n return op.query(op.args);\n }\n const touched = touchedInterest(op, op.args.data);\n const before =\n touched.length === 0\n ? undefined\n : await readBefore(op, op.args.where, touched, { unique: false });\n const { result, rows } = await runWidened(op);\n // Matching no row, it returns none, and records nothing.\n record(op, writesOf(op, \"update\", rows, keysOf(op.args.data), before));\n return result;\n}\n\n/** `createMany` inside an array-form transaction: tracked when every row names its id. */\nasync function createManyInBatch(op: Operation): Promise<unknown> {\n const items = (Array.isArray(op.args.data) ? op.args.data : [op.args.data]).filter(isRecord);\n const result = await op.query(op.args);\n const rows = items.filter((item) => idOf(item) !== undefined);\n if (rows.length === items.length) {\n record(op, writesOf(op, \"create\", rows, keysOf(op.args.data)));\n } else {\n op.runtime.tracker.warn({\n kind: \"batch-create-many\",\n subject: op.model,\n message: `createMany on ${op.model} inside an array-form $transaction cannot report the rows it created, so they are not tracked; give each row an id, or use an interactive transaction`,\n meta: { model: op.model },\n });\n }\n return result;\n}\n\n/**\n * `updateMany` inside an array-form transaction: its ids are read first,\n * before the batch runs. With a `limit`, every row the read found is\n * recorded, which may be more rows than were updated.\n */\nasync function updateManyInBatch(op: Operation): Promise<unknown> {\n if (writesNothing(op.args.data)) {\n return op.query(op.args);\n }\n const before = await readBefore(op, op.args.where, touchedInterest(op, op.args.data), {\n unique: false,\n });\n const result = await op.query(op.args);\n // Only a count comes back: 0 means it updated nothing, whatever the read found.\n if (isRecord(result) && result.count === 0) {\n return result;\n }\n const rows = [...before.keys()].map((id) => ({ id }));\n record(op, writesOf(op, \"update\", rows, keysOf(op.args.data), before));\n return result;\n}\n\n/**\n * `createMany` and `updateMany` outside a batch: the `...AndReturn` form,\n * through the transaction's client when one is open, which the hook then\n * records like any other call of it.\n */\nasync function rewrite(\n op: Operation,\n run: (delegate: Delegate, args: Args) => Promise<Row[]>,\n): Promise<unknown> {\n let rows: Row[];\n try {\n rows = await run(op.runtime.delegate(op.model), { ...op.args, select: { id: true } });\n } catch (error) {\n if (!isValidationError(error)) {\n throw error;\n }\n op.runtime.tracker.countStatement();\n return runUntracked(op, \"selecting its id failed\");\n }\n return { count: rows.length };\n}\n\nfunction createMany(op: Operation): Promise<unknown> {\n if (op.runtime.tracker.inBatch()) {\n return createManyInBatch(op);\n }\n return rewrite(op, (delegate, args) => delegate.createManyAndReturn(args));\n}\n\nfunction updateMany(op: Operation): Promise<unknown> {\n if (op.runtime.tracker.inBatch()) {\n return updateManyInBatch(op);\n }\n if (writesNothing(op.args.data)) {\n // As it is: Prisma writes nothing and answers count 0, which the rewrite would not.\n return op.query(op.args);\n }\n return rewrite(op, (delegate, args) => delegate.updateManyAndReturn(args));\n}\n\nasync function deleteMany(op: Operation): Promise<unknown> {\n const { where, limit } = op.args;\n const interest = op.runtime.interestOf(op.model);\n const before = await readBefore(op, where, interest, { unique: false, take: limit });\n const ids = [...before.keys()];\n // With a limit, which rows go is up to the database: delete the rows read.\n const args =\n limit === undefined\n ? op.args\n : { ...op.args, where: { AND: [where ?? {}, { id: { in: ids } }] } };\n const result = await op.query(args);\n const rows = ids.map((id) => ({ id, ...before.get(id) }));\n record(op, writesOf(op, \"delete\", rows, []));\n return result;\n}\n\n/**\n * The write operations the hook tracks, by Prisma operation name. Every\n * other operation passes through untouched.\n */\nexport const WRITE_OPERATIONS: Readonly<Record<string, (op: Operation) => Promise<unknown>>> =\n Object.freeze({\n create,\n upsert,\n update,\n delete: remove,\n createMany,\n createManyAndReturn,\n updateMany,\n updateManyAndReturn,\n deleteMany,\n });\n\n/**\n * Whether a tracked operation hands its work to another one, which then\n * counts the statement (`createMany` and `updateMany` outside a batch, an\n * `upsert` whose `update` sets nothing outside a batch: its read): the hook\n * counts every other operation itself.\n */\nexport function delegates(runtime: Runtime, operation: string, args: Args | undefined): boolean {\n if (runtime.tracker.inBatch()) {\n return false;\n }\n switch (operation) {\n case \"createMany\":\n return true;\n case \"updateMany\":\n return !writesNothing(args?.data);\n case \"upsert\":\n return writesNothing(args?.update);\n default:\n return false;\n }\n}\n","// `trackPrisma` (RFC 0003 sections 5.2 and 5.4): wraps an app's Prisma\n// client so every write made through it is recorded into the unit of work it\n// runs in. In 4.1 only `BaseService.create/update/delete` were observed\n// (4.1 `src/server/BaseService.ts:769-827`); a raw `prisma.task.update`\n// was invisible, and every live update needed a hand-written emit.\n//\n// Two client extensions, both public Prisma API:\n//\n// 1. a `query` hook on every operation records writes (`operations.ts`) and\n// counts statements;\n// 2. a `client` extension replaces `$transaction`, so writes inside a\n// transaction are buffered and join the unit of work only once it commits.\n// It calls the `$transaction` of the client from step 1, so the\n// transaction's client carries the hook. Transactions are found through\n// that wrapper and `AsyncLocalStorage`, never through Prisma internals.\n//\n// Make it the last extension applied: an extension added after it still\n// runs outside transactions, but not on a transaction's client.\n\nimport { consoleLogger, type Logger } from \"../contract/logger\";\nimport { quietly } from \"../server/devWarnings\";\nimport {\n createInterestRegistry,\n modelKey,\n STORAGE_KEY,\n storageOf,\n type CountArgs,\n type FindManyArgs,\n type StorageAdapter,\n} from \"../server/storage\";\nimport { createWriteTracker, type WriteTracker } from \"../server/uow/unitOfWork\";\nimport {\n delegates,\n runUntracked,\n Untrackable,\n WRITE_OPERATIONS,\n type Args,\n type Delegate,\n type Operation,\n type Runtime,\n} from \"./operations\";\n\n/** Options of {@link trackPrisma}. */\nexport interface TrackPrismaOptions {\n /**\n * Interested columns per model, whose values writes report in `before`\n * and `after`: `{ task: [\"projectId\", \"status\"] }`. The framework adds the\n * columns its collections and access policies need with\n * `storage.registerInterest`; this is for the app's own sinks.\n */\n readonly interest?: Readonly<Record<string, readonly string[]>>;\n /**\n * Receives warnings until a dispatcher is created with this client; then\n * the dispatcher's logger does. Default: the console logger.\n */\n readonly logger?: Logger;\n /**\n * Warn about writes outside any unit of work and about nested writes.\n * Default: on unless `NODE_ENV` is `\"production\"`.\n */\n readonly development?: boolean;\n}\n\n/** The part of a Prisma client `trackPrisma` relies on: client extensions. */\nexport interface PrismaClientLike {\n $extends(extension: never): unknown;\n}\n\n/** The client as `trackPrisma` calls it. */\ninterface ExtendableClient {\n $extends(extension: object): ExtendedClient;\n}\n\ninterface ExtendedClient extends ExtendableClient {\n $transaction(arg: unknown, options?: unknown): Promise<unknown>;\n}\n\n/** What a query extension's `$allOperations` hook receives. */\ninterface QueryHookArgs {\n readonly model?: string;\n readonly operation: string;\n readonly args: Args | undefined;\n readonly query: (args: Args | undefined) => Promise<unknown>;\n}\n\nfunction isClient(value: unknown): value is ExtendableClient {\n return (\n (typeof value === \"object\" || typeof value === \"function\") &&\n value !== null &&\n typeof Reflect.get(value, \"$extends\") === \"function\"\n );\n}\n\nfunction delegateOf(client: unknown, model: string): Delegate {\n const delegate: unknown =\n typeof client === \"object\" && client !== null ? Reflect.get(client, model) : undefined;\n if (typeof delegate !== \"object\" || delegate === null) {\n throw new TypeError(`The tracked Prisma client has no model \"${model}\"`);\n }\n return delegate as Delegate;\n}\n\n/** Counts one statement the hook is about to run, and hands a model's to the development checks. */\nfunction count(\n runtime: Runtime,\n model: string | undefined,\n operation: string,\n args: Args | undefined,\n): void {\n runtime.tracker.countStatement();\n if (model !== undefined) {\n runtime.tracker.observe({ model: modelKey(model), operation, args });\n }\n}\n\nfunction createHook(runtime: Runtime) {\n return async function track({ model, operation, args, query }: QueryHookArgs): Promise<unknown> {\n const handler = model === undefined ? undefined : WRITE_OPERATIONS[operation];\n if (model === undefined || handler === undefined || runtime.untracked.has(modelKey(model))) {\n count(runtime, model, operation, args);\n return query(args);\n }\n if (!delegates(runtime, operation, args)) {\n count(runtime, model, operation, args);\n }\n const op: Operation = { runtime, model: modelKey(model), operation, args: args ?? {}, query };\n try {\n return await handler(op);\n } catch (error) {\n if (error instanceof Untrackable) {\n return runUntracked(op, error.message);\n }\n throw error;\n }\n };\n}\n\n/** `$transaction`, in both forms, inside a transaction frame of the tracker. */\nasync function transaction(\n tracker: WriteTracker,\n hooked: ExtendedClient,\n arg: unknown,\n options: unknown,\n): Promise<unknown> {\n const interactive = typeof arg === \"function\";\n const frame = tracker.openTransaction(interactive ? \"interactive\" : \"batch\");\n try {\n const result = interactive\n ? await hooked.$transaction((client: unknown) => {\n frame.setClient(client);\n return frame.run(() => (arg as (client: unknown) => unknown)(client));\n }, options)\n : await frame.run(() => hooked.$transaction(arg, options));\n frame.commit();\n return result;\n } catch (error) {\n frame.rollback();\n throw error;\n }\n}\n\n/**\n * `StorageAdapter.nullable`: Prisma validates a filter against the schema\n * before sending it, and refuses `{ column: null }` on a required column. The\n * answer is kept for the life of the client: one statement per optional\n * column, none for a required one.\n */\nfunction createNullability(\n delegate: (model: string) => Delegate,\n): (model: string, column: string) => Promise<boolean> {\n const known = new Map<string, boolean>();\n return async (model, column) => {\n const key = `${modelKey(model)}\\u0000${column}`;\n const kept = known.get(key);\n if (kept !== undefined) {\n return kept;\n }\n let nullable = true;\n try {\n await quietly(() => delegate(modelKey(model)).count({ where: { [column]: null } }));\n } catch (error) {\n if (!(error instanceof Error && error.name === \"PrismaClientValidationError\")) {\n throw error;\n }\n nullable = false;\n }\n known.set(key, nullable);\n return nullable;\n };\n}\n\n/**\n * The adapter the framework reads through. Its reads are the framework's own\n * (access checks, subscriptions, flushes, kits), so the development checks\n * of statements leave them alone.\n */\nfunction createStorage(\n tracker: WriteTracker,\n interest: ReturnType<typeof createInterestRegistry>,\n delegate: (model: string) => Delegate,\n): StorageAdapter {\n return Object.freeze({\n findMany: (model: string, args: FindManyArgs = {}) =>\n quietly(() => delegate(modelKey(model)).findMany(args as Args)),\n count: (model: string, args: CountArgs = {}) =>\n quietly(() => delegate(modelKey(model)).count(args as Args)),\n onWrite: tracker.onWrite,\n countStatements: tracker.countStatements,\n registerInterest: interest.register,\n interestOf: interest.of,\n inTransaction: () => tracker.transactionClient() !== undefined || tracker.inBatch(),\n nullable: createNullability(delegate),\n unitOfWork: tracker.unitOfWork,\n });\n}\n\n/**\n * Wraps a Prisma client so the framework sees every write made through it:\n * `create`, `update`, `upsert`, `delete` and their `Many` forms, inside and\n * outside transactions. Pass the result as `db` to `initQuickdraw`'s app and\n * to `createServer`, which find its storage adapter on it (`storageOf`).\n * Nested writes, raw SQL and database cascades are not seen; record those\n * with `ctx.touch`.\n *\n * Prefer interactive transactions (`db.$transaction(async (tx) => ...)`). An\n * array-form `db.$transaction([...])` has no transaction client, so the rows\n * a `deleteMany` or `updateMany` there reads first (and an `update`'s old\n * values) are read on the root client, outside the batch: rows the batch's\n * earlier statements created or changed may be missed, and their frames\n * with them. A development warning names the model and operation once.\n *\n * @example\n * export const db = trackPrisma(new PrismaClient({ adapter }));\n * export const qd = initQuickdraw<{ db: typeof db; principal: AppPrincipal }>();\n * const server = qd.createServer({ app, services, db, auth });\n */\nexport function trackPrisma<C extends PrismaClientLike>(\n client: C,\n options: TrackPrismaOptions = {},\n): C {\n if (!isClient(client)) {\n throw new TypeError(\"trackPrisma: client must be a Prisma client\");\n }\n if (storageOf(client) !== undefined) {\n throw new TypeError(\"trackPrisma: this client is tracked already; pass the untracked client\");\n }\n const tracker = createWriteTracker({\n logger: options.logger ?? consoleLogger,\n development: options.development,\n });\n const interest = createInterestRegistry(options.interest);\n // The client with the hook; the hook's own reads use it outside transactions.\n let root: ExtendedClient | undefined;\n const delegate = (model: string): Delegate =>\n delegateOf(tracker.transactionClient() ?? root, model);\n const runtime: Runtime = { tracker, delegate, interestOf: interest.of, untracked: new Set() };\n const hooked = client.$extends({\n name: \"quickdraw-tracking\",\n query: { $allOperations: createHook(runtime) },\n });\n root = hooked;\n const tracked = hooked.$extends({\n name: \"quickdraw-transactions\",\n client: {\n $transaction: (arg: unknown, txOptions?: unknown) =>\n transaction(tracker, hooked, arg, txOptions),\n [STORAGE_KEY]: createStorage(tracker, interest, delegate),\n },\n });\n return tracked as unknown as C;\n}\n"],"mappings":"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","names":["result"]}
1
+ {"version":3,"sources":["../../src/prisma/links.ts","../../src/prisma/operations.ts","../../src/prisma/schemaText.ts","../../src/prisma/trackPrisma.ts"],"sourcesContent":["// The junction links a tracked delete of a via entry model reads first (RFC\n// 0003 sections 5.2 and 7.2; the 5.1 audit's COLL-3). A `via` collection\n// registers its junction as its entries' links (`registerLinks`); a `delete`\n// or `deleteMany` of an entry then reads the junction rows that link the\n// rows it deletes, through the open transaction, and records them in each\n// write's `links`, possibly none, so its flush tells only the scopes a\n// deleted entry was linked to. A junction the client does not have, or a\n// read that fails validation (a column it does not have), leaves the links\n// unknown, and warns once: such a delete's collections are told as for a\n// row nobody can place, and the model stays tracked.\n//\n// The links are read in a statement of their own just before the delete,\n// as `deleteMany` reads its ids: under the database's default isolation\n// (read committed), and always outside an interactive transaction, a link\n// another unit commits in between is removed by the delete's cascade\n// without being read, so the scope it put the entry in keeps the entry\n// until that scope is read again.\n\nimport { quietly } from \"../server/devWarnings\";\nimport type { WriteRecord } from \"../server/uow/types\";\nimport type { Delegate, Row, Runtime } from \"./operations\";\n\n/** Per entry id, per junction model: the junction rows linking it. */\nexport type Links = ReadonlyMap<string, Record<string, Row[]>>;\n\nconst UNREAD = new WeakMap<Runtime, Set<string>>();\n\n/** Says once per model and junction that a delete's links could not be read. */\nfunction warnUnread(runtime: Runtime, model: string, junction: string): void {\n const warned = UNREAD.get(runtime) ?? new Set<string>();\n UNREAD.set(runtime, warned);\n const key = `${model}\\u0000${junction}`;\n if (warned.has(key)) {\n return;\n }\n warned.add(key);\n runtime.tracker.logger.warn(\n `Reading the ${junction} rows that link a deleted ${model} failed, so its deletes tell every subscribed scope of its via lists, as for a row nobody can place`,\n { category: \"quickdraw.writes\", model, junction },\n );\n}\n\n/**\n * The junction rows that link each of `ids`, rows of `model` about to be\n * deleted: per id, per registered junction, possibly none. One statement\n * per junction. `undefined` when `model` has no links or `ids` is empty\n * (nothing is read), or when a read failed validation.\n */\nexport async function readLinks(\n runtime: Runtime,\n model: string,\n ids: readonly string[],\n): Promise<Links | undefined> {\n const links = runtime.linksOf(model);\n if (links.length === 0 || ids.length === 0) {\n return undefined;\n }\n const byId = new Map(\n ids.map((id) => [id, Object.fromEntries(links.map((link) => [link.model, [] as Row[]]))]),\n );\n for (const link of links) {\n const select = Object.fromEntries(\n [link.entry, ...link.columns].map((column) => [column, true]),\n );\n let delegate: Delegate;\n try {\n delegate = runtime.delegate(link.model);\n } catch {\n // A junction model the client does not have.\n warnUnread(runtime, model, link.model);\n return undefined;\n }\n let rows: Row[];\n try {\n rows = await quietly(() =>\n delegate.findMany({ where: { [link.entry]: { in: [...ids] } }, select }),\n );\n } catch (error) {\n if (error instanceof Error && error.name === \"PrismaClientValidationError\") {\n warnUnread(runtime, model, link.model);\n return undefined;\n }\n throw error;\n }\n for (const row of rows) {\n const entry = row[link.entry];\n if (typeof entry === \"string\") {\n byId.get(entry)?.[link.model]?.push(row);\n }\n }\n }\n return byId;\n}\n\n/** `writes`, each with its row's links when they were read. */\nexport function withLinks(writes: readonly WriteRecord[], links: Links | undefined): WriteRecord[] {\n return writes.map((write) => {\n const own = links?.get(write.id);\n return own === undefined ? write : { ...write, links: own };\n });\n}\n","// The Prisma operation table (RFC 0003 section 5.2): for each write, how the\n// tracking hook learns the ids it touched, the fields it set, and the\n// interested columns' values before and after, and what that costs.\n//\n// | Operation | Recorded as | Ids and values from | Extra statements |\n// |---------------------|-------------|------------------------------------|------------------------------|\n// | create | create | the result | none |\n// | upsert | create, or | the result; old values from a read | one read, only when `update` |\n// | | update when | that also says the row existed | sets an interested column or |\n// | | read found | | holds a nested write |\n// | update | update | the result; old values from a read | one read, only when `data` |\n// | | | | sets an interested column or |\n// | | | | holds a nested write |\n// | delete | delete | the result (the deleted row) | none; for a via entry model, |\n// | | | | one read per junction, and |\n// | | | | one for the id when `where` |\n// | | | | names no `id` |\n// | createMany | create | rewritten to createManyAndReturn | none |\n// | updateMany | update | rewritten to updateManyAndReturn | as updateManyAndReturn |\n// | createManyAndReturn | create | the result | none |\n// | updateManyAndReturn | update | the result; old values from a read | one read, only when `data` |\n// | | | | sets an interested column |\n// | deleteMany | delete | a read with the same `where` | one read; for a via entry |\n// | | | | model, one per junction more |\n// | | | | when the read found rows |\n//\n// A `delete` or `deleteMany` of a via entry model (one whose junction a\n// `via` collection registered: `registerLinks`) reads the junction rows that\n// link the rows it deletes first, through the open transaction, and records\n// them in each write's `links` (possibly none), so its flush tells only the\n// scopes the row was linked to (the 5.1 audit's COLL-3; `links.ts`).\n//\n// `fields` are the keys of `data` (for upsert, of `update` when the row\n// existed, of `create` when it did not, and of both when no read told; such\n// a create is marked `mayHaveExisted`). An `update` (or an upsert's\n// `update`) whose `data` holds a nested write may set a foreign key through\n// a relation (`project: { connect }`, `parent: { disconnect: true }`), which\n// its keys do not name: it reads every interested column first and lists\n// them all in `fields`, so an access change it makes is seen (the 5.1\n// audit's DATA-1). The rows the nested write itself creates, changes or\n// deletes are not seen.\n// When a `select` (or `omit`) would hide the `id` or an interested column,\n// the hook adds it and strips it from the result again, so the caller gets\n// exactly what it asked for. Reads go through the open interactive\n// transaction's client, so they see its uncommitted rows. A `deleteMany`\n// with a `limit` deletes exactly the rows its read found.\n//\n// Inside an array-form `$transaction([...])` an operation cannot be replaced\n// by another one, so `createMany` and `updateMany` run as they are there:\n// `updateMany` reads its ids first, and `createMany` is tracked only when\n// every row it creates has an explicit `id`. A batch has no transaction\n// client, so every read made first there (`deleteMany`'s and `updateMany`'s\n// ids, an `update`'s old values) runs on the root client, outside the batch,\n// and misses what the batch's earlier statements changed: a development\n// warning says so once per model and operation.\n//\n// A write that certainly changed nothing records nothing (finding F7.2 of\n// the quickdraw-chat review), so no frame, delta, topic change,\n// `refreshEntry` or `affects` hop follows it. Only the write itself tells:\n//\n// - a write that matched no row (`updateMany`, `updateManyAndReturn` or\n// `deleteMany`; in a batch, an `updateMany` answering count 0);\n// - a `data` (or an upsert's `update`) with nothing to write, `{}` or only\n// `undefined` values, for which Prisma writes nothing at all.\n//\n// A write that sets a column to the value it held is recorded like any\n// other. Comparing the values the hook read before the write with the ones\n// it returned cannot tell: that read is not atomic with the write (in an\n// array-form batch it runs before the whole batch, and elsewhere another\n// write may land between the two), so a real change would be lost and its\n// subscribers left on a value the database no longer holds. rc.5 skipped\n// such writes; the final review of the release candidates showed both.\n//\n// An upsert whose `update` sets nothing changes a row only when it creates\n// one, and nothing it returns tells which it did. Its read replaces it:\n// `findUnique` with its `where` and selection answers for a row that exists\n// (one statement, as the upsert was), and only a missing row runs the upsert\n// after it, recorded as a create (one statement more). In a batch, where no\n// operation can be replaced, it is still recorded as a create that may have\n// found its row.\n\nimport { quietly } from \"../server/devWarnings\";\nimport type { LinkInterest } from \"../server/storage\";\nimport type { WriteRecord } from \"../server/uow/types\";\nimport type { WriteTracker } from \"../server/uow/unitOfWork\";\nimport { readLinks, withLinks, type Links } from \"./links\";\nimport { findNestedWrites } from \"./nested\";\n\n/** A Prisma operation's arguments. */\nexport type Args = Readonly<Record<string, unknown>>;\n\n/** A row a Prisma operation returned. */\nexport type Row = Readonly<Record<string, unknown>>;\n\ntype Values = Readonly<Record<string, unknown>>;\n\n/** The model methods the hook's own queries use. */\nexport interface Delegate {\n findMany(args: Args): Promise<Row[]>;\n findUnique(args: Args): Promise<Row | null>;\n count(args: Args): Promise<number>;\n createManyAndReturn(args: Args): Promise<Row[]>;\n updateManyAndReturn(args: Args): Promise<Row[]>;\n}\n\n/** What every operation handler shares. */\nexport interface Runtime {\n readonly tracker: WriteTracker;\n /** The model's delegate on the open interactive transaction's client, or else the root client's. */\n delegate(model: string): Delegate;\n interestOf(model: string): readonly string[];\n /** The junctions whose links a delete of `model` reads first (`registerLinks`). */\n linksOf(model: string): readonly LinkInterest[];\n /** Models whose writes run untracked: no usable `id` column. */\n readonly untracked: Set<string>;\n}\n\n/** One write operation, as the hook received it. */\nexport interface Operation {\n readonly runtime: Runtime;\n /** The model, named as the client names it: `\"task\"`. */\n readonly model: string;\n /** The Prisma operation: `\"deleteMany\"`. */\n readonly operation: string;\n readonly args: Args;\n readonly query: (args: Args) => Promise<unknown>;\n}\n\n/**\n * Thrown when the hook's own read failed validation before the write ran;\n * the hook then runs the write as the caller wrote it (`runUntracked`).\n */\nexport class Untrackable extends Error {\n override readonly name = \"Untrackable\";\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isValidationError(error: unknown): boolean {\n return error instanceof Error && error.name === \"PrismaClientValidationError\";\n}\n\n/** Stops tracking `model` for the life of the process, and says why once. */\nfunction untrack(op: Operation, reason: string): void {\n if (op.runtime.untracked.has(op.model)) {\n return;\n }\n op.runtime.untracked.add(op.model);\n op.runtime.tracker.logger.warn(\n `Writes to ${op.model} are not tracked: ${reason}. Tracked models need a string id column named \"id\"`,\n { category: \"quickdraw.writes\", model: op.model },\n );\n}\n\n/**\n * Runs the operation as the caller wrote it, after a query the hook built\n * failed validation (a model without an `id` column, or an interested column\n * it does not have). The hook stops tracking the model only when the\n * caller's own query then works: an error in the caller's arguments is\n * theirs, and reaches them.\n */\nexport async function runUntracked(op: Operation, reason: string): Promise<unknown> {\n const result = await op.query(op.args);\n untrack(op, reason);\n return result;\n}\n\n/** A row's id as the tracker keys it: a string, or a number or bigint as a string. */\nexport function idOf(row: Row): string | undefined {\n const { id } = row;\n if (typeof id === \"string\") {\n return id;\n }\n return typeof id === \"number\" || typeof id === \"bigint\" ? String(id) : undefined;\n}\n\nfunction pick(row: Row, columns: readonly string[]): Values | undefined {\n const present = columns.filter((column) => Object.hasOwn(row, column));\n return present.length === 0\n ? undefined\n : Object.fromEntries(present.map((column) => [column, row[column]]));\n}\n\nfunction keysOf(data: unknown): string[] {\n if (Array.isArray(data)) {\n return [...new Set(data.flatMap((item) => keysOf(item)))];\n }\n return isRecord(data) ? Object.keys(data) : [];\n}\n\nfunction rowsOf(result: unknown): Row[] {\n if (Array.isArray(result)) {\n return result.filter(isRecord);\n }\n return isRecord(result) ? [result] : [];\n}\n\n/** The keys of `data` Prisma writes: those whose value is not `undefined`. */\nfunction writtenKeys(data: unknown): string[] {\n return isRecord(data)\n ? Object.entries(data)\n .filter(([, value]) => value !== undefined)\n .map(([key]) => key)\n : [];\n}\n\n/** True for a `data` Prisma writes nothing for: an object with no key whose value is set. */\nexport function writesNothing(data: unknown): boolean {\n return isRecord(data) && writtenKeys(data).length === 0;\n}\n\n/** Counts a statement the hook runs past itself (`op.query`), and hands it to the development checks. */\nfunction countOwn(op: Operation, operation: string, args: Args): void {\n op.runtime.tracker.countStatement();\n op.runtime.tracker.observe({ model: op.model, operation, args });\n}\n\n/**\n * Whether `data` holds a nested write, warning (in development) once per\n * write that the related rows are not tracked. It is found in every\n * environment: such a `data` may set a foreign key the tracker must read.\n */\nfunction warnNested(op: Operation, data: unknown): boolean {\n const nested = findNestedWrites(data);\n for (const { field, operation } of nested) {\n op.runtime.tracker.warn({\n kind: \"nested-write\",\n subject: `${op.model}.${field}.${operation}`,\n message: `A nested write (${op.model}.${field}: { ${operation} }) is not tracked: the related rows it creates, changes or deletes send no frames and revoke nothing. The ${op.model} row is tracked, and an update of it reads its access and scope columns first, so a foreign key a to-one connect or disconnect sets on it is seen. Write related rows through their own model, or set the foreign key column`,\n meta: { model: op.model, field, operation },\n });\n }\n return nested.length > 0;\n}\n\n/** The keys of `data` and `columns`, each once: the fields of a write that holds a nested write. */\nfunction withColumns(data: unknown, columns: readonly string[]): string[] {\n return [...new Set([...keysOf(data), ...columns])];\n}\n\n/** The interested columns `data` sets. */\nfunction touchedInterest(op: Operation, data: unknown): string[] {\n const keys = new Set(keysOf(data));\n return op.runtime.interestOf(op.model).filter((column) => keys.has(column));\n}\n\n/** `args` with `columns` added to its `select`, or no longer omitted, and the columns that were added. */\nfunction widen(args: Args, columns: readonly string[]): { args: Args; added: string[] } {\n const { select, omit } = args;\n if (isRecord(select)) {\n const added = columns.filter((column) => select[column] !== true);\n const widened = { ...select, ...Object.fromEntries(added.map((column) => [column, true])) };\n return { args: added.length === 0 ? args : { ...args, select: widened }, added };\n }\n if (isRecord(omit)) {\n const added = columns.filter((column) => omit[column] === true);\n const widened = { ...omit, ...Object.fromEntries(added.map((column) => [column, false])) };\n return { args: added.length === 0 ? args : { ...args, omit: widened }, added };\n }\n return { args, added: [] };\n}\n\nfunction strip(result: unknown, added: readonly string[]): unknown {\n const without = (row: unknown): unknown =>\n isRecord(row)\n ? Object.fromEntries(Object.entries(row).filter(([key]) => !added.includes(key)))\n : row;\n return Array.isArray(result) ? result.map(without) : without(result);\n}\n\n/**\n * Runs the operation with the `id` and interested columns in its result,\n * and returns the caller's result plus the rows to record. When adding them\n * fails validation (a model without an `id` column), the operation runs as\n * the caller wrote it and its rows are not recorded.\n */\nasync function runWidened(op: Operation): Promise<{ result: unknown; rows: Row[] }> {\n const { args, added } = widen(op.args, [\"id\", ...op.runtime.interestOf(op.model)]);\n if (added.length === 0) {\n const result = await op.query(op.args);\n return { result, rows: rowsOf(result) };\n }\n let result: unknown;\n try {\n result = await op.query(args);\n } catch (error) {\n if (!isValidationError(error)) {\n throw error;\n }\n return { result: await runUntracked(op, \"selecting its id failed\"), rows: [] };\n }\n return { result: strip(result, added), rows: rowsOf(result) };\n}\n\n/**\n * Warns once per model and operation that a read made first inside an\n * array-form `$transaction` runs on the root client: an array-form batch\n * has no transaction client to read through, so the read does not see what\n * the batch's earlier statements changed.\n */\nfunction warnBatchRead(op: Operation): void {\n if (!op.runtime.tracker.inBatch()) {\n return;\n }\n op.runtime.tracker.warn({\n kind: \"batch-read\",\n subject: `${op.model}.${op.operation}`,\n message: `${op.operation} on ${op.model} inside an array-form $transaction reads its rows first on the root client, outside the batch, so rows the batch's earlier statements changed may be missed; use an interactive transaction to read inside it`,\n meta: { model: op.model, operation: op.operation },\n });\n}\n\n/**\n * Reads `columns` of the rows `where` matches, by id, through the transaction\n * when one is open. The read is the tracker's own, not the app's, so the\n * development checks of statements leave it alone.\n */\nasync function readBefore(\n op: Operation,\n where: unknown,\n columns: readonly string[],\n options: { readonly unique: boolean; readonly take?: unknown },\n): Promise<Map<string, Values>> {\n warnBatchRead(op);\n const select = Object.fromEntries([\"id\", ...columns].map((column) => [column, true]));\n const delegate = op.runtime.delegate(op.model);\n let rows: Row[];\n try {\n if (options.unique) {\n const row = await quietly(() => delegate.findUnique({ where, select }));\n rows = row === null ? [] : [row];\n } else {\n rows = await quietly(() =>\n delegate.findMany({\n where,\n select,\n ...(options.take === undefined ? {} : { take: options.take }),\n }),\n );\n }\n } catch (error) {\n if (isValidationError(error)) {\n throw new Untrackable(\"reading its id failed\", { cause: error });\n }\n throw error;\n }\n const before = new Map<string, Values>();\n for (const row of rows) {\n const id = idOf(row);\n if (id !== undefined) {\n before.set(id, pick(row, columns) ?? {});\n }\n }\n return before;\n}\n\nfunction writesOf(\n op: Operation,\n kind: WriteRecord[\"op\"],\n rows: readonly Row[],\n fields: readonly string[],\n before?: ReadonlyMap<string, Values>,\n): WriteRecord[] {\n const interest = op.runtime.interestOf(op.model);\n const writes: WriteRecord[] = [];\n for (const row of rows) {\n const id = idOf(row);\n if (id === undefined) {\n untrack(op, \"its rows have no id\");\n return [];\n }\n const values = pick(row, interest);\n const old = kind === \"delete\" ? values : before?.get(id);\n const after = kind === \"delete\" ? undefined : values;\n writes.push({\n model: op.model,\n id,\n op: kind,\n fields,\n ...(old === undefined || Object.keys(old).length === 0 ? {} : { before: old }),\n ...(after === undefined ? {} : { after }),\n });\n }\n return writes;\n}\n\nfunction record(op: Operation, writes: readonly WriteRecord[]): void {\n op.runtime.tracker.record(writes);\n}\n\nasync function create(op: Operation): Promise<unknown> {\n warnNested(op, op.args.data);\n const { result, rows } = await runWidened(op);\n record(op, writesOf(op, \"create\", rows, keysOf(op.args.data)));\n return result;\n}\n\n/** The selection of a read that returns what `args` (an upsert's) would: its `select`, `include` and `omit`. */\nfunction selectionOf(args: Args): Args {\n return Object.fromEntries(\n [\"select\", \"include\", \"omit\"]\n .filter((key) => args[key] !== undefined)\n .map((key) => [key, args[key]]),\n );\n}\n\n/**\n * An upsert whose `update` sets nothing (see the top of this file): the\n * read that tells whether its row exists takes its place, and answers it\n * when the row is there; only a missing row runs the upsert.\n */\nasync function upsertWithoutUpdate(op: Operation): Promise<unknown> {\n warnNested(op, op.args.create);\n const { args, added } = widen(op.args, [\"id\", ...op.runtime.interestOf(op.model)]);\n let found: Row | null;\n try {\n // Through the hook, which counts it as this call's one statement.\n found = await op.runtime\n .delegate(op.model)\n .findUnique({ where: op.args.where, ...selectionOf(args) });\n } catch (error) {\n if (!isValidationError(error)) {\n throw error;\n }\n // The hook counted the read that failed; the upsert runs in its place.\n return runUntracked(op, \"reading its id failed\");\n }\n if (found !== null) {\n // Prisma writes nothing to a row that exists when `update` sets nothing: no change.\n return strip(found, added);\n }\n countOwn(op, op.operation, op.args);\n const { result, rows } = await runWidened(op);\n // Created, unless another transaction created the row in between: then it may have existed.\n const writes = writesOf(op, \"create\", rows, keysOf(op.args.create));\n record(\n op,\n writes.map((write) => ({ ...write, mayHaveExisted: true as const })),\n );\n return result;\n}\n\nasync function upsert(op: Operation): Promise<unknown> {\n if (writesNothing(op.args.update) && !op.runtime.tracker.inBatch()) {\n return upsertWithoutUpdate(op);\n }\n warnNested(op, op.args.create);\n // A nested write may set a foreign key through a relation: read every interested column.\n const nested = warnNested(op, op.args.update);\n const touched = nested\n ? [...op.runtime.interestOf(op.model)]\n : touchedInterest(op, op.args.update);\n // Reading the interested columns first also tells whether the row existed.\n const before =\n touched.length === 0\n ? undefined\n : await readBefore(op, op.args.where, touched, { unique: true });\n const { result, rows } = await runWidened(op);\n if (before !== undefined && before.size > 0) {\n const fields = nested ? withColumns(op.args.update, touched) : keysOf(op.args.update);\n record(op, writesOf(op, \"update\", rows, fields, before));\n } else if (before === undefined) {\n // Nothing read: the row may have existed, and been updated.\n const writes = writesOf(op, \"create\", rows, keysOf([op.args.create, op.args.update]));\n record(\n op,\n writes.map((write) => ({ ...write, mayHaveExisted: true as const })),\n );\n } else {\n record(op, writesOf(op, \"create\", rows, keysOf(op.args.create)));\n }\n return result;\n}\n\nasync function update(op: Operation): Promise<unknown> {\n if (writesNothing(op.args.data)) {\n // Prisma only reads the row (and answers NOT_FOUND without one): nothing to record.\n return op.query(op.args);\n }\n // A nested write may set a foreign key through a relation: read every interested column.\n const nested = warnNested(op, op.args.data);\n const touched = nested ? [...op.runtime.interestOf(op.model)] : touchedInterest(op, op.args.data);\n const before =\n touched.length === 0\n ? undefined\n : await readBefore(op, op.args.where, touched, { unique: true });\n const { result, rows } = await runWidened(op);\n const fields = nested ? withColumns(op.args.data, touched) : keysOf(op.args.data);\n record(op, writesOf(op, \"update\", rows, fields, before));\n return result;\n}\n\n/** The links of the row a `delete` names (`readLinks`): by its `where.id`, or a read of its id first. */\nasync function linksOfDelete(op: Operation): Promise<Links | undefined> {\n if (op.runtime.linksOf(op.model).length === 0) {\n return undefined;\n }\n warnBatchRead(op);\n const { where } = op.args;\n const ids =\n isRecord(where) && typeof where.id === \"string\"\n ? [where.id]\n : [...(await readBefore(op, where, [], { unique: true })).keys()];\n return await readLinks(op.runtime, op.model, ids);\n}\n\nasync function remove(op: Operation): Promise<unknown> {\n const links = await linksOfDelete(op);\n const { result, rows } = await runWidened(op);\n record(op, withLinks(writesOf(op, \"delete\", rows, []), links));\n return result;\n}\n\nasync function createManyAndReturn(op: Operation): Promise<unknown> {\n const { result, rows } = await runWidened(op);\n record(op, writesOf(op, \"create\", rows, keysOf(op.args.data)));\n return result;\n}\n\nasync function updateManyAndReturn(op: Operation): Promise<unknown> {\n if (writesNothing(op.args.data)) {\n // Prisma only reads the rows `where` matches: nothing to record.\n return op.query(op.args);\n }\n const touched = touchedInterest(op, op.args.data);\n const before =\n touched.length === 0\n ? undefined\n : await readBefore(op, op.args.where, touched, { unique: false });\n const { result, rows } = await runWidened(op);\n // Matching no row, it returns none, and records nothing.\n record(op, writesOf(op, \"update\", rows, keysOf(op.args.data), before));\n return result;\n}\n\n/** `createMany` inside an array-form transaction: tracked when every row names its id. */\nasync function createManyInBatch(op: Operation): Promise<unknown> {\n const items = (Array.isArray(op.args.data) ? op.args.data : [op.args.data]).filter(isRecord);\n const result = await op.query(op.args);\n const rows = items.filter((item) => idOf(item) !== undefined);\n if (rows.length === items.length) {\n record(op, writesOf(op, \"create\", rows, keysOf(op.args.data)));\n } else {\n op.runtime.tracker.warn({\n kind: \"batch-create-many\",\n subject: op.model,\n message: `createMany on ${op.model} inside an array-form $transaction cannot report the rows it created, so they are not tracked; give each row an id, or use an interactive transaction`,\n meta: { model: op.model },\n });\n }\n return result;\n}\n\n/**\n * `updateMany` inside an array-form transaction: its ids are read first,\n * before the batch runs. With a `limit`, every row the read found is\n * recorded, which may be more rows than were updated.\n */\nasync function updateManyInBatch(op: Operation): Promise<unknown> {\n if (writesNothing(op.args.data)) {\n return op.query(op.args);\n }\n const before = await readBefore(op, op.args.where, touchedInterest(op, op.args.data), {\n unique: false,\n });\n const result = await op.query(op.args);\n // Only a count comes back: 0 means it updated nothing, whatever the read found.\n if (isRecord(result) && result.count === 0) {\n return result;\n }\n const rows = [...before.keys()].map((id) => ({ id }));\n record(op, writesOf(op, \"update\", rows, keysOf(op.args.data), before));\n return result;\n}\n\n/**\n * `createMany` and `updateMany` outside a batch: the `...AndReturn` form,\n * through the transaction's client when one is open, which the hook then\n * records like any other call of it.\n */\nasync function rewrite(\n op: Operation,\n run: (delegate: Delegate, args: Args) => Promise<Row[]>,\n): Promise<unknown> {\n let rows: Row[];\n try {\n rows = await run(op.runtime.delegate(op.model), { ...op.args, select: { id: true } });\n } catch (error) {\n if (!isValidationError(error)) {\n throw error;\n }\n op.runtime.tracker.countStatement();\n return runUntracked(op, \"selecting its id failed\");\n }\n return { count: rows.length };\n}\n\nfunction createMany(op: Operation): Promise<unknown> {\n if (op.runtime.tracker.inBatch()) {\n return createManyInBatch(op);\n }\n return rewrite(op, (delegate, args) => delegate.createManyAndReturn(args));\n}\n\nfunction updateMany(op: Operation): Promise<unknown> {\n if (op.runtime.tracker.inBatch()) {\n return updateManyInBatch(op);\n }\n if (writesNothing(op.args.data)) {\n // As it is: Prisma writes nothing and answers count 0, which the rewrite would not.\n return op.query(op.args);\n }\n return rewrite(op, (delegate, args) => delegate.updateManyAndReturn(args));\n}\n\nasync function deleteMany(op: Operation): Promise<unknown> {\n const { where, limit } = op.args;\n const interest = op.runtime.interestOf(op.model);\n const before = await readBefore(op, where, interest, { unique: false, take: limit });\n const ids = [...before.keys()];\n const links = await readLinks(op.runtime, op.model, ids);\n // With a limit, which rows go is up to the database: delete the rows read.\n const args =\n limit === undefined\n ? op.args\n : { ...op.args, where: { AND: [where ?? {}, { id: { in: ids } }] } };\n const result = await op.query(args);\n const rows = ids.map((id) => ({ id, ...before.get(id) }));\n record(op, withLinks(writesOf(op, \"delete\", rows, []), links));\n return result;\n}\n\n/**\n * The write operations the hook tracks, by Prisma operation name. Every\n * other operation passes through untouched.\n */\nexport const WRITE_OPERATIONS: Readonly<Record<string, (op: Operation) => Promise<unknown>>> =\n Object.freeze({\n create,\n upsert,\n update,\n delete: remove,\n createMany,\n createManyAndReturn,\n updateMany,\n updateManyAndReturn,\n deleteMany,\n });\n\n/**\n * Whether a tracked operation hands its work to another one, which then\n * counts the statement (`createMany` and `updateMany` outside a batch, an\n * `upsert` whose `update` sets nothing outside a batch: its read): the hook\n * counts every other operation itself.\n */\nexport function delegates(runtime: Runtime, operation: string, args: Args | undefined): boolean {\n if (runtime.tracker.inBatch()) {\n return false;\n }\n switch (operation) {\n case \"createMany\":\n return true;\n case \"updateMany\":\n return !writesNothing(args?.data);\n case \"upsert\":\n return writesNothing(args?.update);\n default:\n return false;\n }\n}\n","// What a Prisma client's own schema says about its models' fields, for the\n// storage adapter's `nullable` and `trackable` (`trackPrisma.ts`). Prisma 7's\n// generated client carries the schema's text (`config.inlineSchema`), which\n// its runtime keeps on every client, extended ones included, as\n// `_engineConfig.inlineSchema`. Its runtime data model (`_runtimeDataModel`)\n// names each field's kind but not whether the field is optional, and there is\n// no runtime DMMF. Reading the text answers with no statement; the probes it\n// replaces send a filter or select Prisma refuses, which a client created\n// with `log: [\"error\"]` prints as a `prisma:error` line. Whatever the text\n// does not answer (no text, or a model or field it does not declare) is left\n// to those probes.\n//\n// Only what the answers need is read: the field lines of `model` and `view`\n// blocks (`name Type`, `Type?` optional, `Type[]` a list), the names of\n// `enum`s, and `@ignore`. Comments, block attributes (`@@id`, `@@map`) and\n// the other field attributes (`@map`, `@default`) are skipped: the answers\n// are by Prisma field name, as the probes ask.\n\nimport { modelKey } from \"../server/storage\";\n\n/** What a client's schema says, by model (either spelling) and Prisma field name. */\nexport interface PrismaSchemaFacts {\n /** Whether `column` of `model` may hold null; `undefined` when the schema does not say. */\n nullable(model: string, column: string): boolean | undefined;\n /**\n * Whether the tracker can key `model`'s rows by an `id` field: false when\n * the model has none (a composite `@@id`), true for a required `String`,\n * `Int`, `BigInt`, `Float` or enum `id`; `undefined` when the schema does\n * not say, or the answer depends on the rows (an optional `id`).\n */\n trackable(model: string): boolean | undefined;\n}\n\n/** One scalar field of a model, as its schema declares it. */\ninterface SchemaField {\n readonly type: string;\n readonly optional: boolean;\n readonly list: boolean;\n}\n\ninterface SchemaModel {\n readonly fields: ReadonlyMap<string, SchemaField>;\n readonly trackable: boolean | undefined;\n}\n\ninterface Block {\n readonly kind: string;\n readonly name: string;\n readonly lines: string[];\n}\n\n/** The runtime data model's field kinds of one model: `scalar`, `enum`, `object` (a relation). */\ntype FieldKinds = ReadonlyMap<string, string>;\n\nconst BLOCK_START = /^(\\w+)\\s+([A-Za-z_]\\w*)\\s*\\{/;\n\nconst FIELD = /^([A-Za-z_]\\w*)\\s+([A-Za-z_]\\w*)(\\([^)]*\\))?(\\[\\])?(\\?)?(?=\\s|$)/;\n\nconst IGNORED = /(?:^|\\s)@ignore(?=\\s|$|\\()/;\n\n/** The `id` types whose values the tracker keys rows by (`idOf`). */\nconst KEY_TYPES: ReadonlySet<string> = new Set([\"String\", \"Int\", \"BigInt\", \"Float\"]);\n\nconst COLUMN_KINDS: ReadonlySet<string> = new Set([\"scalar\", \"enum\"]);\n\nfunction isObject(value: unknown): value is object {\n return (typeof value === \"object\" || typeof value === \"function\") && value !== null;\n}\n\n/** `line` without its `//` or `///` comment, which never starts inside a string. */\nfunction withoutComment(line: string): string {\n let inString = false;\n for (let index = 0; index < line.length; index += 1) {\n const char = line[index];\n if (char === '\"' && line[index - 1] !== \"\\\\\") {\n inString = !inString;\n } else if (!inString && char === \"/\" && line[index + 1] === \"/\") {\n return line.slice(0, index);\n }\n }\n return line;\n}\n\n/** The schema's top-level blocks, each with its lines, comments and blank lines dropped. */\nfunction blocksOf(text: string): Block[] {\n const blocks: Block[] = [];\n let open: Block | undefined;\n for (const raw of text.split(/\\r?\\n/)) {\n const line = withoutComment(raw).trim();\n if (line === \"\") {\n continue;\n }\n if (open !== undefined) {\n if (line === \"}\") {\n open = undefined;\n } else {\n open.lines.push(line);\n }\n continue;\n }\n const start = BLOCK_START.exec(line);\n if (start !== null) {\n const block: Block = { kind: start[1] ?? \"\", name: start[2] ?? \"\", lines: [] };\n blocks.push(block);\n // `model X {}` closes on the line it opens.\n open = line.slice(start[0].length).trim() === \"}\" ? undefined : block;\n }\n }\n return blocks;\n}\n\n/** The field kinds the runtime data model lists for `model`, or `undefined`. */\nfunction kindsOf(runtimeDataModel: unknown, model: string): FieldKinds | undefined {\n const models: unknown = isObject(runtimeDataModel)\n ? Reflect.get(runtimeDataModel, \"models\")\n : undefined;\n const entry: unknown =\n isObject(models) && Object.hasOwn(models, model) ? Reflect.get(models, model) : undefined;\n const fields: unknown = isObject(entry) ? Reflect.get(entry, \"fields\") : undefined;\n if (!Array.isArray(fields)) {\n return undefined;\n }\n const kinds = new Map<string, string>();\n for (const field of fields as unknown[]) {\n const name: unknown = isObject(field) ? Reflect.get(field, \"name\") : undefined;\n const kind: unknown = isObject(field) ? Reflect.get(field, \"kind\") : undefined;\n if (typeof name === \"string\" && typeof kind === \"string\") {\n kinds.set(name, kind);\n }\n }\n return kinds;\n}\n\n/**\n * Whether the field `name` of type `type` is a column: as the runtime data\n * model says when it lists the model (a relation is `object`), else unless\n * its type names a model, view or composite type, or is `Unsupported`.\n */\nfunction isColumn(\n name: string,\n type: string,\n kinds: FieldKinds | undefined,\n records: ReadonlySet<string>,\n): boolean {\n if (kinds !== undefined) {\n return COLUMN_KINDS.has(kinds.get(name) ?? \"\");\n }\n return type !== \"Unsupported\" && !records.has(type);\n}\n\nfunction trackableOf(\n fields: ReadonlyMap<string, SchemaField>,\n kinds: FieldKinds | undefined,\n enums: ReadonlySet<string>,\n): boolean | undefined {\n const id = fields.get(\"id\");\n if (id === undefined) {\n // The runtime knows an `id` column the text did not show: let the probe say.\n return kinds !== undefined && COLUMN_KINDS.has(kinds.get(\"id\") ?? \"\") ? undefined : false;\n }\n if (id.optional || id.list) {\n return undefined;\n }\n return KEY_TYPES.has(id.type) || enums.has(id.type) ? true : undefined;\n}\n\nfunction modelOf(\n block: Block,\n kinds: FieldKinds | undefined,\n records: ReadonlySet<string>,\n enums: ReadonlySet<string>,\n): SchemaModel {\n const fields = new Map<string, SchemaField>();\n for (const line of block.lines) {\n const field = FIELD.exec(line);\n const [, name = \"\", type = \"\", , list, optional] = field ?? [];\n if (field !== null && !IGNORED.test(line) && isColumn(name, type, kinds, records)) {\n fields.set(name, { type, optional: optional !== undefined, list: list !== undefined });\n }\n }\n return { fields, trackable: trackableOf(fields, kinds, enums) };\n}\n\n/**\n * Reads a Prisma schema's text: what each model's fields say about null, and\n * whether the model has an `id` the tracker can key. A relation field is not\n * a column: the runtime data model's kinds say so when given (a client's\n * `_runtimeDataModel`), else a field whose type is a model. A model the text\n * does not declare, or marks `@@ignore`, is not answered.\n */\nexport function parsePrismaSchema(text: string, runtimeDataModel?: unknown): PrismaSchemaFacts {\n const blocks = blocksOf(text);\n const named = (...kinds: string[]): Set<string> =>\n new Set(blocks.filter((block) => kinds.includes(block.kind)).map((block) => block.name));\n const enums = named(\"enum\");\n const records = named(\"model\", \"view\", \"type\");\n const models = new Map<string, SchemaModel>();\n for (const block of blocks) {\n const ignored = block.lines.some((line) => /^@@ignore\\b/.test(line));\n if ((block.kind === \"model\" || block.kind === \"view\") && !ignored) {\n const kinds = kindsOf(runtimeDataModel, block.name);\n models.set(modelKey(block.name), modelOf(block, kinds, records, enums));\n }\n }\n return Object.freeze({\n nullable(model: string, column: string): boolean | undefined {\n const field = models.get(modelKey(model))?.fields.get(column);\n return field === undefined ? undefined : field.optional && !field.list;\n },\n trackable: (model: string): boolean | undefined => models.get(modelKey(model))?.trackable,\n });\n}\n\n/**\n * The schema text a Prisma client carries (`_engineConfig.inlineSchema`, on\n * an extended client too), or `undefined`. Never throws.\n */\nexport function schemaTextOf(client: unknown): string | undefined {\n try {\n const config: unknown = isObject(client) ? Reflect.get(client, \"_engineConfig\") : undefined;\n const text: unknown = isObject(config) ? Reflect.get(config, \"inlineSchema\") : undefined;\n return typeof text === \"string\" && text !== \"\" ? text : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** The runtime data model a Prisma client carries, or `undefined`. Never throws. */\nfunction runtimeDataModelOf(client: unknown): unknown {\n try {\n const own: unknown = isObject(client) ? Reflect.get(client, \"_runtimeDataModel\") : undefined;\n if (own !== undefined) {\n return own;\n }\n const config: unknown = isObject(client) ? Reflect.get(client, \"_engineConfig\") : undefined;\n return isObject(config) ? Reflect.get(config, \"runtimeDataModel\") : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** What `client`'s own schema says, or `undefined` when it carries no schema text. */\nexport function prismaSchemaOf(client: unknown): PrismaSchemaFacts | undefined {\n const text = schemaTextOf(client);\n return text === undefined ? undefined : parsePrismaSchema(text, runtimeDataModelOf(client));\n}\n","// `trackPrisma` (RFC 0003 sections 5.2 and 5.4): wraps an app's Prisma\n// client so every write made through it is recorded into the unit of work it\n// runs in. In 4.1 only `BaseService.create/update/delete` were observed\n// (4.1 `src/server/BaseService.ts:769-827`); a raw `prisma.task.update`\n// was invisible, and every live update needed a hand-written emit.\n//\n// Two client extensions, both public Prisma API:\n//\n// 1. a `query` hook on every operation records writes (`operations.ts`) and\n// counts statements;\n// 2. a `client` extension replaces `$transaction`, so writes inside a\n// transaction are buffered and join the unit of work only once it commits.\n// It calls the `$transaction` of the client from step 1, so the\n// transaction's client carries the hook. Transactions are found through\n// that wrapper and `AsyncLocalStorage`, never through Prisma internals.\n//\n// Make it the last extension applied: an extension added after it still\n// runs outside transactions, but not on a transaction's client.\n//\n// The storage adapter's `nullable` and `trackable` read the one Prisma\n// internal used here, the schema text the client keeps\n// (`_engineConfig.inlineSchema`, `schemaText.ts`). Without it they ask the\n// database, as before: a statement Prisma refuses, which it logs as an error.\n\nimport { consoleLogger, type Logger } from \"../contract/logger\";\nimport { quietly } from \"../server/devWarnings\";\nimport {\n createInterestRegistry,\n createLinkRegistry,\n modelKey,\n STORAGE_KEY,\n storageOf,\n type CountArgs,\n type FindManyArgs,\n type StorageAdapter,\n} from \"../server/storage\";\nimport { createWriteTracker, type WriteTracker } from \"../server/uow/unitOfWork\";\nimport {\n delegates,\n idOf,\n runUntracked,\n Untrackable,\n WRITE_OPERATIONS,\n type Args,\n type Delegate,\n type Operation,\n type Runtime,\n} from \"./operations\";\nimport { prismaSchemaOf, type PrismaSchemaFacts } from \"./schemaText\";\nimport type { Tracked } from \"./tracked\";\n\n/** Options of {@link trackPrisma}. */\nexport interface TrackPrismaOptions {\n /**\n * Interested columns per model, whose values writes report in `before`\n * and `after`: `{ task: [\"projectId\", \"status\"] }`. The framework adds the\n * columns its collections and access policies need with\n * `storage.registerInterest`; this is for the app's own sinks.\n */\n readonly interest?: Readonly<Record<string, readonly string[]>>;\n /**\n * Receives warnings until a dispatcher is created with this client; then\n * the dispatcher's logger does. Default: the console logger.\n */\n readonly logger?: Logger;\n /**\n * Warn about writes outside any unit of work and about nested writes.\n * Default: on unless `NODE_ENV` is `\"production\"`.\n */\n readonly development?: boolean;\n}\n\n/** The part of a Prisma client `trackPrisma` relies on: client extensions. */\nexport interface PrismaClientLike {\n $extends(extension: never): unknown;\n}\n\n/** The client as `trackPrisma` calls it. */\ninterface ExtendableClient {\n $extends(extension: object): ExtendedClient;\n}\n\ninterface ExtendedClient extends ExtendableClient {\n $transaction(arg: unknown, options?: unknown): Promise<unknown>;\n}\n\n/** What a query extension's `$allOperations` hook receives. */\ninterface QueryHookArgs {\n readonly model?: string;\n readonly operation: string;\n readonly args: Args | undefined;\n readonly query: (args: Args | undefined) => Promise<unknown>;\n}\n\nfunction isClient(value: unknown): value is ExtendableClient {\n return (\n (typeof value === \"object\" || typeof value === \"function\") &&\n value !== null &&\n typeof Reflect.get(value, \"$extends\") === \"function\"\n );\n}\n\nfunction delegateOf(client: unknown, model: string): Delegate {\n const delegate: unknown =\n typeof client === \"object\" && client !== null ? Reflect.get(client, model) : undefined;\n if (typeof delegate !== \"object\" || delegate === null) {\n throw new TypeError(`The tracked Prisma client has no model \"${model}\"`);\n }\n return delegate as Delegate;\n}\n\n/** Counts one statement the hook is about to run, and hands a model's to the development checks. */\nfunction count(\n runtime: Runtime,\n model: string | undefined,\n operation: string,\n args: Args | undefined,\n): void {\n runtime.tracker.countStatement();\n if (model !== undefined) {\n runtime.tracker.observe({ model: modelKey(model), operation, args });\n }\n}\n\nfunction createHook(runtime: Runtime) {\n return async function track({ model, operation, args, query }: QueryHookArgs): Promise<unknown> {\n const handler = model === undefined ? undefined : WRITE_OPERATIONS[operation];\n if (model === undefined || handler === undefined || runtime.untracked.has(modelKey(model))) {\n count(runtime, model, operation, args);\n return query(args);\n }\n if (!delegates(runtime, operation, args)) {\n count(runtime, model, operation, args);\n }\n const op: Operation = { runtime, model: modelKey(model), operation, args: args ?? {}, query };\n try {\n return await handler(op);\n } catch (error) {\n if (error instanceof Untrackable) {\n return runUntracked(op, error.message);\n }\n throw error;\n }\n };\n}\n\n/** `$transaction`, in both forms, inside a transaction frame of the tracker. */\nasync function transaction(\n tracker: WriteTracker,\n hooked: ExtendedClient,\n arg: unknown,\n options: unknown,\n): Promise<unknown> {\n const interactive = typeof arg === \"function\";\n const frame = tracker.openTransaction(interactive ? \"interactive\" : \"batch\");\n try {\n const result = interactive\n ? await hooked.$transaction((client: unknown) => {\n frame.setClient(client);\n return frame.run(() => (arg as (client: unknown) => unknown)(client));\n }, options)\n : await frame.run(() => hooked.$transaction(arg, options));\n frame.commit();\n return result;\n } catch (error) {\n frame.rollback();\n throw error;\n }\n}\n\n/**\n * `StorageAdapter.nullable`: what the client's schema says (`Type?`), with\n * no statement (`schemaText.ts`). A column the schema does not answer for is\n * probed: Prisma validates a filter against the schema before sending it,\n * and refuses `{ column: null }` on a required column (a client that logs\n * errors prints that refusal). The probe's answer is kept for the life of the\n * client: one statement per optional column, none for a required one.\n */\nfunction createNullability(\n delegate: (model: string) => Delegate,\n schema: PrismaSchemaFacts | undefined,\n): (model: string, column: string) => Promise<boolean> {\n const known = new Map<string, boolean>();\n return async (model, column) => {\n const declared = schema?.nullable(model, column);\n if (declared !== undefined) {\n return declared;\n }\n const key = `${modelKey(model)}\\u0000${column}`;\n const kept = known.get(key);\n if (kept !== undefined) {\n return kept;\n }\n let nullable = true;\n try {\n await quietly(() => delegate(modelKey(model)).count({ where: { [column]: null } }));\n } catch (error) {\n if (!(error instanceof Error && error.name === \"PrismaClientValidationError\")) {\n throw error;\n }\n nullable = false;\n }\n known.set(key, nullable);\n return nullable;\n };\n}\n\n/**\n * `StorageAdapter.trackable`: whether the tracker can key `model`'s writes,\n * that is whether its rows have an `id`, as the client's schema says, with no\n * statement (`schemaText.ts`). A model the schema does not answer for is\n * probed: one read of one row's id per model, kept for the life of the\n * client, which Prisma refuses for a model without an `id` column (a\n * composite `@@id`). Any other failure (the database down) is thrown, and\n * asked again next time.\n */\nfunction createTrackability(\n delegate: (model: string) => Delegate,\n schema: PrismaSchemaFacts | undefined,\n): (model: string) => Promise<boolean> {\n const known = new Map<string, Promise<boolean>>();\n const probe = async (key: string): Promise<boolean> => {\n try {\n const rows = await quietly(() => delegate(key).findMany({ select: { id: true }, take: 1 }));\n const [row] = Array.isArray(rows) ? (rows as Readonly<Record<string, unknown>>[]) : [];\n return row === undefined || idOf(row) !== undefined;\n } catch (error) {\n if (error instanceof Error && error.name === \"PrismaClientValidationError\") {\n return false;\n }\n throw error;\n }\n };\n return async (model) => {\n const declared = schema?.trackable(model);\n if (declared !== undefined) {\n return declared;\n }\n const key = modelKey(model);\n let answer = known.get(key);\n if (answer === undefined) {\n answer = probe(key);\n known.set(key, answer);\n answer.catch(() => {\n known.delete(key);\n });\n }\n return await answer;\n };\n}\n\n/**\n * The adapter the framework reads through. Its reads are the framework's own\n * (access checks, subscriptions, flushes, kits), so the development checks\n * of statements leave them alone.\n */\nfunction createStorage(\n tracker: WriteTracker,\n [interest, links]: readonly [\n ReturnType<typeof createInterestRegistry>,\n ReturnType<typeof createLinkRegistry>,\n ],\n delegate: (model: string) => Delegate,\n schema: PrismaSchemaFacts | undefined,\n): StorageAdapter {\n return Object.freeze({\n findMany: (model: string, args: FindManyArgs = {}) =>\n quietly(() => delegate(modelKey(model)).findMany(args as Args)),\n count: (model: string, args: CountArgs = {}) =>\n quietly(() => delegate(modelKey(model)).count(args as Args)),\n onWrite: tracker.onWrite,\n countStatements: tracker.countStatements,\n registerInterest: interest.register,\n interestOf: interest.of,\n registerLinks: links.register,\n linksOf: links.of,\n inTransaction: () => tracker.transactionClient() !== undefined || tracker.inBatch(),\n nullable: createNullability(delegate, schema),\n trackable: createTrackability(delegate, schema),\n unitOfWork: tracker.unitOfWork,\n });\n}\n\n/**\n * Wraps a Prisma client so the framework sees every write made through it:\n * `create`, `update`, `upsert`, `delete` and their `Many` forms, inside and\n * outside transactions. Pass the result as `db` to `initQuickdraw`'s app and\n * to `createServer`, which find its storage adapter on it (`storageOf`).\n * Nested writes, raw SQL and database cascades are not seen; record those\n * with `ctx.touch`.\n *\n * The result is a `Tracked<C>` (`tracked.ts`): still a `C`, but the\n * untracked client is no `Tracked<C>`, so a helper that writes takes\n * `db: Tracked<Db>` (or `TrackedTransaction<Db>`, which a transaction's `tx`\n * is too) and the compiler refuses the untracked client there.\n *\n * Prefer interactive transactions (`db.$transaction(async (tx) => ...)`). An\n * array-form `db.$transaction([...])` has no transaction client, so the rows\n * a `deleteMany` or `updateMany` there reads first (and an `update`'s old\n * values) are read on the root client, outside the batch: rows the batch's\n * earlier statements created or changed may be missed, and their frames\n * with them. A development warning names the model and operation once.\n *\n * @example\n * export const db = trackPrisma(new PrismaClient({ adapter }));\n * export const qd = initQuickdraw<{ db: typeof db; principal: AppPrincipal }>();\n * const server = qd.createServer({ app, services, db, auth });\n */\nexport function trackPrisma<C extends PrismaClientLike>(\n client: C,\n options: TrackPrismaOptions = {},\n): Tracked<C> {\n if (!isClient(client)) {\n throw new TypeError(\"trackPrisma: client must be a Prisma client\");\n }\n if (storageOf(client) !== undefined) {\n throw new TypeError(\"trackPrisma: this client is tracked already; pass the untracked client\");\n }\n const tracker = createWriteTracker({\n logger: options.logger ?? consoleLogger,\n development: options.development,\n });\n const interest = createInterestRegistry(options.interest);\n // The client with the hook; the hook's own reads use it outside transactions.\n let root: ExtendedClient | undefined;\n const delegate = (model: string): Delegate =>\n delegateOf(tracker.transactionClient() ?? root, model);\n const links = createLinkRegistry();\n const runtime: Runtime = {\n tracker,\n delegate,\n interestOf: interest.of,\n linksOf: links.of,\n untracked: new Set(),\n };\n const hooked = client.$extends({\n name: \"quickdraw-tracking\",\n query: { $allOperations: createHook(runtime) },\n });\n root = hooked;\n const tracked = hooked.$extends({\n name: \"quickdraw-transactions\",\n client: {\n $transaction: (arg: unknown, txOptions?: unknown) =>\n transaction(tracker, hooked, arg, txOptions),\n [STORAGE_KEY]: createStorage(tracker, [interest, links], delegate, prismaSchemaOf(client)),\n },\n });\n // `Tracked<C>` is a type: the client carries no mark at run time.\n return tracked as unknown as Tracked<C>;\n}\n"],"mappings":"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","names":["result"]}
@@ -7,7 +7,7 @@ import {
7
7
  createPublicApiLimiter,
8
8
  createWebhookLimiter,
9
9
  stripIp
10
- } from "./chunk-TBMKJ26R.js";
10
+ } from "./chunk-NW6U45HX.js";
11
11
  export {
12
12
  bearerOrIp,
13
13
  createAuthLimiter,
@@ -18,4 +18,4 @@ export {
18
18
  createWebhookLimiter,
19
19
  stripIp
20
20
  };
21
- //# sourceMappingURL=rateLimit-ZMIZJUZF.js.map
21
+ //# sourceMappingURL=rateLimit-5RKBFLUR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,15 @@
1
+ import {
2
+ createPeerLink
3
+ } from "./chunk-DNP65TD5.js";
4
+ import {
5
+ controlOf
6
+ } from "./chunk-ASAMUGHG.js";
7
+ import "./chunk-2FDSKLBO.js";
8
+ import "./chunk-X4ZU4QH5.js";
9
+ import "./chunk-7Y5ROPXL.js";
10
+ import "./chunk-QSU47XEX.js";
11
+ export {
12
+ controlOf,
13
+ createPeerLink
14
+ };
15
+ //# sourceMappingURL=remote-N7OUAGOW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,8 +1,9 @@
1
- import { L as Logger } from '../../logger-BY28acW-.js';
1
+ import { L as Logger } from '../../logger-Yz93KzdV.js';
2
2
  import { IncomingHttpHeaders, IncomingMessage, ServerResponse } from 'node:http';
3
- import { M as MaybePromise, P as Principal } from '../../types-Cu0vmx7c.js';
4
- import { b as AuthenticateRequest, H as HttpRequest } from '../../auth-BhWqdyb-.js';
5
- import '../../infer-Teo1xpsd.js';
3
+ import { M as MaybePromise, P as Principal } from '../../types-CLRCQGnO.js';
4
+ import { A as AllowedOrigin } from '../../origins-kvpxnVcW.js';
5
+ import { b as AuthenticateRequest, H as HttpRequest } from '../../auth-DtdYjrZ9.js';
6
+ import '../../infer-Br62cnyW.js';
6
7
  import 'socket.io';
7
8
 
8
9
  /**
@@ -60,10 +61,11 @@ interface SessionCookieOptions {
60
61
  }
61
62
  /**
62
63
  * Sets the session cookie, under the name {@link sessionCookieNameFor} gives
63
- * the response's request, so `socketAuth` and the HTTP transport read it.
64
+ * the response's request, so `socketAuth` and the HTTP transport read it,
65
+ * and clears a stale `__Host-session` that would shadow it.
64
66
  */
65
67
  declare function setSessionCookie(res: CookieResponse, jwt: string, options?: SessionCookieOptions): void;
66
- /** Clears the session cookie `setSessionCookie` sets on the same request. */
68
+ /** Clears the session cookie `setSessionCookie` sets on the same request, and a stale `__Host-session` beside it. */
67
69
  declare function clearSessionCookie(res: CookieResponse, options?: SessionCookieOptions): void;
68
70
 
69
71
  interface JWTPayload {
@@ -86,7 +88,13 @@ interface JWTPayload {
86
88
  */
87
89
  declare function createJWT(payload: Omit<JWTPayload, "exp" | "iat">, secret: string, expiresIn?: string): Promise<string>;
88
90
  /**
89
- * Verify and decode a JWT token.
91
+ * Verify and decode a JWT token: its signature and expiry, nothing more.
92
+ * It is never a session check: a token of a session that was signed out,
93
+ * logged out everywhere or revoked still verifies until the JWT expires (7
94
+ * days by default). Check a session token with `liveSession({ sessions,
95
+ * jwtSecret }, token)`, `bearerAuth(...)` or `socketAuth(...)`, which ask the
96
+ * session store on every call. In development it warns once per process
97
+ * when it verifies a token that carries a session (`sid`).
90
98
  *
91
99
  * @param token - The JWT token to verify
92
100
  * @param secret - The secret key for verification
@@ -190,10 +198,12 @@ declare const googleProvider: OAuthProvider<GoogleUser>;
190
198
  * via `registerMockOAuthProvider`. Users are supplied by the app (typically
191
199
  * seeded demo accounts); no real credentials are involved.
192
200
  *
193
- * Production hard-block: routes are never mounted when NODE_ENV is
194
- * "production" or ENABLE_MOCK_OAUTH !== "true", and every handler re-checks
195
- * NODE_ENV at request time. Apps should add a third layer and refuse to boot
196
- * in production with the flag set.
201
+ * Development only: routes are mounted only when ENABLE_MOCK_OAUTH is
202
+ * "true" and NODE_ENV is "development" or "test" (an allowlist: an unset
203
+ * NODE_ENV, "prod" or "staging" mount nothing, the 5.1 audit's AUTH-3), every
204
+ * handler re-checks NODE_ENV at request time, and mounting them logs a
205
+ * warning. Apps should add a third layer and refuse to boot outside
206
+ * development with the flag set.
197
207
  */
198
208
 
199
209
  interface MockOAuthUser {
@@ -203,6 +213,7 @@ interface MockOAuthUser {
203
213
  picture?: string | null;
204
214
  }
205
215
  declare const DEFAULT_MOCK_PATH_PREFIX = "/auth/mock/provider";
216
+ /** True when ENABLE_MOCK_OAUTH is "true" and NODE_ENV is "development" or "test". */
206
217
  declare function isMockOAuthEnabled(): boolean;
207
218
  interface MockOAuthProviderOptions {
208
219
  /**
@@ -259,8 +270,9 @@ interface RegisterMockOAuthOptions {
259
270
  * Mount the mock OAuth provider endpoints (authorize, token, userinfo) on an
260
271
  * Express-compatible router.
261
272
  *
262
- * No-ops (returning false) unless `isMockOAuthEnabled()` — i.e. in production
263
- * or without ENABLE_MOCK_OAUTH=true the routes are never mounted.
273
+ * No-ops (returning false) unless `isMockOAuthEnabled()` — i.e. without
274
+ * ENABLE_MOCK_OAUTH=true, or unless NODE_ENV is development or test, the
275
+ * routes are never mounted. Mounting them logs a warning.
264
276
  */
265
277
  declare function registerMockOAuthProvider(router: MockOAuthRouter, options: RegisterMockOAuthOptions): boolean;
266
278
 
@@ -351,8 +363,8 @@ interface RequireAuthOptions {
351
363
  /**
352
364
  * Cookie to read the JWT from. Default: the names `setSessionCookie` and
353
365
  * the auth routes set on the same request (`sessionCookieNamesFor`):
354
- * `__Host-session` over HTTPS, `session` (then `__Host-session`) over
355
- * plain HTTP or when `COOKIE_DOMAIN` is set.
366
+ * `__Host-session` over HTTPS, `__Host-session` then `session` over plain
367
+ * HTTP or when `COOKIE_DOMAIN` is set.
356
368
  */
357
369
  cookieName?: string;
358
370
  }
@@ -385,13 +397,6 @@ interface AuthRouteRequest extends IncomingMessage {
385
397
  /** The response the routes answer: Express's, which also sets cookies. */
386
398
  type AuthRouteResponse = ServerResponse & CookieResponse;
387
399
 
388
- /**
389
- * An allowed origin: exact (`"https://app.example.com"`), or a pattern over
390
- * whole origins, anchored at both ends
391
- * (`/^https:\/\/[a-z0-9-]+\.preview\.example\.com$/`).
392
- */
393
- type AllowedOrigin = string | RegExp;
394
-
395
400
  /** The cookie that carries a sign-in in progress, on a request that is not secure. */
396
401
  declare const OAUTH_STATE_COOKIE = "qd_oauth";
397
402
  /**
@@ -607,7 +612,8 @@ declare namespace discord {
607
612
  * The development sign-in: a picker of the app's demo users, served by the
608
613
  * routes through `registerMockOAuthProvider`. Left out (its routes answer
609
614
  * nothing) unless `isMockOAuthEnabled()`: `ENABLE_MOCK_OAUTH=true` and
610
- * `NODE_ENV` other than `production`.
615
+ * `NODE_ENV` `development` or `test` (an unset `NODE_ENV` leaves it out: set
616
+ * `NODE_ENV=development`). Mounting it logs a warning.
611
617
  */
612
618
  declare function mock(options: MockSignInOptions): MockSignInProvider;
613
619
 
@@ -767,8 +773,8 @@ interface SocketAuthOptions<P extends Principal = Principal> {
767
773
  * The session cookie's name. Default: the name the auth routes set on the
768
774
  * same handshake: `"session"` when `COOKIE_DOMAIN` gives the cookie a
769
775
  * domain; else `"__Host-session"` over HTTPS, where the plain name a
770
- * sibling site could plant is never read, and `"session"` (then
771
- * `"__Host-session"`) over plain HTTP. A name given here is the only one
776
+ * sibling site could plant is never read, and `"session"` over plain HTTP,
777
+ * where `"__Host-session"` is read first all the same. A name given here is the only one
772
778
  * read, on any handshake: give the routes' `cookie.name` here, or
773
779
  * `"session"` when their `cookie.domain` is set without `COOKIE_DOMAIN`. A
774
780
  * name the handshake repeats counts as no credential.
@@ -785,9 +791,11 @@ interface SocketAuthOptions<P extends Principal = Principal> {
785
791
  * Development sign-in without a session: a socket whose handshake carries
786
792
  * `auth: { userId }` and no token is that user, as this function answers:
787
793
  * their principal (its `userId` the one named), or `null` to refuse the
788
- * handshake (an unknown id). For a game editor or load-test bots. Never in
789
- * production: `socketAuth` throws when it is given while `NODE_ENV` is
790
- * `"production"`, and refuses such a handshake there anyway. HTTP calls
794
+ * handshake (an unknown id). For a game editor or load-test bots. Only
795
+ * while `NODE_ENV` is `development` or `test`: `socketAuth` throws when it
796
+ * is given otherwise (an unset `NODE_ENV` included: set
797
+ * `NODE_ENV=development`), refuses such a handshake once `NODE_ENV` says
798
+ * otherwise, and `createServer` warns at startup while it is on. HTTP calls
791
799
  * never use it. Pass it only when the app's own flag is on:
792
800
  * `devCredentials: env.ENABLE_DEV_CREDENTIALS ? findDevUser : undefined`.
793
801
  */
@@ -813,13 +821,19 @@ interface CookieOriginRequest {
813
821
  * `Sec-Fetch-Site` names another site, and a socket handshake only when
814
822
  * `Sec-Fetch-Site` is `same-origin` or with `allowMissingOrigin`. A bearer
815
823
  * token is not ambient: check only a credential that came from the cookie
816
- * (`request.credential === "cookie"` on an HTTP `authenticate` request).
824
+ * (`request.sessionCookie` on an HTTP `authenticate` request, where the
825
+ * transport hands an `authenticate` other than socketAuth's the cookie; it is
826
+ * in `auth.token` only for socketAuth's). Then check the session against the
827
+ * store, on every call (`liveSession`).
817
828
  *
818
829
  * @example
819
830
  * authenticate: async (request) => {
820
- * if (request.transport === "http" && request.credential === "cookie" &&
821
- * !cookieOriginAllowed(request, allowedOrigins)) {
822
- * throw new QuickdrawError("FORBIDDEN", "This page may not use the session cookie");
831
+ * if (request.transport === "http" && request.sessionCookie !== undefined) {
832
+ * if (!cookieOriginAllowed(request, allowedOrigins)) {
833
+ * throw new QuickdrawError("FORBIDDEN", "This page may not use the session cookie");
834
+ * }
835
+ * const session = await liveSession({ sessions, jwtSecret }, request.sessionCookie);
836
+ * // ...
823
837
  * }
824
838
  * // ...
825
839
  * }
@@ -836,6 +850,41 @@ declare function socketAuth<P extends Principal>(options: SocketAuthOptions<P> &
836
850
  }): SessionAuthenticate<P>;
837
851
  declare function socketAuth(options: SocketAuthOptions): SessionAuthenticate<Principal>;
838
852
 
853
+ /** Options of {@link bearerAuth}: the auth routes' session store and secret, and how a principal is built. */
854
+ interface BearerAuthOptions<P extends Principal = Principal> extends SessionKeys {
855
+ /**
856
+ * Builds the principal of a session's user, for example `kind: "agent"`
857
+ * for an MCP caller; its `userId` must be the session's. Default
858
+ * `{ userId, kind: "user" }`.
859
+ */
860
+ readonly loadPrincipal?: PrincipalLoader<P>;
861
+ }
862
+ /**
863
+ * What {@link bearerAuth} returns: the principal a bearer token signs in,
864
+ * `null` for no token, and a rejection (`UNAUTHENTICATED`) for a token that
865
+ * is not a live session's.
866
+ */
867
+ type BearerAuthenticate<P extends Principal> = (token: unknown) => Promise<P | null>;
868
+ /**
869
+ * Checks bearer tokens against the auth routes' sessions, on every call: no
870
+ * token (anything but a non-empty string) is anonymous (`null`); a token
871
+ * whose session was signed out, revoked or has expired, or a JWT without a
872
+ * session, is refused with `UNAUTHENTICATED`; a live session's token is its
873
+ * user's principal, built as `socketAuth` builds it. It records no socket
874
+ * session: for `createServer`'s `authenticate` use `socketAuth`.
875
+ *
876
+ * @example
877
+ * const verifySession = bearerAuth({ sessions, jwtSecret, loadPrincipal: (userId) => ({ userId, kind: "agent" }) });
878
+ * // the MCP bridge's principal hook
879
+ * createMcpRegistry({ ..., principal: (request) => verifySession(request.transport === "http" ? request.token : process.env.AGENT_TOKEN) });
880
+ * // an authenticate that takes bearer tokens only
881
+ * createHttpRouter({ dispatcher, auth: { authenticate: ({ auth }) => verifySession(auth.token) } });
882
+ */
883
+ declare function bearerAuth<P extends Principal>(options: BearerAuthOptions<P> & {
884
+ readonly loadPrincipal: PrincipalLoader<P>;
885
+ }): BearerAuthenticate<P>;
886
+ declare function bearerAuth(options: BearerAuthOptions): BearerAuthenticate<Principal>;
887
+
839
888
  /** Options of {@link requireSession}. */
840
889
  interface RequireSessionOptions<P extends Principal = Principal> {
841
890
  /**
@@ -927,4 +976,4 @@ declare function requireSession(keys: SessionKeys, options?: RequireSessionOptio
927
976
  */
928
977
  declare function sessionOf<P extends Principal = Principal>(req: object): RequestSession<P>;
929
978
 
930
- export { type AllowedOrigin, type AuthCookieOptions, type AuthMiddleware, type AuthProfile, type AuthProvider, type AuthProviderInfo, type AuthRateLimits, type AuthRequest, type AuthResponse, type AuthRouteRequest, type AuthRouteResponse, type AuthRoutes, type AuthRoutesOptions, type AuthSession, type CookieOriginRequest, type CookieResponse, type CookieSettings, DEFAULT_MOCK_PATH_PREFIX, DEFAULT_SESSION_TTL_MS, type DevCredentials, type DiscordUser, GUEST_MAX_BODY_BYTES, type GoogleUser, type GuestOptions, type GuestProvider, type GuestUser, HOST_OAUTH_STATE_COOKIE, HOST_SESSION_COOKIE, type IssuedSession, type JWTPayload, MIN_JWT_SECRET_LENGTH, type MemorySessionStore, type MockOAuthProviderOptions, type MockOAuthRouter, type MockOAuthUser, type MockSignInOptions, type MockSignInProvider, OAUTH_RETURN_ORIGIN_COOKIE, OAUTH_STATE_COOKIE, OAUTH_STATE_TTL_MS, type OAuthClientOptions, type OAuthConfig, type OAuthProvider, type OAuthSignInProvider, type OAuthTokenResponse, type OptionalClientOptions, type PrincipalLoader, type RegisterMockOAuthOptions, type RequestSession, type RequireAuthOptions, type RequireSessionOptions, SESSION_COOKIE, type SessionAuthenticate, type SessionCookieOptions, type SessionKeys, type SessionMeta, type SessionMiddleware, type SessionRequest, type SessionStore, type SocketAuthOptions, type ValidateOriginOptions, clearSessionCookie, cookieOriginAllowed, createAuthRoutes, createJWT, createMemorySessionStore, createMockOAuthProvider, createOAuthURL, createRequireAuth, discord, discordProvider, exchangeOAuthCode, extractBearerOrCookieToken, getDiscordAvatarUrl, google, googleProvider, guest, isMockOAuthEnabled, issueSession, liveSession, mock, registerMockOAuthProvider, requireSession, sessionOf, setSessionCookie, socketAuth, validateRedirectOrigin, verifyJWT };
979
+ export { AllowedOrigin, type AuthCookieOptions, type AuthMiddleware, type AuthProfile, type AuthProvider, type AuthProviderInfo, type AuthRateLimits, type AuthRequest, type AuthResponse, type AuthRouteRequest, type AuthRouteResponse, type AuthRoutes, type AuthRoutesOptions, type AuthSession, type BearerAuthOptions, type BearerAuthenticate, type CookieOriginRequest, type CookieResponse, type CookieSettings, DEFAULT_MOCK_PATH_PREFIX, DEFAULT_SESSION_TTL_MS, type DevCredentials, type DiscordUser, GUEST_MAX_BODY_BYTES, type GoogleUser, type GuestOptions, type GuestProvider, type GuestUser, HOST_OAUTH_STATE_COOKIE, HOST_SESSION_COOKIE, type IssuedSession, type JWTPayload, MIN_JWT_SECRET_LENGTH, type MemorySessionStore, type MockOAuthProviderOptions, type MockOAuthRouter, type MockOAuthUser, type MockSignInOptions, type MockSignInProvider, OAUTH_RETURN_ORIGIN_COOKIE, OAUTH_STATE_COOKIE, OAUTH_STATE_TTL_MS, type OAuthClientOptions, type OAuthConfig, type OAuthProvider, type OAuthSignInProvider, type OAuthTokenResponse, type OptionalClientOptions, type PrincipalLoader, type RegisterMockOAuthOptions, type RequestSession, type RequireAuthOptions, type RequireSessionOptions, SESSION_COOKIE, type SessionAuthenticate, type SessionCookieOptions, type SessionKeys, type SessionMeta, type SessionMiddleware, type SessionRequest, type SessionStore, type SocketAuthOptions, type ValidateOriginOptions, bearerAuth, clearSessionCookie, cookieOriginAllowed, createAuthRoutes, createJWT, createMemorySessionStore, createMockOAuthProvider, createOAuthURL, createRequireAuth, discord, discordProvider, exchangeOAuthCode, extractBearerOrCookieToken, getDiscordAvatarUrl, google, googleProvider, guest, isMockOAuthEnabled, issueSession, liveSession, mock, registerMockOAuthProvider, requireSession, sessionOf, setSessionCookie, socketAuth, validateRedirectOrigin, verifyJWT };