@rocicorp/zero 0.26.0-canary.0 → 0.26.0-canary.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 (391) hide show
  1. package/README.md +1 -1
  2. package/out/replicache/src/persist/collect-idb-databases.d.ts +4 -4
  3. package/out/replicache/src/persist/collect-idb-databases.d.ts.map +1 -1
  4. package/out/replicache/src/persist/collect-idb-databases.js +22 -19
  5. package/out/replicache/src/persist/collect-idb-databases.js.map +1 -1
  6. package/out/replicache/src/persist/refresh.d.ts.map +1 -1
  7. package/out/replicache/src/persist/refresh.js +0 -8
  8. package/out/replicache/src/persist/refresh.js.map +1 -1
  9. package/out/replicache/src/process-scheduler.d.ts +23 -0
  10. package/out/replicache/src/process-scheduler.d.ts.map +1 -1
  11. package/out/replicache/src/process-scheduler.js +50 -1
  12. package/out/replicache/src/process-scheduler.js.map +1 -1
  13. package/out/replicache/src/replicache-impl.d.ts +8 -0
  14. package/out/replicache/src/replicache-impl.d.ts.map +1 -1
  15. package/out/replicache/src/replicache-impl.js +11 -2
  16. package/out/replicache/src/replicache-impl.js.map +1 -1
  17. package/out/shared/src/custom-key-map.d.ts +4 -4
  18. package/out/shared/src/custom-key-map.d.ts.map +1 -1
  19. package/out/shared/src/custom-key-map.js.map +1 -1
  20. package/out/shared/src/falsy.d.ts +3 -0
  21. package/out/shared/src/falsy.d.ts.map +1 -0
  22. package/out/shared/src/iterables.d.ts +6 -8
  23. package/out/shared/src/iterables.d.ts.map +1 -1
  24. package/out/shared/src/iterables.js +13 -7
  25. package/out/shared/src/iterables.js.map +1 -1
  26. package/out/shared/src/options.d.ts +1 -0
  27. package/out/shared/src/options.d.ts.map +1 -1
  28. package/out/shared/src/options.js +5 -1
  29. package/out/shared/src/options.js.map +1 -1
  30. package/out/zero/package.json.js +1 -1
  31. package/out/zero/src/adapters/drizzle.js +1 -2
  32. package/out/zero/src/adapters/prisma.d.ts +2 -0
  33. package/out/zero/src/adapters/prisma.d.ts.map +1 -0
  34. package/out/zero/src/adapters/prisma.js +6 -0
  35. package/out/zero/src/adapters/prisma.js.map +1 -0
  36. package/out/zero/src/pg.js +4 -7
  37. package/out/zero/src/react.js +3 -1
  38. package/out/zero/src/react.js.map +1 -1
  39. package/out/zero/src/server.js +5 -8
  40. package/out/zero/src/zero-cache-dev.js +7 -3
  41. package/out/zero/src/zero-cache-dev.js.map +1 -1
  42. package/out/zero-cache/src/auth/load-permissions.d.ts +3 -2
  43. package/out/zero-cache/src/auth/load-permissions.d.ts.map +1 -1
  44. package/out/zero-cache/src/auth/load-permissions.js +14 -8
  45. package/out/zero-cache/src/auth/load-permissions.js.map +1 -1
  46. package/out/zero-cache/src/auth/write-authorizer.d.ts +6 -0
  47. package/out/zero-cache/src/auth/write-authorizer.d.ts.map +1 -1
  48. package/out/zero-cache/src/auth/write-authorizer.js +16 -3
  49. package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
  50. package/out/zero-cache/src/config/zero-config.d.ts +54 -9
  51. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  52. package/out/zero-cache/src/config/zero-config.js +80 -20
  53. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  54. package/out/zero-cache/src/custom/fetch.d.ts +3 -0
  55. package/out/zero-cache/src/custom/fetch.d.ts.map +1 -1
  56. package/out/zero-cache/src/custom/fetch.js +26 -0
  57. package/out/zero-cache/src/custom/fetch.js.map +1 -1
  58. package/out/zero-cache/src/db/lite-tables.js +1 -1
  59. package/out/zero-cache/src/db/lite-tables.js.map +1 -1
  60. package/out/zero-cache/src/db/migration-lite.d.ts.map +1 -1
  61. package/out/zero-cache/src/db/migration-lite.js +9 -3
  62. package/out/zero-cache/src/db/migration-lite.js.map +1 -1
  63. package/out/zero-cache/src/db/migration.d.ts.map +1 -1
  64. package/out/zero-cache/src/db/migration.js +9 -3
  65. package/out/zero-cache/src/db/migration.js.map +1 -1
  66. package/out/zero-cache/src/db/specs.d.ts +4 -3
  67. package/out/zero-cache/src/db/specs.d.ts.map +1 -1
  68. package/out/zero-cache/src/db/specs.js +4 -1
  69. package/out/zero-cache/src/db/specs.js.map +1 -1
  70. package/out/zero-cache/src/db/transaction-pool.d.ts.map +1 -1
  71. package/out/zero-cache/src/db/transaction-pool.js +9 -3
  72. package/out/zero-cache/src/db/transaction-pool.js.map +1 -1
  73. package/out/zero-cache/src/observability/events.d.ts.map +1 -1
  74. package/out/zero-cache/src/observability/events.js +15 -5
  75. package/out/zero-cache/src/observability/events.js.map +1 -1
  76. package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
  77. package/out/zero-cache/src/server/change-streamer.js +10 -2
  78. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  79. package/out/zero-cache/src/server/inspector-delegate.d.ts +1 -1
  80. package/out/zero-cache/src/server/inspector-delegate.d.ts.map +1 -1
  81. package/out/zero-cache/src/server/inspector-delegate.js +11 -30
  82. package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
  83. package/out/zero-cache/src/server/main.js +1 -1
  84. package/out/zero-cache/src/server/main.js.map +1 -1
  85. package/out/zero-cache/src/server/priority-op.d.ts +8 -0
  86. package/out/zero-cache/src/server/priority-op.d.ts.map +1 -0
  87. package/out/zero-cache/src/server/priority-op.js +29 -0
  88. package/out/zero-cache/src/server/priority-op.js.map +1 -0
  89. package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
  90. package/out/zero-cache/src/server/syncer.js +10 -10
  91. package/out/zero-cache/src/server/syncer.js.map +1 -1
  92. package/out/zero-cache/src/services/analyze.js +1 -1
  93. package/out/zero-cache/src/services/analyze.js.map +1 -1
  94. package/out/zero-cache/src/services/change-source/custom/change-source.d.ts.map +1 -1
  95. package/out/zero-cache/src/services/change-source/custom/change-source.js +4 -7
  96. package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
  97. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
  98. package/out/zero-cache/src/services/change-source/pg/change-source.js +68 -13
  99. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  100. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
  101. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +7 -2
  102. package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
  103. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.d.ts.map +1 -1
  104. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +7 -4
  105. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js.map +1 -1
  106. package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts +125 -180
  107. package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts.map +1 -1
  108. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js +1 -10
  109. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js.map +1 -1
  110. package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts.map +1 -1
  111. package/out/zero-cache/src/services/change-source/pg/schema/init.js +26 -12
  112. package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
  113. package/out/zero-cache/src/services/change-source/pg/schema/published.d.ts +36 -90
  114. package/out/zero-cache/src/services/change-source/pg/schema/published.d.ts.map +1 -1
  115. package/out/zero-cache/src/services/change-source/pg/schema/published.js +51 -14
  116. package/out/zero-cache/src/services/change-source/pg/schema/published.js.map +1 -1
  117. package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts +31 -36
  118. package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts.map +1 -1
  119. package/out/zero-cache/src/services/change-source/pg/schema/shard.js +25 -17
  120. package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
  121. package/out/zero-cache/src/services/change-source/pg/schema/validation.d.ts +2 -2
  122. package/out/zero-cache/src/services/change-source/pg/schema/validation.d.ts.map +1 -1
  123. package/out/zero-cache/src/services/change-source/pg/schema/validation.js +2 -4
  124. package/out/zero-cache/src/services/change-source/pg/schema/validation.js.map +1 -1
  125. package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts +158 -53
  126. package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts.map +1 -1
  127. package/out/zero-cache/src/services/change-source/protocol/current/data.js +55 -10
  128. package/out/zero-cache/src/services/change-source/protocol/current/data.js.map +1 -1
  129. package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts +210 -72
  130. package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts.map +1 -1
  131. package/out/zero-cache/src/services/change-source/protocol/current.js +4 -2
  132. package/out/zero-cache/src/services/change-source/replica-schema.d.ts.map +1 -1
  133. package/out/zero-cache/src/services/change-source/replica-schema.js +20 -4
  134. package/out/zero-cache/src/services/change-source/replica-schema.js.map +1 -1
  135. package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts +1 -1
  136. package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts.map +1 -1
  137. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +6 -4
  138. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  139. package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts +71 -25
  140. package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts.map +1 -1
  141. package/out/zero-cache/src/services/change-streamer/change-streamer.js +1 -1
  142. package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
  143. package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts +1 -0
  144. package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts.map +1 -1
  145. package/out/zero-cache/src/services/change-streamer/schema/tables.js +6 -5
  146. package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
  147. package/out/zero-cache/src/services/change-streamer/storer.d.ts +1 -1
  148. package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
  149. package/out/zero-cache/src/services/change-streamer/storer.js +17 -6
  150. package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
  151. package/out/zero-cache/src/services/change-streamer/subscriber.d.ts +2 -0
  152. package/out/zero-cache/src/services/change-streamer/subscriber.d.ts.map +1 -1
  153. package/out/zero-cache/src/services/change-streamer/subscriber.js +14 -1
  154. package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
  155. package/out/zero-cache/src/services/heapz.d.ts.map +1 -1
  156. package/out/zero-cache/src/services/heapz.js +1 -0
  157. package/out/zero-cache/src/services/heapz.js.map +1 -1
  158. package/out/zero-cache/src/services/life-cycle.d.ts +1 -1
  159. package/out/zero-cache/src/services/life-cycle.d.ts.map +1 -1
  160. package/out/zero-cache/src/services/life-cycle.js.map +1 -1
  161. package/out/zero-cache/src/services/litestream/commands.d.ts.map +1 -1
  162. package/out/zero-cache/src/services/litestream/commands.js +3 -1
  163. package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
  164. package/out/zero-cache/src/services/litestream/config.yml +1 -0
  165. package/out/zero-cache/src/services/mutagen/error.d.ts.map +1 -1
  166. package/out/zero-cache/src/services/mutagen/error.js +4 -1
  167. package/out/zero-cache/src/services/mutagen/error.js.map +1 -1
  168. package/out/zero-cache/src/services/mutagen/mutagen.d.ts +4 -4
  169. package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
  170. package/out/zero-cache/src/services/mutagen/mutagen.js +10 -24
  171. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  172. package/out/zero-cache/src/services/mutagen/pusher.d.ts +8 -6
  173. package/out/zero-cache/src/services/mutagen/pusher.d.ts.map +1 -1
  174. package/out/zero-cache/src/services/mutagen/pusher.js +130 -19
  175. package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
  176. package/out/zero-cache/src/services/replicator/change-processor.d.ts.map +1 -1
  177. package/out/zero-cache/src/services/replicator/change-processor.js +24 -31
  178. package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
  179. package/out/zero-cache/src/services/replicator/schema/change-log.d.ts +4 -4
  180. package/out/zero-cache/src/services/replicator/schema/change-log.d.ts.map +1 -1
  181. package/out/zero-cache/src/services/replicator/schema/change-log.js +38 -36
  182. package/out/zero-cache/src/services/replicator/schema/change-log.js.map +1 -1
  183. package/out/zero-cache/src/services/{change-source → replicator/schema}/column-metadata.d.ts +3 -3
  184. package/out/zero-cache/src/services/replicator/schema/column-metadata.d.ts.map +1 -0
  185. package/out/zero-cache/src/services/{change-source → replicator/schema}/column-metadata.js +3 -3
  186. package/out/zero-cache/src/services/replicator/schema/column-metadata.js.map +1 -0
  187. package/out/zero-cache/src/services/replicator/schema/replication-state.d.ts.map +1 -1
  188. package/out/zero-cache/src/services/replicator/schema/replication-state.js +3 -1
  189. package/out/zero-cache/src/services/replicator/schema/replication-state.js.map +1 -1
  190. package/out/zero-cache/src/services/run-ast.js +1 -1
  191. package/out/zero-cache/src/services/run-ast.js.map +1 -1
  192. package/out/zero-cache/src/services/statz.d.ts.map +1 -1
  193. package/out/zero-cache/src/services/statz.js +1 -0
  194. package/out/zero-cache/src/services/statz.js.map +1 -1
  195. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts +5 -6
  196. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts.map +1 -1
  197. package/out/zero-cache/src/services/view-syncer/client-handler.js +5 -23
  198. package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
  199. package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts +1 -1
  200. package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
  201. package/out/zero-cache/src/services/view-syncer/cvr-store.js +65 -44
  202. package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
  203. package/out/zero-cache/src/services/view-syncer/cvr.d.ts +0 -1
  204. package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
  205. package/out/zero-cache/src/services/view-syncer/cvr.js +23 -6
  206. package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
  207. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +14 -22
  208. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  209. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +46 -67
  210. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  211. package/out/zero-cache/src/services/view-syncer/row-record-cache.d.ts +1 -1
  212. package/out/zero-cache/src/services/view-syncer/row-record-cache.d.ts.map +1 -1
  213. package/out/zero-cache/src/services/view-syncer/row-record-cache.js +22 -11
  214. package/out/zero-cache/src/services/view-syncer/row-record-cache.js.map +1 -1
  215. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +0 -2
  216. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
  217. package/out/zero-cache/src/services/view-syncer/snapshotter.js +3 -11
  218. package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
  219. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +6 -4
  220. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  221. package/out/zero-cache/src/services/view-syncer/view-syncer.js +216 -243
  222. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  223. package/out/zero-cache/src/types/lexi-version.d.ts.map +1 -1
  224. package/out/zero-cache/src/types/lexi-version.js +4 -1
  225. package/out/zero-cache/src/types/lexi-version.js.map +1 -1
  226. package/out/zero-cache/src/types/lite.d.ts.map +1 -1
  227. package/out/zero-cache/src/types/lite.js +8 -2
  228. package/out/zero-cache/src/types/lite.js.map +1 -1
  229. package/out/zero-cache/src/types/shards.js +1 -1
  230. package/out/zero-cache/src/types/shards.js.map +1 -1
  231. package/out/zero-cache/src/types/sql.d.ts +5 -0
  232. package/out/zero-cache/src/types/sql.d.ts.map +1 -1
  233. package/out/zero-cache/src/types/sql.js +5 -1
  234. package/out/zero-cache/src/types/sql.js.map +1 -1
  235. package/out/zero-cache/src/types/subscription.js +1 -1
  236. package/out/zero-cache/src/types/subscription.js.map +1 -1
  237. package/out/zero-cache/src/workers/connect-params.d.ts +1 -1
  238. package/out/zero-cache/src/workers/connect-params.d.ts.map +1 -1
  239. package/out/zero-cache/src/workers/connect-params.js +2 -3
  240. package/out/zero-cache/src/workers/connect-params.js.map +1 -1
  241. package/out/zero-cache/src/workers/replicator.d.ts.map +1 -1
  242. package/out/zero-cache/src/workers/replicator.js +2 -5
  243. package/out/zero-cache/src/workers/replicator.js.map +1 -1
  244. package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts.map +1 -1
  245. package/out/zero-cache/src/workers/syncer-ws-message-handler.js +15 -10
  246. package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
  247. package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
  248. package/out/zero-cache/src/workers/syncer.js +17 -10
  249. package/out/zero-cache/src/workers/syncer.js.map +1 -1
  250. package/out/zero-client/src/client/connection-manager.d.ts +8 -0
  251. package/out/zero-client/src/client/connection-manager.d.ts.map +1 -1
  252. package/out/zero-client/src/client/connection-manager.js +33 -0
  253. package/out/zero-client/src/client/connection-manager.js.map +1 -1
  254. package/out/zero-client/src/client/connection.d.ts.map +1 -1
  255. package/out/zero-client/src/client/connection.js +6 -3
  256. package/out/zero-client/src/client/connection.js.map +1 -1
  257. package/out/zero-client/src/client/context.js +1 -0
  258. package/out/zero-client/src/client/context.js.map +1 -1
  259. package/out/zero-client/src/client/error.js +1 -1
  260. package/out/zero-client/src/client/error.js.map +1 -1
  261. package/out/zero-client/src/client/mutator-proxy.d.ts.map +1 -1
  262. package/out/zero-client/src/client/mutator-proxy.js +15 -1
  263. package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
  264. package/out/zero-client/src/client/options.d.ts +11 -1
  265. package/out/zero-client/src/client/options.d.ts.map +1 -1
  266. package/out/zero-client/src/client/options.js.map +1 -1
  267. package/out/zero-client/src/client/query-manager.d.ts +4 -0
  268. package/out/zero-client/src/client/query-manager.d.ts.map +1 -1
  269. package/out/zero-client/src/client/query-manager.js +7 -0
  270. package/out/zero-client/src/client/query-manager.js.map +1 -1
  271. package/out/zero-client/src/client/version.js +1 -1
  272. package/out/zero-client/src/client/zero.d.ts +5 -5
  273. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  274. package/out/zero-client/src/client/zero.js +53 -8
  275. package/out/zero-client/src/client/zero.js.map +1 -1
  276. package/out/zero-client/src/mod.d.ts +1 -0
  277. package/out/zero-client/src/mod.d.ts.map +1 -1
  278. package/out/zero-protocol/src/connect.d.ts +4 -0
  279. package/out/zero-protocol/src/connect.d.ts.map +1 -1
  280. package/out/zero-protocol/src/connect.js +3 -1
  281. package/out/zero-protocol/src/connect.js.map +1 -1
  282. package/out/zero-protocol/src/protocol-version.d.ts +1 -1
  283. package/out/zero-protocol/src/protocol-version.d.ts.map +1 -1
  284. package/out/zero-protocol/src/protocol-version.js +1 -1
  285. package/out/zero-protocol/src/protocol-version.js.map +1 -1
  286. package/out/zero-protocol/src/push.d.ts +16 -0
  287. package/out/zero-protocol/src/push.d.ts.map +1 -1
  288. package/out/zero-protocol/src/push.js +25 -1
  289. package/out/zero-protocol/src/push.js.map +1 -1
  290. package/out/zero-protocol/src/up.d.ts +2 -0
  291. package/out/zero-protocol/src/up.d.ts.map +1 -1
  292. package/out/zero-react/src/mod.d.ts +3 -1
  293. package/out/zero-react/src/mod.d.ts.map +1 -1
  294. package/out/zero-react/src/paging-reducer.d.ts +61 -0
  295. package/out/zero-react/src/paging-reducer.d.ts.map +1 -0
  296. package/out/zero-react/src/paging-reducer.js +77 -0
  297. package/out/zero-react/src/paging-reducer.js.map +1 -0
  298. package/out/zero-react/src/use-query.d.ts +11 -1
  299. package/out/zero-react/src/use-query.d.ts.map +1 -1
  300. package/out/zero-react/src/use-query.js +13 -11
  301. package/out/zero-react/src/use-query.js.map +1 -1
  302. package/out/zero-react/src/use-rows.d.ts +39 -0
  303. package/out/zero-react/src/use-rows.d.ts.map +1 -0
  304. package/out/zero-react/src/use-rows.js +130 -0
  305. package/out/zero-react/src/use-rows.js.map +1 -0
  306. package/out/zero-react/src/use-zero-virtualizer.d.ts +122 -0
  307. package/out/zero-react/src/use-zero-virtualizer.d.ts.map +1 -0
  308. package/out/zero-react/src/use-zero-virtualizer.js +342 -0
  309. package/out/zero-react/src/use-zero-virtualizer.js.map +1 -0
  310. package/out/zero-react/src/zero-provider.js +1 -1
  311. package/out/zero-react/src/zero-provider.js.map +1 -1
  312. package/out/zero-server/src/adapters/drizzle.d.ts +18 -18
  313. package/out/zero-server/src/adapters/drizzle.d.ts.map +1 -1
  314. package/out/zero-server/src/adapters/drizzle.js +8 -22
  315. package/out/zero-server/src/adapters/drizzle.js.map +1 -1
  316. package/out/zero-server/src/adapters/pg.d.ts +19 -13
  317. package/out/zero-server/src/adapters/pg.d.ts.map +1 -1
  318. package/out/zero-server/src/adapters/pg.js.map +1 -1
  319. package/out/zero-server/src/adapters/postgresjs.d.ts +19 -13
  320. package/out/zero-server/src/adapters/postgresjs.d.ts.map +1 -1
  321. package/out/zero-server/src/adapters/postgresjs.js.map +1 -1
  322. package/out/zero-server/src/adapters/prisma.d.ts +66 -0
  323. package/out/zero-server/src/adapters/prisma.d.ts.map +1 -0
  324. package/out/zero-server/src/adapters/prisma.js +63 -0
  325. package/out/zero-server/src/adapters/prisma.js.map +1 -0
  326. package/out/zero-server/src/custom.js +1 -15
  327. package/out/zero-server/src/custom.js.map +1 -1
  328. package/out/zero-server/src/mod.d.ts +9 -8
  329. package/out/zero-server/src/mod.d.ts.map +1 -1
  330. package/out/zero-server/src/process-mutations.d.ts +2 -1
  331. package/out/zero-server/src/process-mutations.d.ts.map +1 -1
  332. package/out/zero-server/src/process-mutations.js +39 -4
  333. package/out/zero-server/src/process-mutations.js.map +1 -1
  334. package/out/zero-server/src/push-processor.js +1 -1
  335. package/out/zero-server/src/push-processor.js.map +1 -1
  336. package/out/zero-server/src/schema.d.ts.map +1 -1
  337. package/out/zero-server/src/schema.js +4 -1
  338. package/out/zero-server/src/schema.js.map +1 -1
  339. package/out/zero-server/src/zql-database.d.ts.map +1 -1
  340. package/out/zero-server/src/zql-database.js +18 -0
  341. package/out/zero-server/src/zql-database.js.map +1 -1
  342. package/out/zero-solid/src/mod.d.ts +1 -1
  343. package/out/zero-solid/src/mod.d.ts.map +1 -1
  344. package/out/zero-solid/src/solid-view.js +1 -0
  345. package/out/zero-solid/src/solid-view.js.map +1 -1
  346. package/out/zero-solid/src/use-query.d.ts +10 -1
  347. package/out/zero-solid/src/use-query.d.ts.map +1 -1
  348. package/out/zero-solid/src/use-query.js +22 -5
  349. package/out/zero-solid/src/use-query.js.map +1 -1
  350. package/out/zero-solid/src/use-zero.js +1 -1
  351. package/out/zero-solid/src/use-zero.js.map +1 -1
  352. package/out/zql/src/ivm/constraint.d.ts.map +1 -1
  353. package/out/zql/src/ivm/constraint.js +4 -1
  354. package/out/zql/src/ivm/constraint.js.map +1 -1
  355. package/out/zql/src/ivm/exists.d.ts.map +1 -1
  356. package/out/zql/src/ivm/exists.js +4 -1
  357. package/out/zql/src/ivm/exists.js.map +1 -1
  358. package/out/zql/src/ivm/join-utils.d.ts.map +1 -1
  359. package/out/zql/src/ivm/join-utils.js +8 -2
  360. package/out/zql/src/ivm/join-utils.js.map +1 -1
  361. package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
  362. package/out/zql/src/ivm/memory-source.js +12 -3
  363. package/out/zql/src/ivm/memory-source.js.map +1 -1
  364. package/out/zql/src/ivm/push-accumulated.d.ts.map +1 -1
  365. package/out/zql/src/ivm/push-accumulated.js +25 -2
  366. package/out/zql/src/ivm/push-accumulated.js.map +1 -1
  367. package/out/zql/src/ivm/stream.d.ts.map +1 -1
  368. package/out/zql/src/ivm/stream.js +1 -1
  369. package/out/zql/src/ivm/stream.js.map +1 -1
  370. package/out/zql/src/ivm/take.d.ts.map +1 -1
  371. package/out/zql/src/ivm/take.js +24 -6
  372. package/out/zql/src/ivm/take.js.map +1 -1
  373. package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
  374. package/out/zql/src/ivm/union-fan-in.js +12 -3
  375. package/out/zql/src/ivm/union-fan-in.js.map +1 -1
  376. package/out/zql/src/mutate/mutator.js +4 -4
  377. package/out/zql/src/mutate/mutator.js.map +1 -1
  378. package/out/zql/src/query/create-builder.js +3 -5
  379. package/out/zql/src/query/create-builder.js.map +1 -1
  380. package/out/zql/src/query/query-registry.js +4 -4
  381. package/out/zql/src/query/query-registry.js.map +1 -1
  382. package/out/zqlite/src/table-source.d.ts.map +1 -1
  383. package/out/zqlite/src/table-source.js +1 -2
  384. package/out/zqlite/src/table-source.js.map +1 -1
  385. package/package.json +8 -4
  386. package/out/zero-cache/src/services/change-source/column-metadata.d.ts.map +0 -1
  387. package/out/zero-cache/src/services/change-source/column-metadata.js.map +0 -1
  388. package/out/zero-cache/src/types/schema-versions.d.ts +0 -12
  389. package/out/zero-cache/src/types/schema-versions.d.ts.map +0 -1
  390. package/out/zero-cache/src/types/schema-versions.js +0 -28
  391. package/out/zero-cache/src/types/schema-versions.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"write-authorizer.js","sources":["../../../../../zero-cache/src/auth/write-authorizer.ts"],"sourcesContent":["import type {SQLQuery} from '@databases/sql';\nimport type {MaybePromise} from '@opentelemetry/resources';\nimport type {LogContext} from '@rocicorp/logger';\nimport type {JWTPayload} from 'jose';\nimport {assert} from '../../../shared/src/asserts.ts';\nimport type {JSONValue, ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport {must} from '../../../shared/src/must.ts';\nimport * as v from '../../../shared/src/valita.ts';\nimport type {Condition} from '../../../zero-protocol/src/ast.ts';\nimport {\n primaryKeyValueSchema,\n type PrimaryKeyValue,\n} from '../../../zero-protocol/src/primary-key.ts';\nimport type {\n CRUDOp,\n DeleteOp,\n InsertOp,\n UpdateOp,\n UpsertOp,\n} from '../../../zero-protocol/src/push.ts';\nimport type {Policy} from '../../../zero-schema/src/compiled-permissions.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport type {BuilderDelegate} from '../../../zql/src/builder/builder.ts';\nimport {\n bindStaticParameters,\n buildPipeline,\n} from '../../../zql/src/builder/builder.ts';\nimport {consume} from '../../../zql/src/ivm/stream.ts';\nimport {simplifyCondition} from '../../../zql/src/query/expression.ts';\nimport {asQueryInternals} from '../../../zql/src/query/query-internals.ts';\nimport type {Query} from '../../../zql/src/query/query.ts';\nimport {newStaticQuery} from '../../../zql/src/query/static-query.ts';\nimport type {\n ClientGroupStorage,\n DatabaseStorage,\n} from '../../../zqlite/src/database-storage.ts';\nimport type {Database} from '../../../zqlite/src/db.ts';\nimport {compile, sql} from '../../../zqlite/src/internal/sql.ts';\nimport {\n fromSQLiteTypes,\n TableSource,\n} from '../../../zqlite/src/table-source.ts';\nimport type {LogConfig, ZeroConfig} from '../config/zero-config.ts';\nimport {computeZqlSpecs} from '../db/lite-tables.ts';\nimport type {LiteAndZqlSpec} from '../db/specs.ts';\nimport {StatementRunner} from '../db/statements.ts';\nimport {mapLiteDataTypeToZqlSchemaValue} from '../types/lite.ts';\nimport {\n getSchema,\n reloadPermissionsIfChanged,\n type LoadedPermissions,\n} from './load-permissions.ts';\n\ntype Phase = 'preMutation' | 'postMutation';\n\nexport interface WriteAuthorizer {\n canPreMutation(\n authData: JWTPayload | undefined,\n ops: Exclude<CRUDOp, UpsertOp>[],\n ): Promise<boolean>;\n canPostMutation(\n authData: JWTPayload | undefined,\n ops: Exclude<CRUDOp, UpsertOp>[],\n ): Promise<boolean>;\n reloadPermissions(): void;\n normalizeOps(ops: CRUDOp[]): Exclude<CRUDOp, UpsertOp>[];\n}\n\nexport class WriteAuthorizerImpl implements WriteAuthorizer {\n readonly #schema: Schema;\n readonly #replica: Database;\n readonly #builderDelegate: BuilderDelegate;\n readonly #tableSpecs: Map<string, LiteAndZqlSpec>;\n readonly #tables = new Map<string, TableSource>();\n readonly #statementRunner: StatementRunner;\n readonly #lc: LogContext;\n readonly #appID: string;\n readonly #logConfig: LogConfig;\n readonly #cgStorage: ClientGroupStorage;\n\n #loadedPermissions: LoadedPermissions | null = null;\n\n constructor(\n lc: LogContext,\n config: ZeroConfig,\n replica: Database,\n appID: string,\n cgID: string,\n writeAuthzStorage: DatabaseStorage,\n ) {\n this.#appID = appID;\n this.#lc = lc.withContext('class', 'WriteAuthorizerImpl');\n this.#logConfig = config.log;\n this.#schema = getSchema(this.#lc, replica);\n this.#replica = replica;\n this.#cgStorage = writeAuthzStorage.createClientGroupStorage(cgID);\n this.#builderDelegate = {\n getSource: name => this.#getSource(name),\n createStorage: () => this.#cgStorage.createStorage(),\n decorateSourceInput: input => input,\n decorateInput: input => input,\n addEdge() {},\n decorateFilterInput: input => input,\n };\n this.#tableSpecs = computeZqlSpecs(this.#lc, replica);\n this.#statementRunner = new StatementRunner(replica);\n this.reloadPermissions();\n }\n\n reloadPermissions() {\n this.#loadedPermissions = reloadPermissionsIfChanged(\n this.#lc,\n this.#statementRunner,\n this.#appID,\n this.#loadedPermissions,\n ).permissions;\n }\n\n destroy() {\n this.#cgStorage.destroy();\n }\n\n async canPreMutation(\n authData: JWTPayload | undefined,\n ops: Exclude<CRUDOp, UpsertOp>[],\n ) {\n for (const op of ops) {\n switch (op.op) {\n case 'insert':\n // insert does not run pre-mutation checks\n break;\n case 'update':\n if (!(await this.#canUpdate('preMutation', authData, op))) {\n return false;\n }\n break;\n case 'delete':\n if (!(await this.#canDelete('preMutation', authData, op))) {\n return false;\n }\n break;\n }\n }\n return true;\n }\n\n async canPostMutation(\n authData: JWTPayload | undefined,\n ops: Exclude<CRUDOp, UpsertOp>[],\n ) {\n this.#statementRunner.beginConcurrent();\n try {\n for (const op of ops) {\n const source = this.#getSource(op.tableName);\n switch (op.op) {\n case 'insert': {\n consume(\n source.push({\n type: 'add',\n row: op.value,\n }),\n );\n break;\n }\n // TODO(mlaw): what if someone updates the same thing twice?\n // TODO(aa): It seems like it will just work? source.push()\n // is going to push the row into the table source, and then the\n // next requirePreMutationRow will just return the row that was\n // pushed in.\n case 'update': {\n consume(\n source.push({\n type: 'edit',\n oldRow: this.#requirePreMutationRow(op),\n row: op.value,\n }),\n );\n break;\n }\n case 'delete': {\n consume(\n source.push({\n type: 'remove',\n row: this.#requirePreMutationRow(op),\n }),\n );\n break;\n }\n }\n }\n\n for (const op of ops) {\n switch (op.op) {\n case 'insert':\n if (!(await this.#canInsert('postMutation', authData, op))) {\n return false;\n }\n break;\n case 'update':\n if (!(await this.#canUpdate('postMutation', authData, op))) {\n return false;\n }\n break;\n case 'delete':\n // delete does not run post-mutation checks.\n break;\n }\n }\n } finally {\n this.#statementRunner.rollback();\n }\n\n return true;\n }\n\n normalizeOps(ops: CRUDOp[]): Exclude<CRUDOp, UpsertOp>[] {\n return ops.map(op => {\n if (op.op === 'upsert') {\n const preMutationRow = this.#getPreMutationRow(op);\n if (preMutationRow) {\n return {\n op: 'update',\n tableName: op.tableName,\n primaryKey: op.primaryKey,\n value: op.value,\n };\n }\n return {\n op: 'insert',\n tableName: op.tableName,\n primaryKey: op.primaryKey,\n value: op.value,\n };\n }\n return op;\n });\n }\n\n #canInsert(phase: Phase, authData: JWTPayload | undefined, op: InsertOp) {\n return this.#timedCanDo(phase, 'insert', authData, op);\n }\n\n #canUpdate(phase: Phase, authData: JWTPayload | undefined, op: UpdateOp) {\n return this.#timedCanDo(phase, 'update', authData, op);\n }\n\n #canDelete(phase: Phase, authData: JWTPayload | undefined, op: DeleteOp) {\n return this.#timedCanDo(phase, 'delete', authData, op);\n }\n\n /**\n * Gets schema-defined primary key and validates that operation contains required PK values.\n *\n * @returns Record where keys are column names and values are client-provided values\n * @throws Error if operation value is missing required primary key columns\n */\n #getPrimaryKey(\n tableName: string,\n opValue: Record<string, ReadonlyJSONValue | undefined>,\n ): Record<string, ReadonlyJSONValue> {\n const tableSpec = this.#tableSpecs.get(tableName);\n if (!tableSpec) {\n throw new Error(`Table ${tableName} not found`);\n }\n const columns = tableSpec.tableSpec.primaryKey;\n\n // Extract primary key values from operation value and validate they exist\n const values: Record<string, ReadonlyJSONValue> = {};\n for (const col of columns) {\n const val = opValue[col];\n if (val === undefined) {\n throw new Error(\n `Primary key column '${col}' is missing from operation value for table ${tableName}`,\n );\n }\n values[col] = val;\n }\n\n return values;\n }\n\n #getSource(tableName: string) {\n let source = this.#tables.get(tableName);\n if (source) {\n return source;\n }\n const tableSpec = this.#tableSpecs.get(tableName);\n if (!tableSpec) {\n throw new Error(`Table ${tableName} not found`);\n }\n const {columns, primaryKey} = tableSpec.tableSpec;\n assert(primaryKey.length);\n source = new TableSource(\n this.#lc,\n this.#logConfig,\n this.#replica,\n tableName,\n Object.fromEntries(\n Object.entries(columns).map(([name, {dataType}]) => [\n name,\n mapLiteDataTypeToZqlSchemaValue(dataType),\n ]),\n ),\n [primaryKey[0], ...primaryKey.slice(1)],\n );\n this.#tables.set(tableName, source);\n\n return source;\n }\n\n async #timedCanDo<A extends keyof ActionOpMap>(\n phase: Phase,\n action: A,\n authData: JWTPayload | undefined,\n op: ActionOpMap[A],\n ) {\n const start = performance.now();\n try {\n const ret = await this.#canDo(phase, action, authData, op);\n return ret;\n } finally {\n this.#lc.info?.(\n 'action:',\n action,\n 'duration:',\n performance.now() - start,\n 'tableName:',\n op.tableName,\n 'primaryKey:',\n op.primaryKey,\n );\n }\n }\n\n /**\n * Evaluation order is from static to dynamic, broad to specific.\n * table -> column -> row -> cell.\n *\n * If any step fails, the entire operation is denied.\n *\n * That is, table rules supersede column rules, which supersede row rules,\n *\n * All steps must allow for the operation to be allowed.\n */\n async #canDo<A extends keyof ActionOpMap>(\n phase: Phase,\n action: A,\n authData: JWTPayload | undefined,\n op: ActionOpMap[A],\n ) {\n const rules = must(this.#loadedPermissions)?.permissions?.tables?.[\n op.tableName\n ];\n const rowPolicies = rules?.row;\n let rowQuery = newStaticQuery(this.#schema, op.tableName);\n\n const primaryKeyValues = this.#getPrimaryKey(op.tableName, op.value);\n\n for (const pk in primaryKeyValues) {\n rowQuery = rowQuery.where(pk, '=', primaryKeyValues[pk]);\n }\n\n let applicableRowPolicy: Policy | undefined;\n switch (action) {\n case 'insert':\n if (phase === 'postMutation') {\n applicableRowPolicy = rowPolicies?.insert;\n }\n break;\n case 'update':\n if (phase === 'preMutation') {\n applicableRowPolicy = rowPolicies?.update?.preMutation;\n } else if (phase === 'postMutation') {\n applicableRowPolicy = rowPolicies?.update?.postMutation;\n }\n break;\n case 'delete':\n if (phase === 'preMutation') {\n applicableRowPolicy = rowPolicies?.delete;\n }\n break;\n }\n\n const cellPolicies = rules?.cell;\n const applicableCellPolicies: Policy[] = [];\n if (cellPolicies) {\n for (const [column, policy] of Object.entries(cellPolicies)) {\n if (action === 'update' && op.value[column] === undefined) {\n // If the cell is not being updated, we do not need to check\n // the cell rules.\n continue;\n }\n switch (action) {\n case 'insert':\n if (policy.insert && phase === 'postMutation') {\n applicableCellPolicies.push(policy.insert);\n }\n break;\n case 'update':\n if (phase === 'preMutation' && policy.update?.preMutation) {\n applicableCellPolicies.push(policy.update.preMutation);\n }\n if (phase === 'postMutation' && policy.update?.postMutation) {\n applicableCellPolicies.push(policy.update.postMutation);\n }\n break;\n case 'delete':\n if (policy.delete && phase === 'preMutation') {\n applicableCellPolicies.push(policy.delete);\n }\n break;\n }\n }\n }\n\n if (\n !(await this.#passesPolicyGroup(\n applicableRowPolicy,\n applicableCellPolicies,\n authData,\n rowQuery,\n ))\n ) {\n this.#lc.warn?.(\n `Permission check failed for ${JSON.stringify(\n op,\n )}, action ${action}, phase ${phase}, authData: ${JSON.stringify(\n authData,\n )}, rowPolicies: ${JSON.stringify(\n applicableRowPolicy,\n )}, cellPolicies: ${JSON.stringify(applicableCellPolicies)}`,\n );\n return false;\n }\n\n return true;\n }\n\n #getPreMutationRow(op: UpsertOp | UpdateOp | DeleteOp) {\n const {value} = op;\n\n const primaryKeyValues = this.#getPrimaryKey(op.tableName, value);\n\n const spec = this.#tableSpecs.get(op.tableName);\n if (!spec) {\n throw new Error(`Table ${op.tableName} not found`);\n }\n\n const conditions: SQLQuery[] = [];\n const values: PrimaryKeyValue[] = [];\n for (const pk in primaryKeyValues) {\n conditions.push(sql`${sql.ident(pk)}=?`);\n values.push(v.parse(primaryKeyValues[pk], primaryKeyValueSchema));\n }\n\n const ret = this.#statementRunner.get(\n compile(\n sql`SELECT ${sql.join(\n Object.keys(spec.zqlSpec).map(c => sql.ident(c)),\n sql`,`,\n )} FROM ${sql.ident(op.tableName)} WHERE ${sql.join(\n conditions,\n sql` AND `,\n )}`,\n ),\n ...values,\n );\n if (ret === undefined) {\n return ret;\n }\n return fromSQLiteTypes(spec.zqlSpec, ret, op.tableName);\n }\n\n #requirePreMutationRow(op: UpdateOp | DeleteOp) {\n const ret = this.#getPreMutationRow(op);\n assert(\n ret !== undefined,\n () => `Pre-mutation row not found for ${JSON.stringify(op.value)}`,\n );\n return ret;\n }\n\n async #passesPolicyGroup(\n applicableRowPolicy: Policy | undefined,\n applicableCellPolicies: Policy[],\n authData: JWTPayload | undefined,\n rowQuery: Query<string, Schema>,\n ) {\n if (!(await this.#passesPolicy(applicableRowPolicy, authData, rowQuery))) {\n return false;\n }\n\n for (const policy of applicableCellPolicies) {\n if (!(await this.#passesPolicy(policy, authData, rowQuery))) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Defaults to *false* if the policy is empty. At least one rule has to pass\n * for the policy to pass.\n */\n #passesPolicy(\n policy: Policy | undefined,\n authData: JWTPayload | undefined,\n rowQuery: Query<string, Schema>,\n ): MaybePromise<boolean> {\n if (policy === undefined) {\n return false;\n }\n if (policy.length === 0) {\n return false;\n }\n let rowQueryAst = asQueryInternals(rowQuery).ast;\n rowQueryAst = bindStaticParameters(\n {\n ...rowQueryAst,\n where: updateWhere(rowQueryAst.where, policy),\n },\n {\n authData: authData as Record<string, JSONValue>,\n preMutationRow: undefined,\n },\n );\n\n // call the compiler directly\n // run the sql against upstream.\n // remove the collecting into json? just need to know if a row comes back.\n\n const input = buildPipeline(rowQueryAst, this.#builderDelegate, 'query-id');\n try {\n const res = input.fetch({});\n for (const _ of res) {\n // if any row is returned at all, the\n // rule passes.\n return true;\n }\n } finally {\n input.destroy();\n }\n\n // no rows returned by any rules? The policy fails.\n return false;\n }\n}\n\nfunction updateWhere(where: Condition | undefined, policy: Policy) {\n assert(where, 'A where condition must exist for RowQuery');\n\n return simplifyCondition({\n type: 'and',\n conditions: [\n where,\n {\n type: 'or',\n conditions: policy.map(([action, rule]) => {\n assert(action);\n return rule;\n }),\n },\n ],\n });\n}\n\ntype ActionOpMap = {\n insert: InsertOp;\n update: UpdateOp;\n delete: DeleteOp;\n};\n"],"names":["v.parse"],"mappings":"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"}
1
+ {"version":3,"file":"write-authorizer.js","sources":["../../../../../zero-cache/src/auth/write-authorizer.ts"],"sourcesContent":["import type {SQLQuery} from '@databases/sql';\nimport type {MaybePromise} from '@opentelemetry/resources';\nimport type {LogContext} from '@rocicorp/logger';\nimport type {JWTPayload} from 'jose';\nimport {assert} from '../../../shared/src/asserts.ts';\nimport type {JSONValue, ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport {must} from '../../../shared/src/must.ts';\nimport * as v from '../../../shared/src/valita.ts';\nimport type {Condition} from '../../../zero-protocol/src/ast.ts';\nimport {\n primaryKeyValueSchema,\n type PrimaryKeyValue,\n} from '../../../zero-protocol/src/primary-key.ts';\nimport type {\n CRUDOp,\n DeleteOp,\n InsertOp,\n UpdateOp,\n UpsertOp,\n} from '../../../zero-protocol/src/push.ts';\nimport type {Policy} from '../../../zero-schema/src/compiled-permissions.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport type {BuilderDelegate} from '../../../zql/src/builder/builder.ts';\nimport {\n bindStaticParameters,\n buildPipeline,\n} from '../../../zql/src/builder/builder.ts';\nimport {consume} from '../../../zql/src/ivm/stream.ts';\nimport {simplifyCondition} from '../../../zql/src/query/expression.ts';\nimport {asQueryInternals} from '../../../zql/src/query/query-internals.ts';\nimport type {Query} from '../../../zql/src/query/query.ts';\nimport {newStaticQuery} from '../../../zql/src/query/static-query.ts';\nimport type {\n ClientGroupStorage,\n DatabaseStorage,\n} from '../../../zqlite/src/database-storage.ts';\nimport type {Database} from '../../../zqlite/src/db.ts';\nimport {compile, sql} from '../../../zqlite/src/internal/sql.ts';\nimport {\n fromSQLiteTypes,\n TableSource,\n} from '../../../zqlite/src/table-source.ts';\nimport type {LogConfig, ZeroConfig} from '../config/zero-config.ts';\nimport {computeZqlSpecs} from '../db/lite-tables.ts';\nimport type {LiteAndZqlSpec} from '../db/specs.ts';\nimport {StatementRunner} from '../db/statements.ts';\nimport {mapLiteDataTypeToZqlSchemaValue} from '../types/lite.ts';\nimport {\n getSchema,\n reloadPermissionsIfChanged,\n type LoadedPermissions,\n} from './load-permissions.ts';\n\ntype Phase = 'preMutation' | 'postMutation';\n\nexport interface WriteAuthorizer {\n canPreMutation(\n authData: JWTPayload | undefined,\n ops: Exclude<CRUDOp, UpsertOp>[],\n ): Promise<boolean>;\n canPostMutation(\n authData: JWTPayload | undefined,\n ops: Exclude<CRUDOp, UpsertOp>[],\n ): Promise<boolean>;\n reloadPermissions(): void;\n normalizeOps(ops: CRUDOp[]): Exclude<CRUDOp, UpsertOp>[];\n\n /**\n * Validates that all table names in the operations exist in the schema.\n * @throws Error if any table name is invalid\n */\n validateTableNames(ops: CRUDOp[]): void;\n}\n\nexport class WriteAuthorizerImpl implements WriteAuthorizer {\n readonly #schema: Schema;\n readonly #replica: Database;\n readonly #builderDelegate: BuilderDelegate;\n readonly #tableSpecs: Map<string, LiteAndZqlSpec>;\n readonly #tables = new Map<string, TableSource>();\n readonly #statementRunner: StatementRunner;\n readonly #lc: LogContext;\n readonly #appID: string;\n readonly #logConfig: LogConfig;\n readonly #cgStorage: ClientGroupStorage;\n readonly #config: ZeroConfig;\n\n #loadedPermissions: LoadedPermissions | null = null;\n\n constructor(\n lc: LogContext,\n config: ZeroConfig,\n replica: Database,\n appID: string,\n cgID: string,\n writeAuthzStorage: DatabaseStorage,\n ) {\n this.#appID = appID;\n this.#config = config;\n this.#lc = lc.withContext('class', 'WriteAuthorizerImpl');\n this.#logConfig = config.log;\n this.#schema = getSchema(this.#lc, replica);\n this.#replica = replica;\n this.#cgStorage = writeAuthzStorage.createClientGroupStorage(cgID);\n this.#builderDelegate = {\n getSource: name => this.#getSource(name),\n createStorage: () => this.#cgStorage.createStorage(),\n decorateSourceInput: input => input,\n decorateInput: input => input,\n addEdge() {},\n decorateFilterInput: input => input,\n };\n this.#tableSpecs = computeZqlSpecs(this.#lc, replica);\n this.#statementRunner = new StatementRunner(replica);\n this.reloadPermissions();\n }\n\n reloadPermissions() {\n this.#loadedPermissions = reloadPermissionsIfChanged(\n this.#lc,\n this.#statementRunner,\n this.#appID,\n this.#loadedPermissions,\n this.#config,\n ).permissions;\n }\n\n destroy() {\n this.#cgStorage.destroy();\n }\n\n async canPreMutation(\n authData: JWTPayload | undefined,\n ops: Exclude<CRUDOp, UpsertOp>[],\n ) {\n for (const op of ops) {\n switch (op.op) {\n case 'insert':\n // insert does not run pre-mutation checks\n break;\n case 'update':\n if (!(await this.#canUpdate('preMutation', authData, op))) {\n return false;\n }\n break;\n case 'delete':\n if (!(await this.#canDelete('preMutation', authData, op))) {\n return false;\n }\n break;\n }\n }\n return true;\n }\n\n async canPostMutation(\n authData: JWTPayload | undefined,\n ops: Exclude<CRUDOp, UpsertOp>[],\n ) {\n this.#statementRunner.beginConcurrent();\n try {\n for (const op of ops) {\n const source = this.#getSource(op.tableName);\n switch (op.op) {\n case 'insert': {\n consume(\n source.push({\n type: 'add',\n row: op.value,\n }),\n );\n break;\n }\n // TODO(mlaw): what if someone updates the same thing twice?\n // TODO(aa): It seems like it will just work? source.push()\n // is going to push the row into the table source, and then the\n // next requirePreMutationRow will just return the row that was\n // pushed in.\n case 'update': {\n consume(\n source.push({\n type: 'edit',\n oldRow: this.#requirePreMutationRow(op),\n row: op.value,\n }),\n );\n break;\n }\n case 'delete': {\n consume(\n source.push({\n type: 'remove',\n row: this.#requirePreMutationRow(op),\n }),\n );\n break;\n }\n }\n }\n\n for (const op of ops) {\n switch (op.op) {\n case 'insert':\n if (!(await this.#canInsert('postMutation', authData, op))) {\n return false;\n }\n break;\n case 'update':\n if (!(await this.#canUpdate('postMutation', authData, op))) {\n return false;\n }\n break;\n case 'delete':\n // delete does not run post-mutation checks.\n break;\n }\n }\n } finally {\n this.#statementRunner.rollback();\n }\n\n return true;\n }\n\n normalizeOps(ops: CRUDOp[]): Exclude<CRUDOp, UpsertOp>[] {\n return ops.map(op => {\n if (op.op === 'upsert') {\n const preMutationRow = this.#getPreMutationRow(op);\n if (preMutationRow) {\n return {\n op: 'update',\n tableName: op.tableName,\n primaryKey: op.primaryKey,\n value: op.value,\n };\n }\n return {\n op: 'insert',\n tableName: op.tableName,\n primaryKey: op.primaryKey,\n value: op.value,\n };\n }\n return op;\n });\n }\n\n validateTableNames(ops: CRUDOp[]): void {\n for (const op of ops) {\n if (!this.#tableSpecs.has(op.tableName)) {\n throw new Error(`Table '${op.tableName}' is not a valid table.`);\n }\n }\n }\n\n #canInsert(phase: Phase, authData: JWTPayload | undefined, op: InsertOp) {\n return this.#timedCanDo(phase, 'insert', authData, op);\n }\n\n #canUpdate(phase: Phase, authData: JWTPayload | undefined, op: UpdateOp) {\n return this.#timedCanDo(phase, 'update', authData, op);\n }\n\n #canDelete(phase: Phase, authData: JWTPayload | undefined, op: DeleteOp) {\n return this.#timedCanDo(phase, 'delete', authData, op);\n }\n\n /**\n * Gets schema-defined primary key and validates that operation contains required PK values.\n *\n * @returns Record where keys are column names and values are client-provided values\n * @throws Error if operation value is missing required primary key columns\n */\n #getPrimaryKey(\n tableName: string,\n opValue: Record<string, ReadonlyJSONValue | undefined>,\n ): Record<string, ReadonlyJSONValue> {\n const tableSpec = this.#tableSpecs.get(tableName);\n if (!tableSpec) {\n throw new Error(`Table ${tableName} not found`);\n }\n const columns = tableSpec.tableSpec.primaryKey;\n\n // Extract primary key values from operation value and validate they exist\n const values: Record<string, ReadonlyJSONValue> = {};\n for (const col of columns) {\n const val = opValue[col];\n if (val === undefined) {\n throw new Error(\n `Primary key column '${col}' is missing from operation value for table ${tableName}`,\n );\n }\n values[col] = val;\n }\n\n return values;\n }\n\n #getSource(tableName: string) {\n let source = this.#tables.get(tableName);\n if (source) {\n return source;\n }\n const tableSpec = this.#tableSpecs.get(tableName);\n if (!tableSpec) {\n throw new Error(`Table ${tableName} not found`);\n }\n const {columns, primaryKey} = tableSpec.tableSpec;\n assert(\n primaryKey.length,\n () => `Table ${tableName} must have a primary key`,\n );\n source = new TableSource(\n this.#lc,\n this.#logConfig,\n this.#replica,\n tableName,\n Object.fromEntries(\n Object.entries(columns).map(([name, {dataType}]) => [\n name,\n mapLiteDataTypeToZqlSchemaValue(dataType),\n ]),\n ),\n [primaryKey[0], ...primaryKey.slice(1)],\n );\n this.#tables.set(tableName, source);\n\n return source;\n }\n\n async #timedCanDo<A extends keyof ActionOpMap>(\n phase: Phase,\n action: A,\n authData: JWTPayload | undefined,\n op: ActionOpMap[A],\n ) {\n const start = performance.now();\n try {\n const ret = await this.#canDo(phase, action, authData, op);\n return ret;\n } finally {\n this.#lc.info?.(\n 'action:',\n action,\n 'duration:',\n performance.now() - start,\n 'tableName:',\n op.tableName,\n 'primaryKey:',\n op.primaryKey,\n );\n }\n }\n\n /**\n * Evaluation order is from static to dynamic, broad to specific.\n * table -> column -> row -> cell.\n *\n * If any step fails, the entire operation is denied.\n *\n * That is, table rules supersede column rules, which supersede row rules,\n *\n * All steps must allow for the operation to be allowed.\n */\n async #canDo<A extends keyof ActionOpMap>(\n phase: Phase,\n action: A,\n authData: JWTPayload | undefined,\n op: ActionOpMap[A],\n ) {\n const rules = must(this.#loadedPermissions)?.permissions?.tables?.[\n op.tableName\n ];\n const rowPolicies = rules?.row;\n let rowQuery = newStaticQuery(this.#schema, op.tableName);\n\n const primaryKeyValues = this.#getPrimaryKey(op.tableName, op.value);\n\n for (const pk in primaryKeyValues) {\n rowQuery = rowQuery.where(pk, '=', primaryKeyValues[pk]);\n }\n\n let applicableRowPolicy: Policy | undefined;\n switch (action) {\n case 'insert':\n if (phase === 'postMutation') {\n applicableRowPolicy = rowPolicies?.insert;\n }\n break;\n case 'update':\n if (phase === 'preMutation') {\n applicableRowPolicy = rowPolicies?.update?.preMutation;\n } else if (phase === 'postMutation') {\n applicableRowPolicy = rowPolicies?.update?.postMutation;\n }\n break;\n case 'delete':\n if (phase === 'preMutation') {\n applicableRowPolicy = rowPolicies?.delete;\n }\n break;\n }\n\n const cellPolicies = rules?.cell;\n const applicableCellPolicies: Policy[] = [];\n if (cellPolicies) {\n for (const [column, policy] of Object.entries(cellPolicies)) {\n if (action === 'update' && op.value[column] === undefined) {\n // If the cell is not being updated, we do not need to check\n // the cell rules.\n continue;\n }\n switch (action) {\n case 'insert':\n if (policy.insert && phase === 'postMutation') {\n applicableCellPolicies.push(policy.insert);\n }\n break;\n case 'update':\n if (phase === 'preMutation' && policy.update?.preMutation) {\n applicableCellPolicies.push(policy.update.preMutation);\n }\n if (phase === 'postMutation' && policy.update?.postMutation) {\n applicableCellPolicies.push(policy.update.postMutation);\n }\n break;\n case 'delete':\n if (policy.delete && phase === 'preMutation') {\n applicableCellPolicies.push(policy.delete);\n }\n break;\n }\n }\n }\n\n if (\n !(await this.#passesPolicyGroup(\n applicableRowPolicy,\n applicableCellPolicies,\n authData,\n rowQuery,\n ))\n ) {\n this.#lc.warn?.(\n `Permission check failed for ${JSON.stringify(\n op,\n )}, action ${action}, phase ${phase}, authData: ${JSON.stringify(\n authData,\n )}, rowPolicies: ${JSON.stringify(\n applicableRowPolicy,\n )}, cellPolicies: ${JSON.stringify(applicableCellPolicies)}`,\n );\n return false;\n }\n\n return true;\n }\n\n #getPreMutationRow(op: UpsertOp | UpdateOp | DeleteOp) {\n const {value} = op;\n\n const primaryKeyValues = this.#getPrimaryKey(op.tableName, value);\n\n const spec = this.#tableSpecs.get(op.tableName);\n if (!spec) {\n throw new Error(`Table ${op.tableName} not found`);\n }\n\n const conditions: SQLQuery[] = [];\n const values: PrimaryKeyValue[] = [];\n for (const pk in primaryKeyValues) {\n conditions.push(sql`${sql.ident(pk)}=?`);\n values.push(v.parse(primaryKeyValues[pk], primaryKeyValueSchema));\n }\n\n const ret = this.#statementRunner.get(\n compile(\n sql`SELECT ${sql.join(\n Object.keys(spec.zqlSpec).map(c => sql.ident(c)),\n sql`,`,\n )} FROM ${sql.ident(op.tableName)} WHERE ${sql.join(\n conditions,\n sql` AND `,\n )}`,\n ),\n ...values,\n );\n if (ret === undefined) {\n return ret;\n }\n return fromSQLiteTypes(spec.zqlSpec, ret, op.tableName);\n }\n\n #requirePreMutationRow(op: UpdateOp | DeleteOp) {\n const ret = this.#getPreMutationRow(op);\n assert(\n ret !== undefined,\n () => `Pre-mutation row not found for ${JSON.stringify(op.value)}`,\n );\n return ret;\n }\n\n async #passesPolicyGroup(\n applicableRowPolicy: Policy | undefined,\n applicableCellPolicies: Policy[],\n authData: JWTPayload | undefined,\n rowQuery: Query<string, Schema>,\n ) {\n if (!(await this.#passesPolicy(applicableRowPolicy, authData, rowQuery))) {\n return false;\n }\n\n for (const policy of applicableCellPolicies) {\n if (!(await this.#passesPolicy(policy, authData, rowQuery))) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Defaults to *false* if the policy is empty. At least one rule has to pass\n * for the policy to pass.\n */\n #passesPolicy(\n policy: Policy | undefined,\n authData: JWTPayload | undefined,\n rowQuery: Query<string, Schema>,\n ): MaybePromise<boolean> {\n if (policy === undefined) {\n return false;\n }\n if (policy.length === 0) {\n return false;\n }\n let rowQueryAst = asQueryInternals(rowQuery).ast;\n rowQueryAst = bindStaticParameters(\n {\n ...rowQueryAst,\n where: updateWhere(rowQueryAst.where, policy),\n },\n {\n authData: authData as Record<string, JSONValue>,\n preMutationRow: undefined,\n },\n );\n\n // call the compiler directly\n // run the sql against upstream.\n // remove the collecting into json? just need to know if a row comes back.\n\n const input = buildPipeline(rowQueryAst, this.#builderDelegate, 'query-id');\n try {\n const res = input.fetch({});\n for (const _ of res) {\n // if any row is returned at all, the\n // rule passes.\n return true;\n }\n } finally {\n input.destroy();\n }\n\n // no rows returned by any rules? The policy fails.\n return false;\n }\n}\n\nfunction updateWhere(where: Condition | undefined, policy: Policy) {\n assert(where, 'A where condition must exist for RowQuery');\n\n return simplifyCondition({\n type: 'and',\n conditions: [\n where,\n {\n type: 'or',\n conditions: policy.map(([action, rule]) => {\n assert(action, 'action must be defined in policy');\n return rule;\n }),\n },\n ],\n });\n}\n\ntype ActionOpMap = {\n insert: InsertOp;\n update: UpdateOp;\n delete: DeleteOp;\n};\n"],"names":["v.parse"],"mappings":"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"}
@@ -6,6 +6,8 @@ import { type Config, type ParseOptions } from '../../../shared/src/options.ts';
6
6
  import * as v from '../../../shared/src/valita.ts';
7
7
  import { type NormalizedZeroConfig } from './normalize.ts';
8
8
  export type { LogConfig } from '../../../otel/src/log-options.ts';
9
+ export declare const ZERO_ENV_VAR_PREFIX = "ZERO_";
10
+ export declare const DEFAULT_BACK_PRESSURE_THRESHOLD = 100000;
9
11
  export declare const appOptions: {
10
12
  id: {
11
13
  type: v.Type<string>;
@@ -36,10 +38,6 @@ declare const replicaOptions: {
36
38
  type: v.Optional<number>;
37
39
  desc: string[];
38
40
  };
39
- pageCacheSizeKib: {
40
- type: v.Optional<number>;
41
- desc: string[];
42
- };
43
41
  };
44
42
  export type ReplicaOptions = Config<typeof replicaOptions>;
45
43
  declare const perUserMutationLimit: {
@@ -69,6 +67,16 @@ declare const authOptions: {
69
67
  desc: string[];
70
68
  deprecated: string[];
71
69
  };
70
+ issuer: {
71
+ type: v.Optional<string>;
72
+ desc: string[];
73
+ deprecated: string[];
74
+ };
75
+ audience: {
76
+ type: v.Optional<string>;
77
+ desc: string[];
78
+ deprecated: string[];
79
+ };
72
80
  };
73
81
  /** @deprecated */
74
82
  export type AuthConfig = Config<typeof authOptions>;
@@ -109,6 +117,11 @@ export declare const zeroOptions: {
109
117
  type: v.Type<boolean>;
110
118
  desc: string[];
111
119
  };
120
+ allowedClientHeaders: {
121
+ deprecated?: string[];
122
+ type: v.Optional<string[]>;
123
+ desc: string[];
124
+ };
112
125
  };
113
126
  mutate: {
114
127
  url: {
@@ -126,6 +139,11 @@ export declare const zeroOptions: {
126
139
  type: v.Type<boolean>;
127
140
  desc: string[];
128
141
  };
142
+ allowedClientHeaders: {
143
+ deprecated?: string[];
144
+ type: v.Optional<string[]>;
145
+ desc: string[];
146
+ };
129
147
  };
130
148
  /** @deprecated */
131
149
  getQueries: {
@@ -144,6 +162,11 @@ export declare const zeroOptions: {
144
162
  type: v.Type<boolean>;
145
163
  desc: string[];
146
164
  };
165
+ allowedClientHeaders: {
166
+ deprecated?: string[];
167
+ type: v.Optional<string[]>;
168
+ desc: string[];
169
+ };
147
170
  };
148
171
  query: {
149
172
  url: {
@@ -161,6 +184,11 @@ export declare const zeroOptions: {
161
184
  type: v.Type<boolean>;
162
185
  desc: string[];
163
186
  };
187
+ allowedClientHeaders: {
188
+ deprecated?: string[];
189
+ type: v.Optional<string[]>;
190
+ desc: string[];
191
+ };
164
192
  };
165
193
  cvr: {
166
194
  db: {
@@ -219,10 +247,6 @@ export declare const zeroOptions: {
219
247
  type: v.Optional<number>;
220
248
  desc: string[];
221
249
  };
222
- pageCacheSizeKib: {
223
- type: v.Optional<number>;
224
- desc: string[];
225
- };
226
250
  };
227
251
  log: {
228
252
  level: v.Type<"error" | "debug" | "info" | "warn">;
@@ -281,6 +305,16 @@ export declare const zeroOptions: {
281
305
  desc: string[];
282
306
  deprecated: string[];
283
307
  };
308
+ issuer: {
309
+ type: v.Optional<string>;
310
+ desc: string[];
311
+ deprecated: string[];
312
+ };
313
+ audience: {
314
+ type: v.Optional<string>;
315
+ desc: string[];
316
+ deprecated: string[];
317
+ };
284
318
  };
285
319
  port: {
286
320
  type: v.Type<number>;
@@ -320,6 +354,10 @@ export declare const zeroOptions: {
320
354
  type: v.Type<number>;
321
355
  desc: string[];
322
356
  };
357
+ backPressureThreshold: {
358
+ type: v.Type<number>;
359
+ desc: string[];
360
+ };
323
361
  };
324
362
  taskID: {
325
363
  type: v.Optional<string>;
@@ -355,6 +393,10 @@ export declare const zeroOptions: {
355
393
  type: v.Optional<string>;
356
394
  desc: string[];
357
395
  };
396
+ websocketMaxPayloadBytes: {
397
+ type: v.Type<number>;
398
+ desc: string[];
399
+ };
358
400
  litestream: {
359
401
  executable: {
360
402
  type: v.Optional<string>;
@@ -371,6 +413,10 @@ export declare const zeroOptions: {
371
413
  type: v.Optional<string>;
372
414
  desc: string[];
373
415
  };
416
+ endpoint: {
417
+ type: v.Optional<string>;
418
+ desc: string[];
419
+ };
374
420
  port: {
375
421
  type: v.Optional<number>;
376
422
  desc: string[];
@@ -453,7 +499,6 @@ export declare const zeroOptions: {
453
499
  };
454
500
  };
455
501
  export type ZeroConfig = Config<typeof zeroOptions>;
456
- export declare const ZERO_ENV_VAR_PREFIX = "ZERO_";
457
502
  export declare function getZeroConfig(opts?: Omit<ParseOptions, 'envNamePrefix'>): ZeroConfig;
458
503
  /**
459
504
  * Same as {@link getZeroConfig}, with an additional check that the
@@ -1 +1 @@
1
- {"version":3,"file":"zero-config.d.ts","sourceRoot":"","sources":["../../../../../zero-cache/src/config/zero-config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAEjD,OAAO,EAEL,KAAK,MAAM,EACX,KAAK,YAAY,EAClB,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,CAAC,MAAM,+BAA+B,CAAC;AASnD,OAAO,EAGL,KAAK,oBAAoB,EAC1B,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAC,SAAS,EAAC,MAAM,kCAAkC,CAAC;AAEhE,eAAO,MAAM,UAAU;;;;;;;;;CA+CtB,CAAC;AAEF,eAAO,MAAM,YAAY;;;;;;;;;;CAwBxB,CAAC;AAEF,QAAA,MAAM,cAAc;;;;;;;;;;;;;CAgCnB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,cAAc,CAAC,CAAC;AAE3D,QAAA,MAAM,oBAAoB;;;;;;;;;CAczB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAE5D,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;CA4BhB,CAAC;AAmFF,kBAAkB;AAClB,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,WAAW,CAAC,CAAC;AAKpD,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;IAwCtB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAGlB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAuHlB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA6ChB,kBAAkB;;;;;;QASlB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAoQpB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgEnB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,WAAW,CAAC,CAAC;AAEpD,eAAO,MAAM,mBAAmB,UAAU,CAAC;AAI3C,wBAAgB,aAAa,CAC3B,IAAI,GAAE,IAAI,CAAC,YAAY,EAAE,eAAe,CAAM,GAC7C,UAAU,CAaZ;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,GAAE,IAAI,CAAC,YAAY,EAAE,eAAe,CAAM,GAC7C,oBAAoB,CAItB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,GAAG,SAAS,GACpD,MAAM,CAER;AAED,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,UAAU,EACd,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,eAAe,CAAC,EACnD,QAAQ,EAAE,MAAM,GAAG,SAAS,WA4B7B;AAYD,wBAAgB,kBAAkB,SAEjC"}
1
+ {"version":3,"file":"zero-config.d.ts","sourceRoot":"","sources":["../../../../../zero-cache/src/config/zero-config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAEjD,OAAO,EAGL,KAAK,MAAM,EACX,KAAK,YAAY,EAClB,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,CAAC,MAAM,+BAA+B,CAAC;AASnD,OAAO,EAGL,KAAK,oBAAoB,EAC1B,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAC,SAAS,EAAC,MAAM,kCAAkC,CAAC;AAEhE,eAAO,MAAM,mBAAmB,UAAU,CAAC;AAc3C,eAAO,MAAM,+BAA+B,SAAU,CAAC;AAEvD,eAAO,MAAM,UAAU;;;;;;;;;CA+CtB,CAAC;AAEF,eAAO,MAAM,YAAY;;;;;;;;;;CAwBxB,CAAC;AAEF,QAAA,MAAM,cAAc;;;;;;;;;CAmBnB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,cAAc,CAAC,CAAC;AAE3D,QAAA,MAAM,oBAAoB;;;;;;;;;CAczB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAE5D,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;CAgDhB,CAAC;AAuGF,kBAAkB;AAClB,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,WAAW,CAAC,CAAC;AAKpD,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;IAwCtB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAGlB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAuHlB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA6ChB,kBAAkB;;;;;;QASlB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAiSpB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgEnB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,WAAW,CAAC,CAAC;AAIpD,wBAAgB,aAAa,CAC3B,IAAI,GAAE,IAAI,CAAC,YAAY,EAAE,eAAe,CAAM,GAC7C,UAAU,CAaZ;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,GAAE,IAAI,CAAC,YAAY,EAAE,eAAe,CAAM,GAC7C,oBAAoB,CAItB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,GAAG,SAAS,GACpD,MAAM,CAER;AAED,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,UAAU,EACd,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,eAAe,CAAC,EACnD,QAAQ,EAAE,MAAM,GAAG,SAAS,WAwC7B;AAYD,wBAAgB,kBAAkB,SAEjC"}
@@ -1,5 +1,6 @@
1
+ import { timingSafeEqual } from "node:crypto";
1
2
  import { logOptions } from "../../../otel/src/log-options.js";
2
- import { parseOptions } from "../../../shared/src/options.js";
3
+ import { flagToEnv, parseOptions } from "../../../shared/src/options.js";
3
4
  import { literalUnion } from "../../../shared/src/valita.js";
4
5
  import packageJson from "../../../zero/package.json.js";
5
6
  import { runtimeDebugFlags } from "../../../zql/src/builder/debug-delegate.js";
@@ -7,6 +8,8 @@ import { singleProcessMode } from "../types/processes.js";
7
8
  import { ALLOWED_APP_ID_CHARACTERS, INVALID_APP_ID_MESSAGE } from "../types/shards.js";
8
9
  import { assertNormalized, isDevelopmentMode } from "./normalize.js";
9
10
  import { array, string, number, boolean } from "@badrap/valita";
11
+ const ZERO_ENV_VAR_PREFIX = "ZERO_";
12
+ const DEFAULT_BACK_PRESSURE_THRESHOLD = 1e5;
10
13
  const appOptions = {
11
14
  id: {
12
15
  type: string().default("zero").assert((id) => ALLOWED_APP_ID_CHARACTERS.test(id), INVALID_APP_ID_MESSAGE),
@@ -89,18 +92,6 @@ const replicaOptions = {
89
92
  `and requires double the size of the db in disk space. If unspecified, VACUUM`,
90
93
  `operations are not performed.`
91
94
  ]
92
- },
93
- pageCacheSizeKib: {
94
- type: number().optional(),
95
- desc: [
96
- `The SQLite page cache size in kibibytes (KiB) for view-syncer connections.`,
97
- `The page cache stores recently accessed database pages in memory to reduce disk I/O.`,
98
- `Larger cache sizes improve performance for workloads that fit in cache.`,
99
- `If unspecified, SQLite's default (~2 MB) is used.`,
100
- `Note that the effective memory use of this setting will be:`,
101
- `2 * cache_size * num_cores as each connection to the replica gets its own cache`,
102
- `and each core maintains 2 connections.`
103
- ]
104
95
  }
105
96
  };
106
97
  const perUserMutationLimit = {
@@ -145,8 +136,29 @@ const authOptions = {
145
136
  deprecated: [
146
137
  `Use cookie-based authentication or an auth token instead - see https://zero.rocicorp.dev/docs/auth.`
147
138
  ]
139
+ },
140
+ issuer: {
141
+ type: string().optional(),
142
+ desc: [
143
+ `Expected issuer ({bold iss} claim) for JWT validation.`,
144
+ `If set, tokens with a different or missing issuer will be rejected.`
145
+ ],
146
+ deprecated: [
147
+ `Use cookie-based authentication or an auth token instead - see https://zero.rocicorp.dev/docs/auth.`
148
+ ]
149
+ },
150
+ audience: {
151
+ type: string().optional(),
152
+ desc: [
153
+ `Expected audience ({bold aud} claim) for JWT validation.`,
154
+ `If set, tokens with a different or missing audience will be rejected.`
155
+ ],
156
+ deprecated: [
157
+ `Use cookie-based authentication or an auth token instead - see https://zero.rocicorp.dev/docs/auth.`
158
+ ]
148
159
  }
149
160
  };
161
+ const makeDeprecationMessage = (flag) => `Use {bold ${flagToEnv(ZERO_ENV_VAR_PREFIX, flag)}} (or {bold --${flag}}) instead.`;
150
162
  const makeMutatorQueryOptions = (replacement, suffix) => ({
151
163
  url: {
152
164
  type: array(string()).optional(),
@@ -192,14 +204,14 @@ const makeMutatorQueryOptions = (replacement, suffix) => ({
192
204
  ``,
193
205
  `For full URLPattern syntax, see: https://developer.mozilla.org/en-US/docs/Web/API/URLPattern`
194
206
  ],
195
- ...replacement ? { deprecated: [`Use {bold ${replacement}} instead.`] } : {}
207
+ ...replacement ? { deprecated: [makeDeprecationMessage(`${replacement}-url`)] } : {}
196
208
  },
197
209
  apiKey: {
198
210
  type: string().optional(),
199
211
  desc: [
200
212
  `An optional secret used to authorize zero-cache to call the API server handling writes.`
201
213
  ],
202
- ...replacement ? { deprecated: [`Use {bold ${replacement}-api-key} instead.`] } : {}
214
+ ...replacement ? { deprecated: [makeDeprecationMessage(`${replacement}-api-key`)] } : {}
203
215
  },
204
216
  forwardCookies: {
205
217
  type: boolean().default(false),
@@ -208,14 +220,29 @@ const makeMutatorQueryOptions = (replacement, suffix) => ({
208
220
  `This is useful for passing authentication cookies to the API server.`,
209
221
  `If false, cookies are not forwarded.`
210
222
  ],
211
- ...replacement ? { deprecated: [`Use {bold ${replacement}-forward-cookies} instead.`] } : {}
223
+ ...replacement ? { deprecated: [makeDeprecationMessage(`${replacement}-forward-cookies`)] } : {}
224
+ },
225
+ allowedClientHeaders: {
226
+ type: array(string()).optional(),
227
+ desc: [
228
+ `A list of header names that clients are allowed to set via custom headers.`,
229
+ `If specified, only headers in this list will be forwarded to the ${suffix === "push mutations" ? "push" : "query"} URL.`,
230
+ `Header names are case-insensitive.`,
231
+ `If not specified, no client-provided headers are forwarded (secure by default).`,
232
+ `Example: ZERO_${replacement ? replacement.toUpperCase() : suffix === "push mutations" ? "MUTATE" : "QUERY"}_ALLOWED_CLIENT_HEADERS=x-request-id,x-correlation-id`
233
+ ],
234
+ ...replacement ? {
235
+ deprecated: [
236
+ makeDeprecationMessage(`${replacement}-allowed-client-headers`)
237
+ ]
238
+ } : {}
212
239
  }
213
240
  });
214
241
  const mutateOptions = makeMutatorQueryOptions(void 0, "push mutations");
215
- const pushOptions = makeMutatorQueryOptions("mutate-url", "push mutations");
242
+ const pushOptions = makeMutatorQueryOptions("mutate", "push mutations");
216
243
  const queryOptions = makeMutatorQueryOptions(void 0, "send synced queries");
217
244
  const getQueriesOptions = makeMutatorQueryOptions(
218
- "query-url",
245
+ "query",
219
246
  "send synced queries"
220
247
  );
221
248
  const zeroOptions = {
@@ -446,6 +473,16 @@ const zeroOptions = {
446
473
  `is received during this interval, the delay will be canceled and the takeover will happen`,
447
474
  `immediately, since the incoming request indicates that the task is registered as a target.`
448
475
  ]
476
+ },
477
+ backPressureThreshold: {
478
+ type: number().default(DEFAULT_BACK_PRESSURE_THRESHOLD),
479
+ desc: [
480
+ `The maximum number of queued changes before back pressure is applied to the`,
481
+ `change source. When the queue exceeds this threshold, the change-streamer pauses`,
482
+ `consumption from upstream until the queue drops to 90% of the threshold.`,
483
+ ``,
484
+ `Increasing this value may improve throughput at the cost of higher memory usage.`
485
+ ]
449
486
  }
450
487
  },
451
488
  taskID: {
@@ -516,6 +553,15 @@ const zeroOptions = {
516
553
  "See https://github.com/websockets/ws/blob/master/doc/ws.md#new-websocketserveroptions-callback for available options."
517
554
  ]
518
555
  },
556
+ websocketMaxPayloadBytes: {
557
+ type: number().default(10 * 1024 * 1024),
558
+ desc: [
559
+ "Maximum size of incoming WebSocket messages in bytes.",
560
+ "",
561
+ "Messages exceeding this limit are rejected before parsing.",
562
+ "Default: 10MB (10 * 1024 * 1024 = 10485760)"
563
+ ]
564
+ },
519
565
  litestream: {
520
566
  executable: {
521
567
  type: string().optional(),
@@ -544,6 +590,13 @@ const zeroOptions = {
544
590
  `{bold view-syncers} receive this information from the {bold replication-manager}.`
545
591
  ]
546
592
  },
593
+ endpoint: {
594
+ type: string().optional(),
595
+ desc: [
596
+ `The S3-compatible endpoint URL to use for the litestream backup. Only required for non-AWS services.`,
597
+ `The {bold replication-manager} and {bold view-syncers} must have the same endpoint.`
598
+ ]
599
+ },
547
600
  port: {
548
601
  type: number().optional(),
549
602
  desc: [
@@ -707,7 +760,6 @@ const zeroOptions = {
707
760
  }
708
761
  }
709
762
  };
710
- const ZERO_ENV_VAR_PREFIX = "ZERO_";
711
763
  let loadedConfig;
712
764
  function getZeroConfig(opts = {}) {
713
765
  if (!loadedConfig || singleProcessMode()) {
@@ -743,7 +795,14 @@ function isAdminPasswordValid(lc, config, password) {
743
795
  lc.warn?.("No admin password set; denying access");
744
796
  return false;
745
797
  }
746
- if (password !== config.adminPassword) {
798
+ const passwordBuffer = Buffer.from(password ?? "");
799
+ const configBuffer = Buffer.from(config.adminPassword);
800
+ if (passwordBuffer.length !== configBuffer.length) {
801
+ timingSafeEqual(configBuffer, configBuffer);
802
+ lc.warn?.("Invalid admin password");
803
+ return false;
804
+ }
805
+ if (!timingSafeEqual(passwordBuffer, configBuffer)) {
747
806
  lc.warn?.("Invalid admin password");
748
807
  return false;
749
808
  }
@@ -758,6 +817,7 @@ function warnOnce(lc, msg) {
758
817
  }
759
818
  }
760
819
  export {
820
+ DEFAULT_BACK_PRESSURE_THRESHOLD,
761
821
  ZERO_ENV_VAR_PREFIX,
762
822
  appOptions,
763
823
  getNormalizedZeroConfig,