@dotdo/postgres 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1129) hide show
  1. package/README.md +868 -0
  2. package/dist/cdc/change-stream.d.ts +44 -0
  3. package/dist/cdc/change-stream.d.ts.map +1 -0
  4. package/dist/cdc/change-stream.js +95 -0
  5. package/dist/cdc/change-stream.js.map +1 -0
  6. package/dist/cdc/filter.d.ts +58 -0
  7. package/dist/cdc/filter.d.ts.map +1 -0
  8. package/dist/cdc/filter.js +520 -0
  9. package/dist/cdc/filter.js.map +1 -0
  10. package/dist/cdc/index.d.ts +47 -0
  11. package/dist/cdc/index.d.ts.map +1 -0
  12. package/dist/cdc/index.js +50 -0
  13. package/dist/cdc/index.js.map +1 -0
  14. package/dist/cdc/resume-token.d.ts +60 -0
  15. package/dist/cdc/resume-token.d.ts.map +1 -0
  16. package/dist/cdc/resume-token.js +228 -0
  17. package/dist/cdc/resume-token.js.map +1 -0
  18. package/dist/cdc/transport/index.d.ts +7 -0
  19. package/dist/cdc/transport/index.d.ts.map +1 -0
  20. package/dist/cdc/transport/index.js +7 -0
  21. package/dist/cdc/transport/index.js.map +1 -0
  22. package/dist/cdc/transport/sse.d.ts +120 -0
  23. package/dist/cdc/transport/sse.d.ts.map +1 -0
  24. package/dist/cdc/transport/sse.js +590 -0
  25. package/dist/cdc/transport/sse.js.map +1 -0
  26. package/dist/cdc/transport/websocket.d.ts +130 -0
  27. package/dist/cdc/transport/websocket.d.ts.map +1 -0
  28. package/dist/cdc/transport/websocket.js +688 -0
  29. package/dist/cdc/transport/websocket.js.map +1 -0
  30. package/dist/cdc/types.d.ts +306 -0
  31. package/dist/cdc/types.d.ts.map +1 -0
  32. package/dist/cdc/types.js +8 -0
  33. package/dist/cdc/types.js.map +1 -0
  34. package/dist/config/index.d.ts +25 -0
  35. package/dist/config/index.d.ts.map +1 -0
  36. package/dist/config/index.js +25 -0
  37. package/dist/config/index.js.map +1 -0
  38. package/dist/config/memory.d.ts +139 -0
  39. package/dist/config/memory.d.ts.map +1 -0
  40. package/dist/config/memory.js +157 -0
  41. package/dist/config/memory.js.map +1 -0
  42. package/dist/config/storage.d.ts +157 -0
  43. package/dist/config/storage.d.ts.map +1 -0
  44. package/dist/config/storage.js +178 -0
  45. package/dist/config/storage.js.map +1 -0
  46. package/dist/config/streaming.d.ts +117 -0
  47. package/dist/config/streaming.d.ts.map +1 -0
  48. package/dist/config/streaming.js +132 -0
  49. package/dist/config/streaming.js.map +1 -0
  50. package/dist/config/timeouts.d.ts +168 -0
  51. package/dist/config/timeouts.d.ts.map +1 -0
  52. package/dist/config/timeouts.js +192 -0
  53. package/dist/config/timeouts.js.map +1 -0
  54. package/dist/extensions/config.d.ts +89 -0
  55. package/dist/extensions/config.d.ts.map +1 -0
  56. package/dist/extensions/config.js +216 -0
  57. package/dist/extensions/config.js.map +1 -0
  58. package/dist/extensions/geo.d.ts +452 -0
  59. package/dist/extensions/geo.d.ts.map +1 -0
  60. package/dist/extensions/geo.js +583 -0
  61. package/dist/extensions/geo.js.map +1 -0
  62. package/dist/extensions/index.d.ts +167 -0
  63. package/dist/extensions/index.d.ts.map +1 -0
  64. package/dist/extensions/index.js +99 -0
  65. package/dist/extensions/index.js.map +1 -0
  66. package/dist/extensions/loader.d.ts +226 -0
  67. package/dist/extensions/loader.d.ts.map +1 -0
  68. package/dist/extensions/loader.js +456 -0
  69. package/dist/extensions/loader.js.map +1 -0
  70. package/dist/extensions/pgmq-lite.d.ts +330 -0
  71. package/dist/extensions/pgmq-lite.d.ts.map +1 -0
  72. package/dist/extensions/pgmq-lite.js +648 -0
  73. package/dist/extensions/pgmq-lite.js.map +1 -0
  74. package/dist/extensions/plugins.d.ts +260 -0
  75. package/dist/extensions/plugins.d.ts.map +1 -0
  76. package/dist/extensions/plugins.js +535 -0
  77. package/dist/extensions/plugins.js.map +1 -0
  78. package/dist/extensions/registry.d.ts +93 -0
  79. package/dist/extensions/registry.d.ts.map +1 -0
  80. package/dist/extensions/registry.js +182 -0
  81. package/dist/extensions/registry.js.map +1 -0
  82. package/dist/extensions/vector.d.ts +106 -0
  83. package/dist/extensions/vector.d.ts.map +1 -0
  84. package/dist/extensions/vector.js +129 -0
  85. package/dist/extensions/vector.js.map +1 -0
  86. package/dist/iceberg/analytics.d.ts +279 -0
  87. package/dist/iceberg/analytics.d.ts.map +1 -0
  88. package/dist/iceberg/analytics.js +448 -0
  89. package/dist/iceberg/analytics.js.map +1 -0
  90. package/dist/iceberg/catalog-api.d.ts +39 -0
  91. package/dist/iceberg/catalog-api.d.ts.map +1 -0
  92. package/dist/iceberg/catalog-api.js +388 -0
  93. package/dist/iceberg/catalog-api.js.map +1 -0
  94. package/dist/iceberg/catalog.d.ts +401 -0
  95. package/dist/iceberg/catalog.d.ts.map +1 -0
  96. package/dist/iceberg/catalog.js +677 -0
  97. package/dist/iceberg/catalog.js.map +1 -0
  98. package/dist/iceberg/duckdb-wasm.d.ts +447 -0
  99. package/dist/iceberg/duckdb-wasm.d.ts.map +1 -0
  100. package/dist/iceberg/duckdb-wasm.js +600 -0
  101. package/dist/iceberg/duckdb-wasm.js.map +1 -0
  102. package/dist/iceberg/index.d.ts +92 -0
  103. package/dist/iceberg/index.d.ts.map +1 -0
  104. package/dist/iceberg/index.js +119 -0
  105. package/dist/iceberg/index.js.map +1 -0
  106. package/dist/iceberg/metadata.d.ts +214 -0
  107. package/dist/iceberg/metadata.d.ts.map +1 -0
  108. package/dist/iceberg/metadata.js +535 -0
  109. package/dist/iceberg/metadata.js.map +1 -0
  110. package/dist/iceberg/optimizer.d.ts +296 -0
  111. package/dist/iceberg/optimizer.d.ts.map +1 -0
  112. package/dist/iceberg/optimizer.js +889 -0
  113. package/dist/iceberg/optimizer.js.map +1 -0
  114. package/dist/iceberg/parquet.d.ts +447 -0
  115. package/dist/iceberg/parquet.d.ts.map +1 -0
  116. package/dist/iceberg/parquet.js +1225 -0
  117. package/dist/iceberg/parquet.js.map +1 -0
  118. package/dist/iceberg/r2-organization.d.ts +422 -0
  119. package/dist/iceberg/r2-organization.d.ts.map +1 -0
  120. package/dist/iceberg/r2-organization.js +672 -0
  121. package/dist/iceberg/r2-organization.js.map +1 -0
  122. package/dist/iceberg/scheduler-do-example.d.ts +158 -0
  123. package/dist/iceberg/scheduler-do-example.d.ts.map +1 -0
  124. package/dist/iceberg/scheduler-do-example.js +261 -0
  125. package/dist/iceberg/scheduler-do-example.js.map +1 -0
  126. package/dist/iceberg/scheduler.d.ts +434 -0
  127. package/dist/iceberg/scheduler.d.ts.map +1 -0
  128. package/dist/iceberg/scheduler.js +818 -0
  129. package/dist/iceberg/scheduler.js.map +1 -0
  130. package/dist/iceberg/schema.d.ts +149 -0
  131. package/dist/iceberg/schema.d.ts.map +1 -0
  132. package/dist/iceberg/schema.js +525 -0
  133. package/dist/iceberg/schema.js.map +1 -0
  134. package/dist/iceberg/snapshot-manager.d.ts +406 -0
  135. package/dist/iceberg/snapshot-manager.d.ts.map +1 -0
  136. package/dist/iceberg/snapshot-manager.js +934 -0
  137. package/dist/iceberg/snapshot-manager.js.map +1 -0
  138. package/dist/iceberg/sql-router.d.ts +194 -0
  139. package/dist/iceberg/sql-router.d.ts.map +1 -0
  140. package/dist/iceberg/sql-router.js +180 -0
  141. package/dist/iceberg/sql-router.js.map +1 -0
  142. package/dist/iceberg/test-fixtures.d.ts +151 -0
  143. package/dist/iceberg/test-fixtures.d.ts.map +1 -0
  144. package/dist/iceberg/test-fixtures.js +446 -0
  145. package/dist/iceberg/test-fixtures.js.map +1 -0
  146. package/dist/iceberg/time-travel-api.d.ts +102 -0
  147. package/dist/iceberg/time-travel-api.d.ts.map +1 -0
  148. package/dist/iceberg/time-travel-api.js +437 -0
  149. package/dist/iceberg/time-travel-api.js.map +1 -0
  150. package/dist/iceberg/time-travel.d.ts +293 -0
  151. package/dist/iceberg/time-travel.d.ts.map +1 -0
  152. package/dist/iceberg/time-travel.js +689 -0
  153. package/dist/iceberg/time-travel.js.map +1 -0
  154. package/dist/iceberg/transformer.d.ts +356 -0
  155. package/dist/iceberg/transformer.d.ts.map +1 -0
  156. package/dist/iceberg/transformer.js +770 -0
  157. package/dist/iceberg/transformer.js.map +1 -0
  158. package/dist/iceberg/types.d.ts +318 -0
  159. package/dist/iceberg/types.d.ts.map +1 -0
  160. package/dist/iceberg/types.js +9 -0
  161. package/dist/iceberg/types.js.map +1 -0
  162. package/dist/iceberg/writer.d.ts +144 -0
  163. package/dist/iceberg/writer.d.ts.map +1 -0
  164. package/dist/iceberg/writer.js +452 -0
  165. package/dist/iceberg/writer.js.map +1 -0
  166. package/dist/index.d.ts +50 -0
  167. package/dist/index.d.ts.map +1 -0
  168. package/dist/index.js +69 -0
  169. package/dist/index.js.map +1 -0
  170. package/dist/lineage/index.d.ts +11 -0
  171. package/dist/lineage/index.d.ts.map +1 -0
  172. package/dist/lineage/index.js +11 -0
  173. package/dist/lineage/index.js.map +1 -0
  174. package/dist/lineage/integration.d.ts +134 -0
  175. package/dist/lineage/integration.d.ts.map +1 -0
  176. package/dist/lineage/integration.js +258 -0
  177. package/dist/lineage/integration.js.map +1 -0
  178. package/dist/lineage/tracker.d.ts +189 -0
  179. package/dist/lineage/tracker.d.ts.map +1 -0
  180. package/dist/lineage/tracker.js +1352 -0
  181. package/dist/lineage/tracker.js.map +1 -0
  182. package/dist/lineage/types.d.ts +318 -0
  183. package/dist/lineage/types.d.ts.map +1 -0
  184. package/dist/lineage/types.js +9 -0
  185. package/dist/lineage/types.js.map +1 -0
  186. package/dist/middleware/index.d.ts +11 -0
  187. package/dist/middleware/index.d.ts.map +1 -0
  188. package/dist/middleware/index.js +16 -0
  189. package/dist/middleware/index.js.map +1 -0
  190. package/dist/middleware/rate-limit.d.ts +397 -0
  191. package/dist/middleware/rate-limit.d.ts.map +1 -0
  192. package/dist/middleware/rate-limit.js +507 -0
  193. package/dist/middleware/rate-limit.js.map +1 -0
  194. package/dist/migration-tooling/external-migration.d.ts +601 -0
  195. package/dist/migration-tooling/external-migration.d.ts.map +1 -0
  196. package/dist/migration-tooling/external-migration.js +1612 -0
  197. package/dist/migration-tooling/external-migration.js.map +1 -0
  198. package/dist/migration-tooling/index.d.ts +19 -0
  199. package/dist/migration-tooling/index.d.ts.map +1 -0
  200. package/dist/migration-tooling/index.js +19 -0
  201. package/dist/migration-tooling/index.js.map +1 -0
  202. package/dist/migrations/auto-migrator.d.ts +289 -0
  203. package/dist/migrations/auto-migrator.d.ts.map +1 -0
  204. package/dist/migrations/auto-migrator.js +396 -0
  205. package/dist/migrations/auto-migrator.js.map +1 -0
  206. package/dist/migrations/bulk-orchestrator.d.ts +403 -0
  207. package/dist/migrations/bulk-orchestrator.d.ts.map +1 -0
  208. package/dist/migrations/bulk-orchestrator.js +646 -0
  209. package/dist/migrations/bulk-orchestrator.js.map +1 -0
  210. package/dist/migrations/compatibility.d.ts +216 -0
  211. package/dist/migrations/compatibility.d.ts.map +1 -0
  212. package/dist/migrations/compatibility.js +651 -0
  213. package/dist/migrations/compatibility.js.map +1 -0
  214. package/dist/migrations/do-migrations.d.ts +101 -0
  215. package/dist/migrations/do-migrations.d.ts.map +1 -0
  216. package/dist/migrations/do-migrations.js +1060 -0
  217. package/dist/migrations/do-migrations.js.map +1 -0
  218. package/dist/migrations/do-migrations.types.d.ts +550 -0
  219. package/dist/migrations/do-migrations.types.d.ts.map +1 -0
  220. package/dist/migrations/do-migrations.types.js +15 -0
  221. package/dist/migrations/do-migrations.types.js.map +1 -0
  222. package/dist/migrations/drizzle-compat.d.ts +163 -0
  223. package/dist/migrations/drizzle-compat.d.ts.map +1 -0
  224. package/dist/migrations/drizzle-compat.js +273 -0
  225. package/dist/migrations/drizzle-compat.js.map +1 -0
  226. package/dist/migrations/index.d.ts +109 -0
  227. package/dist/migrations/index.d.ts.map +1 -0
  228. package/dist/migrations/index.js +127 -0
  229. package/dist/migrations/index.js.map +1 -0
  230. package/dist/migrations/migration-api.d.ts +161 -0
  231. package/dist/migrations/migration-api.d.ts.map +1 -0
  232. package/dist/migrations/migration-api.js +499 -0
  233. package/dist/migrations/migration-api.js.map +1 -0
  234. package/dist/migrations/progress-tracker-do.d.ts +195 -0
  235. package/dist/migrations/progress-tracker-do.d.ts.map +1 -0
  236. package/dist/migrations/progress-tracker-do.js +339 -0
  237. package/dist/migrations/progress-tracker-do.js.map +1 -0
  238. package/dist/migrations/progress-tracker-kv.d.ts +103 -0
  239. package/dist/migrations/progress-tracker-kv.d.ts.map +1 -0
  240. package/dist/migrations/progress-tracker-kv.js +231 -0
  241. package/dist/migrations/progress-tracker-kv.js.map +1 -0
  242. package/dist/migrations/progress-tracker.d.ts +320 -0
  243. package/dist/migrations/progress-tracker.d.ts.map +1 -0
  244. package/dist/migrations/progress-tracker.js +443 -0
  245. package/dist/migrations/progress-tracker.js.map +1 -0
  246. package/dist/migrations/registry.d.ts +231 -0
  247. package/dist/migrations/registry.d.ts.map +1 -0
  248. package/dist/migrations/registry.js +376 -0
  249. package/dist/migrations/registry.js.map +1 -0
  250. package/dist/migrations/runner.d.ts +197 -0
  251. package/dist/migrations/runner.d.ts.map +1 -0
  252. package/dist/migrations/runner.js +1167 -0
  253. package/dist/migrations/runner.js.map +1 -0
  254. package/dist/migrations/schema-generator.d.ts +111 -0
  255. package/dist/migrations/schema-generator.d.ts.map +1 -0
  256. package/dist/migrations/schema-generator.js +335 -0
  257. package/dist/migrations/schema-generator.js.map +1 -0
  258. package/dist/migrations/testing.d.ts +321 -0
  259. package/dist/migrations/testing.d.ts.map +1 -0
  260. package/dist/migrations/testing.js +645 -0
  261. package/dist/migrations/testing.js.map +1 -0
  262. package/dist/migrations/types.d.ts +503 -0
  263. package/dist/migrations/types.d.ts.map +1 -0
  264. package/dist/migrations/types.js +11 -0
  265. package/dist/migrations/types.js.map +1 -0
  266. package/dist/migrations/validator.d.ts +215 -0
  267. package/dist/migrations/validator.d.ts.map +1 -0
  268. package/dist/migrations/validator.js +494 -0
  269. package/dist/migrations/validator.js.map +1 -0
  270. package/dist/observability/alerting.d.ts +116 -0
  271. package/dist/observability/alerting.d.ts.map +1 -0
  272. package/dist/observability/alerting.js +353 -0
  273. package/dist/observability/alerting.js.map +1 -0
  274. package/dist/observability/analytics-engine.d.ts +357 -0
  275. package/dist/observability/analytics-engine.d.ts.map +1 -0
  276. package/dist/observability/analytics-engine.js +430 -0
  277. package/dist/observability/analytics-engine.js.map +1 -0
  278. package/dist/observability/cost-metrics.d.ts +269 -0
  279. package/dist/observability/cost-metrics.d.ts.map +1 -0
  280. package/dist/observability/cost-metrics.js +560 -0
  281. package/dist/observability/cost-metrics.js.map +1 -0
  282. package/dist/observability/cross-do-tracing.d.ts +305 -0
  283. package/dist/observability/cross-do-tracing.d.ts.map +1 -0
  284. package/dist/observability/cross-do-tracing.js +431 -0
  285. package/dist/observability/cross-do-tracing.js.map +1 -0
  286. package/dist/observability/error-rate-collector.d.ts +163 -0
  287. package/dist/observability/error-rate-collector.d.ts.map +1 -0
  288. package/dist/observability/error-rate-collector.js +306 -0
  289. package/dist/observability/error-rate-collector.js.map +1 -0
  290. package/dist/observability/exporters.d.ts +231 -0
  291. package/dist/observability/exporters.d.ts.map +1 -0
  292. package/dist/observability/exporters.js +479 -0
  293. package/dist/observability/exporters.js.map +1 -0
  294. package/dist/observability/health-check.d.ts +106 -0
  295. package/dist/observability/health-check.d.ts.map +1 -0
  296. package/dist/observability/health-check.js +243 -0
  297. package/dist/observability/health-check.js.map +1 -0
  298. package/dist/observability/index.d.ts +297 -0
  299. package/dist/observability/index.d.ts.map +1 -0
  300. package/dist/observability/index.js +455 -0
  301. package/dist/observability/index.js.map +1 -0
  302. package/dist/observability/instrumentation.d.ts +222 -0
  303. package/dist/observability/instrumentation.d.ts.map +1 -0
  304. package/dist/observability/instrumentation.js +532 -0
  305. package/dist/observability/instrumentation.js.map +1 -0
  306. package/dist/observability/memory-metrics.d.ts +227 -0
  307. package/dist/observability/memory-metrics.d.ts.map +1 -0
  308. package/dist/observability/memory-metrics.js +688 -0
  309. package/dist/observability/memory-metrics.js.map +1 -0
  310. package/dist/observability/metrics-endpoint.d.ts +91 -0
  311. package/dist/observability/metrics-endpoint.d.ts.map +1 -0
  312. package/dist/observability/metrics-endpoint.js +246 -0
  313. package/dist/observability/metrics-endpoint.js.map +1 -0
  314. package/dist/observability/metrics.d.ts +88 -0
  315. package/dist/observability/metrics.d.ts.map +1 -0
  316. package/dist/observability/metrics.js +253 -0
  317. package/dist/observability/metrics.js.map +1 -0
  318. package/dist/observability/observability-features.d.ts +488 -0
  319. package/dist/observability/observability-features.d.ts.map +1 -0
  320. package/dist/observability/observability-features.js +773 -0
  321. package/dist/observability/observability-features.js.map +1 -0
  322. package/dist/observability/prometheus.d.ts +39 -0
  323. package/dist/observability/prometheus.d.ts.map +1 -0
  324. package/dist/observability/prometheus.js +120 -0
  325. package/dist/observability/prometheus.js.map +1 -0
  326. package/dist/observability/propagation.d.ts +126 -0
  327. package/dist/observability/propagation.d.ts.map +1 -0
  328. package/dist/observability/propagation.js +234 -0
  329. package/dist/observability/propagation.js.map +1 -0
  330. package/dist/observability/query-latency.d.ts +243 -0
  331. package/dist/observability/query-latency.d.ts.map +1 -0
  332. package/dist/observability/query-latency.js +292 -0
  333. package/dist/observability/query-latency.js.map +1 -0
  334. package/dist/observability/query-performance.d.ts +169 -0
  335. package/dist/observability/query-performance.d.ts.map +1 -0
  336. package/dist/observability/query-performance.js +290 -0
  337. package/dist/observability/query-performance.js.map +1 -0
  338. package/dist/observability/storage-tier-metrics.d.ts +174 -0
  339. package/dist/observability/storage-tier-metrics.d.ts.map +1 -0
  340. package/dist/observability/storage-tier-metrics.js +306 -0
  341. package/dist/observability/storage-tier-metrics.js.map +1 -0
  342. package/dist/observability/tier-cost-optimizer.d.ts +155 -0
  343. package/dist/observability/tier-cost-optimizer.d.ts.map +1 -0
  344. package/dist/observability/tier-cost-optimizer.js +536 -0
  345. package/dist/observability/tier-cost-optimizer.js.map +1 -0
  346. package/dist/observability/tracer.d.ts +149 -0
  347. package/dist/observability/tracer.d.ts.map +1 -0
  348. package/dist/observability/tracer.js +435 -0
  349. package/dist/observability/tracer.js.map +1 -0
  350. package/dist/observability/types.d.ts +402 -0
  351. package/dist/observability/types.d.ts.map +1 -0
  352. package/dist/observability/types.js +103 -0
  353. package/dist/observability/types.js.map +1 -0
  354. package/dist/pglite/workers-pglite.d.ts +138 -0
  355. package/dist/pglite/workers-pglite.d.ts.map +1 -0
  356. package/dist/pglite/workers-pglite.js +143 -0
  357. package/dist/pglite/workers-pglite.js.map +1 -0
  358. package/dist/pglite-assets/pglite.data +0 -0
  359. package/dist/pglite-assets/pglite.wasm +0 -0
  360. package/dist/playground/index.d.ts +52 -0
  361. package/dist/playground/index.d.ts.map +1 -0
  362. package/dist/playground/index.js +55 -0
  363. package/dist/playground/index.js.map +1 -0
  364. package/dist/playground/keyboard-shortcuts.d.ts +116 -0
  365. package/dist/playground/keyboard-shortcuts.d.ts.map +1 -0
  366. package/dist/playground/keyboard-shortcuts.js +588 -0
  367. package/dist/playground/keyboard-shortcuts.js.map +1 -0
  368. package/dist/playground/playground.d.ts +82 -0
  369. package/dist/playground/playground.d.ts.map +1 -0
  370. package/dist/playground/playground.js +271 -0
  371. package/dist/playground/playground.js.map +1 -0
  372. package/dist/playground/query-executor.d.ts +115 -0
  373. package/dist/playground/query-executor.d.ts.map +1 -0
  374. package/dist/playground/query-executor.js +558 -0
  375. package/dist/playground/query-executor.js.map +1 -0
  376. package/dist/playground/query-history.d.ts +92 -0
  377. package/dist/playground/query-history.d.ts.map +1 -0
  378. package/dist/playground/query-history.js +259 -0
  379. package/dist/playground/query-history.js.map +1 -0
  380. package/dist/playground/result-formatter.d.ts +59 -0
  381. package/dist/playground/result-formatter.d.ts.map +1 -0
  382. package/dist/playground/result-formatter.js +341 -0
  383. package/dist/playground/result-formatter.js.map +1 -0
  384. package/dist/playground/sample-datasets.d.ts +77 -0
  385. package/dist/playground/sample-datasets.d.ts.map +1 -0
  386. package/dist/playground/sample-datasets.js +641 -0
  387. package/dist/playground/sample-datasets.js.map +1 -0
  388. package/dist/playground/sample-queries.d.ts +73 -0
  389. package/dist/playground/sample-queries.d.ts.map +1 -0
  390. package/dist/playground/sample-queries.js +1095 -0
  391. package/dist/playground/sample-queries.js.map +1 -0
  392. package/dist/playground/schema-explorer.d.ts +55 -0
  393. package/dist/playground/schema-explorer.d.ts.map +1 -0
  394. package/dist/playground/schema-explorer.js +473 -0
  395. package/dist/playground/schema-explorer.js.map +1 -0
  396. package/dist/playground/types.d.ts +430 -0
  397. package/dist/playground/types.d.ts.map +1 -0
  398. package/dist/playground/types.js +10 -0
  399. package/dist/playground/types.js.map +1 -0
  400. package/dist/readonly/cache-reader.d.ts +145 -0
  401. package/dist/readonly/cache-reader.d.ts.map +1 -0
  402. package/dist/readonly/cache-reader.js +198 -0
  403. package/dist/readonly/cache-reader.js.map +1 -0
  404. package/dist/readonly/config.d.ts +74 -0
  405. package/dist/readonly/config.d.ts.map +1 -0
  406. package/dist/readonly/config.js +67 -0
  407. package/dist/readonly/config.js.map +1 -0
  408. package/dist/readonly/index.d.ts +22 -0
  409. package/dist/readonly/index.d.ts.map +1 -0
  410. package/dist/readonly/index.js +17 -0
  411. package/dist/readonly/index.js.map +1 -0
  412. package/dist/readonly/pglite-wrapper.d.ts +82 -0
  413. package/dist/readonly/pglite-wrapper.d.ts.map +1 -0
  414. package/dist/readonly/pglite-wrapper.js +123 -0
  415. package/dist/readonly/pglite-wrapper.js.map +1 -0
  416. package/dist/readonly/worker.d.ts +142 -0
  417. package/dist/readonly/worker.d.ts.map +1 -0
  418. package/dist/readonly/worker.js +187 -0
  419. package/dist/readonly/worker.js.map +1 -0
  420. package/dist/readonly/write-blocker.d.ts +47 -0
  421. package/dist/readonly/write-blocker.d.ts.map +1 -0
  422. package/dist/readonly/write-blocker.js +136 -0
  423. package/dist/readonly/write-blocker.js.map +1 -0
  424. package/dist/recovery/disaster-recovery.d.ts +326 -0
  425. package/dist/recovery/disaster-recovery.d.ts.map +1 -0
  426. package/dist/recovery/disaster-recovery.js +799 -0
  427. package/dist/recovery/disaster-recovery.js.map +1 -0
  428. package/dist/recovery/index.d.ts +12 -0
  429. package/dist/recovery/index.d.ts.map +1 -0
  430. package/dist/recovery/index.js +12 -0
  431. package/dist/recovery/index.js.map +1 -0
  432. package/dist/recovery/parquet-parser.d.ts +321 -0
  433. package/dist/recovery/parquet-parser.d.ts.map +1 -0
  434. package/dist/recovery/parquet-parser.js +797 -0
  435. package/dist/recovery/parquet-parser.js.map +1 -0
  436. package/dist/retention/index.d.ts +50 -0
  437. package/dist/retention/index.d.ts.map +1 -0
  438. package/dist/retention/index.js +50 -0
  439. package/dist/retention/index.js.map +1 -0
  440. package/dist/retention/policy.d.ts +344 -0
  441. package/dist/retention/policy.d.ts.map +1 -0
  442. package/dist/retention/policy.js +472 -0
  443. package/dist/retention/policy.js.map +1 -0
  444. package/dist/retention/purger.d.ts +187 -0
  445. package/dist/retention/purger.d.ts.map +1 -0
  446. package/dist/retention/purger.js +411 -0
  447. package/dist/retention/purger.js.map +1 -0
  448. package/dist/rls/auth-integration.d.ts +280 -0
  449. package/dist/rls/auth-integration.d.ts.map +1 -0
  450. package/dist/rls/auth-integration.js +399 -0
  451. package/dist/rls/auth-integration.js.map +1 -0
  452. package/dist/rls/generator.d.ts +249 -0
  453. package/dist/rls/generator.d.ts.map +1 -0
  454. package/dist/rls/generator.js +495 -0
  455. package/dist/rls/generator.js.map +1 -0
  456. package/dist/rls/index.d.ts +26 -0
  457. package/dist/rls/index.d.ts.map +1 -0
  458. package/dist/rls/index.js +58 -0
  459. package/dist/rls/index.js.map +1 -0
  460. package/dist/rls/policy.d.ts +116 -0
  461. package/dist/rls/policy.d.ts.map +1 -0
  462. package/dist/rls/policy.js +77 -0
  463. package/dist/rls/policy.js.map +1 -0
  464. package/dist/rls/validator.d.ts +155 -0
  465. package/dist/rls/validator.d.ts.map +1 -0
  466. package/dist/rls/validator.js +792 -0
  467. package/dist/rls/validator.js.map +1 -0
  468. package/dist/routing/adaptive-router.d.ts +317 -0
  469. package/dist/routing/adaptive-router.d.ts.map +1 -0
  470. package/dist/routing/adaptive-router.js +554 -0
  471. package/dist/routing/adaptive-router.js.map +1 -0
  472. package/dist/routing/circuit-breaker.d.ts +339 -0
  473. package/dist/routing/circuit-breaker.d.ts.map +1 -0
  474. package/dist/routing/circuit-breaker.js +620 -0
  475. package/dist/routing/circuit-breaker.js.map +1 -0
  476. package/dist/routing/cost-metrics.d.ts +133 -0
  477. package/dist/routing/cost-metrics.d.ts.map +1 -0
  478. package/dist/routing/cost-metrics.js +259 -0
  479. package/dist/routing/cost-metrics.js.map +1 -0
  480. package/dist/routing/do-connection-pool.d.ts +243 -0
  481. package/dist/routing/do-connection-pool.d.ts.map +1 -0
  482. package/dist/routing/do-connection-pool.js +572 -0
  483. package/dist/routing/do-connection-pool.js.map +1 -0
  484. package/dist/routing/index.d.ts +59 -0
  485. package/dist/routing/index.d.ts.map +1 -0
  486. package/dist/routing/index.js +59 -0
  487. package/dist/routing/index.js.map +1 -0
  488. package/dist/routing/query-complexity-estimator.d.ts +73 -0
  489. package/dist/routing/query-complexity-estimator.d.ts.map +1 -0
  490. package/dist/routing/query-complexity-estimator.js +327 -0
  491. package/dist/routing/query-complexity-estimator.js.map +1 -0
  492. package/dist/routing/request-coalescing.d.ts +178 -0
  493. package/dist/routing/request-coalescing.d.ts.map +1 -0
  494. package/dist/routing/request-coalescing.js +325 -0
  495. package/dist/routing/request-coalescing.js.map +1 -0
  496. package/dist/routing/runtime-router.d.ts +107 -0
  497. package/dist/routing/runtime-router.d.ts.map +1 -0
  498. package/dist/routing/runtime-router.js +246 -0
  499. package/dist/routing/runtime-router.js.map +1 -0
  500. package/dist/routing/tenant-router.d.ts +848 -0
  501. package/dist/routing/tenant-router.d.ts.map +1 -0
  502. package/dist/routing/tenant-router.js +1056 -0
  503. package/dist/routing/tenant-router.js.map +1 -0
  504. package/dist/routing/websocket-pool.d.ts +119 -0
  505. package/dist/routing/websocket-pool.d.ts.map +1 -0
  506. package/dist/routing/websocket-pool.js +436 -0
  507. package/dist/routing/websocket-pool.js.map +1 -0
  508. package/dist/storage/cache-layer.d.ts +159 -0
  509. package/dist/storage/cache-layer.d.ts.map +1 -0
  510. package/dist/storage/cache-layer.js +245 -0
  511. package/dist/storage/cache-layer.js.map +1 -0
  512. package/dist/storage/cost-aware-tiering.d.ts +258 -0
  513. package/dist/storage/cost-aware-tiering.d.ts.map +1 -0
  514. package/dist/storage/cost-aware-tiering.js +526 -0
  515. package/dist/storage/cost-aware-tiering.js.map +1 -0
  516. package/dist/storage/index.d.ts +87 -0
  517. package/dist/storage/index.d.ts.map +1 -0
  518. package/dist/storage/index.js +78 -0
  519. package/dist/storage/index.js.map +1 -0
  520. package/dist/storage/interfaces.d.ts +856 -0
  521. package/dist/storage/interfaces.d.ts.map +1 -0
  522. package/dist/storage/interfaces.js +69 -0
  523. package/dist/storage/interfaces.js.map +1 -0
  524. package/dist/storage/r2-layer.d.ts +226 -0
  525. package/dist/storage/r2-layer.d.ts.map +1 -0
  526. package/dist/storage/r2-layer.js +307 -0
  527. package/dist/storage/r2-layer.js.map +1 -0
  528. package/dist/storage/r2-overflow.d.ts +344 -0
  529. package/dist/storage/r2-overflow.d.ts.map +1 -0
  530. package/dist/storage/r2-overflow.js +730 -0
  531. package/dist/storage/r2-overflow.js.map +1 -0
  532. package/dist/storage/r2-page-vfs.d.ts +374 -0
  533. package/dist/storage/r2-page-vfs.d.ts.map +1 -0
  534. package/dist/storage/r2-page-vfs.js +754 -0
  535. package/dist/storage/r2-page-vfs.js.map +1 -0
  536. package/dist/storage/swr-cache.d.ts +181 -0
  537. package/dist/storage/swr-cache.d.ts.map +1 -0
  538. package/dist/storage/swr-cache.js +295 -0
  539. package/dist/storage/swr-cache.js.map +1 -0
  540. package/dist/storage/tiered-orchestrator.d.ts +951 -0
  541. package/dist/storage/tiered-orchestrator.d.ts.map +1 -0
  542. package/dist/storage/tiered-orchestrator.js +1731 -0
  543. package/dist/storage/tiered-orchestrator.js.map +1 -0
  544. package/dist/storage/tiered-vfs-swr.d.ts +279 -0
  545. package/dist/storage/tiered-vfs-swr.d.ts.map +1 -0
  546. package/dist/storage/tiered-vfs-swr.js +584 -0
  547. package/dist/storage/tiered-vfs-swr.js.map +1 -0
  548. package/dist/storage/tiered-vfs.d.ts +405 -0
  549. package/dist/storage/tiered-vfs.d.ts.map +1 -0
  550. package/dist/storage/tiered-vfs.js +833 -0
  551. package/dist/storage/tiered-vfs.js.map +1 -0
  552. package/dist/streaming/backpressure-controller.d.ts +173 -0
  553. package/dist/streaming/backpressure-controller.d.ts.map +1 -0
  554. package/dist/streaming/backpressure-controller.js +344 -0
  555. package/dist/streaming/backpressure-controller.js.map +1 -0
  556. package/dist/streaming/buffer-pool.d.ts +241 -0
  557. package/dist/streaming/buffer-pool.d.ts.map +1 -0
  558. package/dist/streaming/buffer-pool.js +381 -0
  559. package/dist/streaming/buffer-pool.js.map +1 -0
  560. package/dist/streaming/cdc-iceberg-connector.d.ts +272 -0
  561. package/dist/streaming/cdc-iceberg-connector.d.ts.map +1 -0
  562. package/dist/streaming/cdc-iceberg-connector.js +408 -0
  563. package/dist/streaming/cdc-iceberg-connector.js.map +1 -0
  564. package/dist/streaming/index.d.ts +111 -0
  565. package/dist/streaming/index.d.ts.map +1 -0
  566. package/dist/streaming/index.js +128 -0
  567. package/dist/streaming/index.js.map +1 -0
  568. package/dist/streaming/live-cdc-stream.d.ts +400 -0
  569. package/dist/streaming/live-cdc-stream.d.ts.map +1 -0
  570. package/dist/streaming/live-cdc-stream.js +703 -0
  571. package/dist/streaming/live-cdc-stream.js.map +1 -0
  572. package/dist/streaming/memory-bounded-stream.d.ts +207 -0
  573. package/dist/streaming/memory-bounded-stream.d.ts.map +1 -0
  574. package/dist/streaming/memory-bounded-stream.js +340 -0
  575. package/dist/streaming/memory-bounded-stream.js.map +1 -0
  576. package/dist/streaming/query-streamer.d.ts +379 -0
  577. package/dist/streaming/query-streamer.d.ts.map +1 -0
  578. package/dist/streaming/query-streamer.js +495 -0
  579. package/dist/streaming/query-streamer.js.map +1 -0
  580. package/dist/streaming/response-streaming.d.ts +203 -0
  581. package/dist/streaming/response-streaming.d.ts.map +1 -0
  582. package/dist/streaming/response-streaming.js +449 -0
  583. package/dist/streaming/response-streaming.js.map +1 -0
  584. package/dist/types/branded.d.ts +859 -0
  585. package/dist/types/branded.d.ts.map +1 -0
  586. package/dist/types/branded.js +891 -0
  587. package/dist/types/branded.js.map +1 -0
  588. package/dist/types/utilities.d.ts +757 -0
  589. package/dist/types/utilities.d.ts.map +1 -0
  590. package/dist/types/utilities.js +447 -0
  591. package/dist/types/utilities.js.map +1 -0
  592. package/dist/wal/replay-engine.d.ts +344 -0
  593. package/dist/wal/replay-engine.d.ts.map +1 -0
  594. package/dist/wal/replay-engine.js +975 -0
  595. package/dist/wal/replay-engine.js.map +1 -0
  596. package/dist/worker/__mocks__/capnweb.d.ts +13 -0
  597. package/dist/worker/__mocks__/capnweb.d.ts.map +1 -0
  598. package/dist/worker/__mocks__/capnweb.js +15 -0
  599. package/dist/worker/__mocks__/capnweb.js.map +1 -0
  600. package/dist/worker/__mocks__/cloudflare-workers.d.ts +31 -0
  601. package/dist/worker/__mocks__/cloudflare-workers.d.ts.map +1 -0
  602. package/dist/worker/__mocks__/cloudflare-workers.js +33 -0
  603. package/dist/worker/__mocks__/cloudflare-workers.js.map +1 -0
  604. package/dist/worker/__mocks__/pglite.data.d.ts +3 -0
  605. package/dist/worker/__mocks__/pglite.data.d.ts.map +1 -0
  606. package/dist/worker/__mocks__/pglite.data.js +20 -0
  607. package/dist/worker/__mocks__/pglite.data.js.map +1 -0
  608. package/dist/worker/__mocks__/pglite.wasm.d.ts +3 -0
  609. package/dist/worker/__mocks__/pglite.wasm.d.ts.map +1 -0
  610. package/dist/worker/__mocks__/pglite.wasm.js +30 -0
  611. package/dist/worker/__mocks__/pglite.wasm.js.map +1 -0
  612. package/dist/worker/auth-rate-limiter.d.ts +270 -0
  613. package/dist/worker/auth-rate-limiter.d.ts.map +1 -0
  614. package/dist/worker/auth-rate-limiter.js +332 -0
  615. package/dist/worker/auth-rate-limiter.js.map +1 -0
  616. package/dist/worker/auth.d.ts +345 -0
  617. package/dist/worker/auth.d.ts.map +1 -0
  618. package/dist/worker/auth.js +837 -0
  619. package/dist/worker/auth.js.map +1 -0
  620. package/dist/worker/cdc-backpressure.d.ts +338 -0
  621. package/dist/worker/cdc-backpressure.d.ts.map +1 -0
  622. package/dist/worker/cdc-backpressure.js +619 -0
  623. package/dist/worker/cdc-backpressure.js.map +1 -0
  624. package/dist/worker/cdc-sse.d.ts +277 -0
  625. package/dist/worker/cdc-sse.d.ts.map +1 -0
  626. package/dist/worker/cdc-sse.js +528 -0
  627. package/dist/worker/cdc-sse.js.map +1 -0
  628. package/dist/worker/cdc-websocket.d.ts +252 -0
  629. package/dist/worker/cdc-websocket.d.ts.map +1 -0
  630. package/dist/worker/cdc-websocket.js +940 -0
  631. package/dist/worker/cdc-websocket.js.map +1 -0
  632. package/dist/worker/cdc.d.ts +95 -0
  633. package/dist/worker/cdc.d.ts.map +1 -0
  634. package/dist/worker/cdc.js +211 -0
  635. package/dist/worker/cdc.js.map +1 -0
  636. package/dist/worker/concerns/auth-concern.d.ts +50 -0
  637. package/dist/worker/concerns/auth-concern.d.ts.map +1 -0
  638. package/dist/worker/concerns/auth-concern.js +131 -0
  639. package/dist/worker/concerns/auth-concern.js.map +1 -0
  640. package/dist/worker/concerns/cdc-concern.d.ts +99 -0
  641. package/dist/worker/concerns/cdc-concern.d.ts.map +1 -0
  642. package/dist/worker/concerns/cdc-concern.js +137 -0
  643. package/dist/worker/concerns/cdc-concern.js.map +1 -0
  644. package/dist/worker/concerns/index.d.ts +22 -0
  645. package/dist/worker/concerns/index.d.ts.map +1 -0
  646. package/dist/worker/concerns/index.js +13 -0
  647. package/dist/worker/concerns/index.js.map +1 -0
  648. package/dist/worker/concerns/query-execution-concern.d.ts +104 -0
  649. package/dist/worker/concerns/query-execution-concern.d.ts.map +1 -0
  650. package/dist/worker/concerns/query-execution-concern.js +95 -0
  651. package/dist/worker/concerns/query-execution-concern.js.map +1 -0
  652. package/dist/worker/concerns/storage-orchestration-concern.d.ts +78 -0
  653. package/dist/worker/concerns/storage-orchestration-concern.d.ts.map +1 -0
  654. package/dist/worker/concerns/storage-orchestration-concern.js +240 -0
  655. package/dist/worker/concerns/storage-orchestration-concern.js.map +1 -0
  656. package/dist/worker/do-auth-manager.d.ts +108 -0
  657. package/dist/worker/do-auth-manager.d.ts.map +1 -0
  658. package/dist/worker/do-auth-manager.js +212 -0
  659. package/dist/worker/do-auth-manager.js.map +1 -0
  660. package/dist/worker/do-pglite-manager.d.ts +137 -0
  661. package/dist/worker/do-pglite-manager.d.ts.map +1 -0
  662. package/dist/worker/do-pglite-manager.js +228 -0
  663. package/dist/worker/do-pglite-manager.js.map +1 -0
  664. package/dist/worker/do.d.ts +556 -0
  665. package/dist/worker/do.d.ts.map +1 -0
  666. package/dist/worker/do.js +1441 -0
  667. package/dist/worker/do.js.map +1 -0
  668. package/dist/worker/entry.d.ts +23 -0
  669. package/dist/worker/entry.d.ts.map +1 -0
  670. package/dist/worker/entry.js +362 -0
  671. package/dist/worker/entry.js.map +1 -0
  672. package/dist/worker/errors.d.ts +106 -0
  673. package/dist/worker/errors.d.ts.map +1 -0
  674. package/dist/worker/errors.js +178 -0
  675. package/dist/worker/errors.js.map +1 -0
  676. package/dist/worker/health-check-manager.d.ts +141 -0
  677. package/dist/worker/health-check-manager.d.ts.map +1 -0
  678. package/dist/worker/health-check-manager.js +145 -0
  679. package/dist/worker/health-check-manager.js.map +1 -0
  680. package/dist/worker/index.d.ts +60 -0
  681. package/dist/worker/index.d.ts.map +1 -0
  682. package/dist/worker/index.js +67 -0
  683. package/dist/worker/index.js.map +1 -0
  684. package/dist/worker/memory-pressure.d.ts +892 -0
  685. package/dist/worker/memory-pressure.d.ts.map +1 -0
  686. package/dist/worker/memory-pressure.js +1990 -0
  687. package/dist/worker/memory-pressure.js.map +1 -0
  688. package/dist/worker/migration-manager.d.ts +153 -0
  689. package/dist/worker/migration-manager.d.ts.map +1 -0
  690. package/dist/worker/migration-manager.js +461 -0
  691. package/dist/worker/migration-manager.js.map +1 -0
  692. package/dist/worker/plugin-manager.d.ts +147 -0
  693. package/dist/worker/plugin-manager.d.ts.map +1 -0
  694. package/dist/worker/plugin-manager.js +408 -0
  695. package/dist/worker/plugin-manager.js.map +1 -0
  696. package/dist/worker/proxy.d.ts +330 -0
  697. package/dist/worker/proxy.d.ts.map +1 -0
  698. package/dist/worker/proxy.js +504 -0
  699. package/dist/worker/proxy.js.map +1 -0
  700. package/dist/worker/query-execution-manager.d.ts +107 -0
  701. package/dist/worker/query-execution-manager.d.ts.map +1 -0
  702. package/dist/worker/query-execution-manager.js +155 -0
  703. package/dist/worker/query-execution-manager.js.map +1 -0
  704. package/dist/worker/query-executor.d.ts +163 -0
  705. package/dist/worker/query-executor.d.ts.map +1 -0
  706. package/dist/worker/query-executor.js +413 -0
  707. package/dist/worker/query-executor.js.map +1 -0
  708. package/dist/worker/query-stats-manager.d.ts +117 -0
  709. package/dist/worker/query-stats-manager.d.ts.map +1 -0
  710. package/dist/worker/query-stats-manager.js +162 -0
  711. package/dist/worker/query-stats-manager.js.map +1 -0
  712. package/dist/worker/result-handler.d.ts +192 -0
  713. package/dist/worker/result-handler.d.ts.map +1 -0
  714. package/dist/worker/result-handler.js +346 -0
  715. package/dist/worker/result-handler.js.map +1 -0
  716. package/dist/worker/routes.d.ts +135 -0
  717. package/dist/worker/routes.d.ts.map +1 -0
  718. package/dist/worker/routes.js +460 -0
  719. package/dist/worker/routes.js.map +1 -0
  720. package/dist/worker/rpc-methods-manager.d.ts +142 -0
  721. package/dist/worker/rpc-methods-manager.d.ts.map +1 -0
  722. package/dist/worker/rpc-methods-manager.js +195 -0
  723. package/dist/worker/rpc-methods-manager.js.map +1 -0
  724. package/dist/worker/rpc.d.ts +259 -0
  725. package/dist/worker/rpc.d.ts.map +1 -0
  726. package/dist/worker/rpc.js +398 -0
  727. package/dist/worker/rpc.js.map +1 -0
  728. package/dist/worker/schema-version.d.ts +209 -0
  729. package/dist/worker/schema-version.d.ts.map +1 -0
  730. package/dist/worker/schema-version.js +450 -0
  731. package/dist/worker/schema-version.js.map +1 -0
  732. package/dist/worker/session-manager.d.ts +282 -0
  733. package/dist/worker/session-manager.d.ts.map +1 -0
  734. package/dist/worker/session-manager.js +523 -0
  735. package/dist/worker/session-manager.js.map +1 -0
  736. package/dist/worker/shutdown-manager.d.ts +188 -0
  737. package/dist/worker/shutdown-manager.d.ts.map +1 -0
  738. package/dist/worker/shutdown-manager.js +347 -0
  739. package/dist/worker/shutdown-manager.js.map +1 -0
  740. package/dist/worker/sql-transform.d.ts +61 -0
  741. package/dist/worker/sql-transform.d.ts.map +1 -0
  742. package/dist/worker/sql-transform.js +312 -0
  743. package/dist/worker/sql-transform.js.map +1 -0
  744. package/dist/worker/types.d.ts +738 -0
  745. package/dist/worker/types.d.ts.map +1 -0
  746. package/dist/worker/types.js +6 -0
  747. package/dist/worker/types.js.map +1 -0
  748. package/dist/worker/user-routes.d.ts +76 -0
  749. package/dist/worker/user-routes.d.ts.map +1 -0
  750. package/dist/worker/user-routes.js +188 -0
  751. package/dist/worker/user-routes.js.map +1 -0
  752. package/dist/worker/wal-facade.d.ts +138 -0
  753. package/dist/worker/wal-facade.d.ts.map +1 -0
  754. package/dist/worker/wal-facade.js +184 -0
  755. package/dist/worker/wal-facade.js.map +1 -0
  756. package/dist/worker/wal-r2.d.ts +271 -0
  757. package/dist/worker/wal-r2.d.ts.map +1 -0
  758. package/dist/worker/wal-r2.js +689 -0
  759. package/dist/worker/wal-r2.js.map +1 -0
  760. package/dist/worker/wal-replay.d.ts +361 -0
  761. package/dist/worker/wal-replay.d.ts.map +1 -0
  762. package/dist/worker/wal-replay.js +628 -0
  763. package/dist/worker/wal-replay.js.map +1 -0
  764. package/dist/worker/wal-retention.d.ts +389 -0
  765. package/dist/worker/wal-retention.d.ts.map +1 -0
  766. package/dist/worker/wal-retention.js +763 -0
  767. package/dist/worker/wal-retention.js.map +1 -0
  768. package/dist/worker/wal.d.ts +278 -0
  769. package/dist/worker/wal.d.ts.map +1 -0
  770. package/dist/worker/wal.js +467 -0
  771. package/dist/worker/wal.js.map +1 -0
  772. package/dist/worker/websocket.d.ts +85 -0
  773. package/dist/worker/websocket.d.ts.map +1 -0
  774. package/dist/worker/websocket.js +227 -0
  775. package/dist/worker/websocket.js.map +1 -0
  776. package/package.json +108 -0
  777. package/src/cdc/change-stream.ts +137 -0
  778. package/src/cdc/filter.ts +646 -0
  779. package/src/cdc/index.ts +112 -0
  780. package/src/cdc/resume-token.ts +280 -0
  781. package/src/cdc/transport/index.ts +7 -0
  782. package/src/cdc/transport/sse.ts +723 -0
  783. package/src/cdc/transport/websocket.ts +873 -0
  784. package/src/cdc/types.ts +346 -0
  785. package/src/config/index.ts +25 -0
  786. package/src/config/memory.ts +177 -0
  787. package/src/config/storage.ts +204 -0
  788. package/src/config/streaming.ts +147 -0
  789. package/src/config/timeouts.ts +221 -0
  790. package/src/extensions/config.test.ts +187 -0
  791. package/src/extensions/config.ts +278 -0
  792. package/src/extensions/geo.test.ts +455 -0
  793. package/src/extensions/geo.ts +858 -0
  794. package/src/extensions/index.test.ts +259 -0
  795. package/src/extensions/index.ts +227 -0
  796. package/src/extensions/loader.test.ts +555 -0
  797. package/src/extensions/loader.ts +588 -0
  798. package/src/extensions/pgmq-lite.test.ts +727 -0
  799. package/src/extensions/pgmq-lite.ts +770 -0
  800. package/src/extensions/plugins.test.ts +528 -0
  801. package/src/extensions/plugins.ts +718 -0
  802. package/src/extensions/registry.test.ts +202 -0
  803. package/src/extensions/registry.ts +267 -0
  804. package/src/extensions/vector.test.ts +195 -0
  805. package/src/extensions/vector.ts +217 -0
  806. package/src/iceberg/SCHEDULER.md +580 -0
  807. package/src/iceberg/analytics.test.ts +703 -0
  808. package/src/iceberg/analytics.ts +727 -0
  809. package/src/iceberg/catalog-api.test.ts +838 -0
  810. package/src/iceberg/catalog-api.ts +520 -0
  811. package/src/iceberg/catalog.test.ts +680 -0
  812. package/src/iceberg/catalog.ts +1007 -0
  813. package/src/iceberg/iceberg.test.ts +705 -0
  814. package/src/iceberg/index.ts +406 -0
  815. package/src/iceberg/metadata.test.ts +632 -0
  816. package/src/iceberg/metadata.ts +649 -0
  817. package/src/iceberg/optimizer.test.ts +868 -0
  818. package/src/iceberg/optimizer.ts +1287 -0
  819. package/src/iceberg/parquet.test.ts +899 -0
  820. package/src/iceberg/parquet.ts +1640 -0
  821. package/src/iceberg/r2-organization.test.ts +615 -0
  822. package/src/iceberg/r2-organization.ts +951 -0
  823. package/src/iceberg/scheduler-do-example.ts +364 -0
  824. package/src/iceberg/scheduler.test.ts +861 -0
  825. package/src/iceberg/scheduler.ts +1201 -0
  826. package/src/iceberg/schema.test.ts +547 -0
  827. package/src/iceberg/schema.ts +616 -0
  828. package/src/iceberg/snapshot-manager.test.ts +919 -0
  829. package/src/iceberg/snapshot-manager.ts +1369 -0
  830. package/src/iceberg/sql-router.test.ts +334 -0
  831. package/src/iceberg/sql-router.ts +337 -0
  832. package/src/iceberg/test-fixtures.ts +605 -0
  833. package/src/iceberg/time-travel-api.test.ts +1029 -0
  834. package/src/iceberg/time-travel-api.ts +731 -0
  835. package/src/iceberg/time-travel.test.ts +1218 -0
  836. package/src/iceberg/time-travel.ts +1052 -0
  837. package/src/iceberg/transformer.test.ts +689 -0
  838. package/src/iceberg/transformer.ts +1029 -0
  839. package/src/iceberg/types.ts +373 -0
  840. package/src/iceberg/writer.test.ts +716 -0
  841. package/src/iceberg/writer.ts +590 -0
  842. package/src/index.ts +212 -0
  843. package/src/lineage/index.ts +42 -0
  844. package/src/lineage/integration.ts +334 -0
  845. package/src/lineage/tracker.ts +1618 -0
  846. package/src/lineage/types.ts +354 -0
  847. package/src/middleware/index.ts +36 -0
  848. package/src/middleware/rate-limit-concurrent.test.ts +794 -0
  849. package/src/middleware/rate-limit.test.ts +1568 -0
  850. package/src/middleware/rate-limit.ts +840 -0
  851. package/src/migration-tooling/external-migration.test.ts +1864 -0
  852. package/src/migration-tooling/external-migration.ts +2355 -0
  853. package/src/migration-tooling/index.ts +19 -0
  854. package/src/migrations/ARCHITECTURE.md +474 -0
  855. package/src/migrations/PROGRESS_TRACKING.md +485 -0
  856. package/src/migrations/auto-migrator.test.ts +732 -0
  857. package/src/migrations/auto-migrator.ts +531 -0
  858. package/src/migrations/bulk-orchestrator.test.ts +801 -0
  859. package/src/migrations/bulk-orchestrator.ts +1039 -0
  860. package/src/migrations/compatibility.test.ts +958 -0
  861. package/src/migrations/compatibility.ts +902 -0
  862. package/src/migrations/do-migrations.test.ts +2620 -0
  863. package/src/migrations/do-migrations.ts +1289 -0
  864. package/src/migrations/do-migrations.types.ts +715 -0
  865. package/src/migrations/drizzle-compat.test.ts +210 -0
  866. package/src/migrations/drizzle-compat.ts +337 -0
  867. package/src/migrations/index.ts +334 -0
  868. package/src/migrations/migration-api.test.ts +438 -0
  869. package/src/migrations/migration-api.ts +704 -0
  870. package/src/migrations/progress-tracker-do.ts +518 -0
  871. package/src/migrations/progress-tracker-kv.ts +305 -0
  872. package/src/migrations/progress-tracker.test.ts +937 -0
  873. package/src/migrations/progress-tracker.ts +665 -0
  874. package/src/migrations/registry.test.ts +331 -0
  875. package/src/migrations/registry.ts +468 -0
  876. package/src/migrations/rollback.test.ts +644 -0
  877. package/src/migrations/runner.test.ts +807 -0
  878. package/src/migrations/runner.test.ts.backup +759 -0
  879. package/src/migrations/runner.ts +1459 -0
  880. package/src/migrations/schema-generator.test.ts +649 -0
  881. package/src/migrations/schema-generator.ts +513 -0
  882. package/src/migrations/testing.ts +1037 -0
  883. package/src/migrations/types.ts +573 -0
  884. package/src/migrations/validator.test.ts +660 -0
  885. package/src/migrations/validator.ts +741 -0
  886. package/src/observability/alerting.test.ts +1133 -0
  887. package/src/observability/alerting.ts +455 -0
  888. package/src/observability/analytics-engine.ts +733 -0
  889. package/src/observability/cost-metrics.ts +804 -0
  890. package/src/observability/cross-do-tracing.test.ts +516 -0
  891. package/src/observability/cross-do-tracing.ts +588 -0
  892. package/src/observability/dashboards/postgres-do-overview.json +1656 -0
  893. package/src/observability/error-rate-collector.test.ts +977 -0
  894. package/src/observability/error-rate-collector.ts +518 -0
  895. package/src/observability/exporters.test.ts +365 -0
  896. package/src/observability/exporters.ts +650 -0
  897. package/src/observability/health-check.test.ts +353 -0
  898. package/src/observability/health-check.ts +341 -0
  899. package/src/observability/index.test.ts +298 -0
  900. package/src/observability/index.ts +885 -0
  901. package/src/observability/instrumentation.test.ts +428 -0
  902. package/src/observability/instrumentation.ts +788 -0
  903. package/src/observability/memory-metrics.test.ts +355 -0
  904. package/src/observability/memory-metrics.ts +990 -0
  905. package/src/observability/metrics-endpoint.test.ts +402 -0
  906. package/src/observability/metrics-endpoint.ts +374 -0
  907. package/src/observability/metrics.test.ts +291 -0
  908. package/src/observability/metrics.ts +315 -0
  909. package/src/observability/observability-features.ts +1296 -0
  910. package/src/observability/prometheus.test.ts +292 -0
  911. package/src/observability/prometheus.ts +170 -0
  912. package/src/observability/propagation.test.ts +417 -0
  913. package/src/observability/propagation.ts +294 -0
  914. package/src/observability/query-latency.ts +586 -0
  915. package/src/observability/query-performance.test.ts +406 -0
  916. package/src/observability/query-performance.ts +491 -0
  917. package/src/observability/storage-tier-metrics.test.ts +633 -0
  918. package/src/observability/storage-tier-metrics.ts +570 -0
  919. package/src/observability/tier-cost-optimizer.ts +740 -0
  920. package/src/observability/tracer.test.ts +346 -0
  921. package/src/observability/tracer.ts +585 -0
  922. package/src/observability/types.test.ts +726 -0
  923. package/src/observability/types.ts +434 -0
  924. package/src/pglite/auto-demotion.test.ts +477 -0
  925. package/src/pglite/auto-demotion.ts +385 -0
  926. package/src/pglite/auto-promotion.test.ts +824 -0
  927. package/src/pglite/auto-promotion.ts +547 -0
  928. package/src/pglite/cache-layer.test.ts +469 -0
  929. package/src/pglite/cache-layer.ts +271 -0
  930. package/src/pglite/cold-start-manager.ts +1260 -0
  931. package/src/pglite/cold-start-optimizer.test.ts +937 -0
  932. package/src/pglite/cold-start-optimizer.ts +1895 -0
  933. package/src/pglite/dovfs-adapter.ts +1122 -0
  934. package/src/pglite/dovfs.ts +1258 -0
  935. package/src/pglite/etag-cache.test.ts +844 -0
  936. package/src/pglite/etag-cache.ts +526 -0
  937. package/src/pglite/index.ts +442 -0
  938. package/src/pglite/init.test.ts +455 -0
  939. package/src/pglite/init.ts +574 -0
  940. package/src/pglite/lifecycle.test.ts +599 -0
  941. package/src/pglite/lifecycle.ts +704 -0
  942. package/src/pglite/parallel-loader.test.ts +586 -0
  943. package/src/pglite/parallel-loader.ts +481 -0
  944. package/src/pglite/production-pglite.test.ts +666 -0
  945. package/src/pglite/production-pglite.ts +537 -0
  946. package/src/pglite/query-executor.ts +614 -0
  947. package/src/pglite/r2-layer.test.ts +501 -0
  948. package/src/pglite/r2-layer.ts +322 -0
  949. package/src/pglite/tiered-init.test.ts +725 -0
  950. package/src/pglite/tiered-init.ts +556 -0
  951. package/src/pglite/tiered-vfs.test.ts +726 -0
  952. package/src/pglite/tiered-vfs.ts +33 -0
  953. package/src/pglite/tiering-stats.test.ts +531 -0
  954. package/src/pglite/tiering-stats.ts +407 -0
  955. package/src/pglite/transaction-hooks.ts +343 -0
  956. package/src/pglite/warm-loader.test.ts +1701 -0
  957. package/src/pglite/warm-loader.ts +528 -0
  958. package/src/pglite/workers-pglite.ts +224 -0
  959. package/src/pglite-assets/pglite.data +0 -0
  960. package/src/pglite-assets/pglite.wasm +0 -0
  961. package/src/pglite.d.ts +47 -0
  962. package/src/playground/index.ts +137 -0
  963. package/src/playground/keyboard-shortcuts.ts +677 -0
  964. package/src/playground/playground.ts +323 -0
  965. package/src/playground/query-executor.ts +669 -0
  966. package/src/playground/query-history.ts +328 -0
  967. package/src/playground/result-formatter.ts +420 -0
  968. package/src/playground/sample-datasets.ts +674 -0
  969. package/src/playground/sample-queries.ts +1168 -0
  970. package/src/playground/schema-explorer.ts +558 -0
  971. package/src/playground/types.ts +518 -0
  972. package/src/readonly/cache-reader.test.ts +460 -0
  973. package/src/readonly/cache-reader.ts +313 -0
  974. package/src/readonly/config.test.ts +187 -0
  975. package/src/readonly/config.ts +128 -0
  976. package/src/readonly/index.ts +50 -0
  977. package/src/readonly/pglite-wrapper.test.ts +278 -0
  978. package/src/readonly/pglite-wrapper.ts +184 -0
  979. package/src/readonly/worker.test.ts +533 -0
  980. package/src/readonly/worker.ts +341 -0
  981. package/src/readonly/write-blocker.test.ts +459 -0
  982. package/src/readonly/write-blocker.ts +175 -0
  983. package/src/recovery/disaster-recovery.test.ts +618 -0
  984. package/src/recovery/disaster-recovery.ts +1181 -0
  985. package/src/recovery/index.ts +43 -0
  986. package/src/recovery/parquet-parser.ts +974 -0
  987. package/src/retention/index.ts +74 -0
  988. package/src/retention/policy.test.ts +571 -0
  989. package/src/retention/policy.ts +774 -0
  990. package/src/retention/purger.test.ts +465 -0
  991. package/src/retention/purger.ts +558 -0
  992. package/src/rls/auth-integration.test.ts +752 -0
  993. package/src/rls/auth-integration.ts +533 -0
  994. package/src/rls/generator.test.ts +829 -0
  995. package/src/rls/generator.ts +573 -0
  996. package/src/rls/index.ts +128 -0
  997. package/src/rls/policy.ts +208 -0
  998. package/src/rls/rls.test.ts +1071 -0
  999. package/src/rls/validator.test.ts +930 -0
  1000. package/src/rls/validator.ts +895 -0
  1001. package/src/routing/adaptive-router.test.ts +884 -0
  1002. package/src/routing/adaptive-router.ts +845 -0
  1003. package/src/routing/circuit-breaker.test.ts +1505 -0
  1004. package/src/routing/circuit-breaker.ts +852 -0
  1005. package/src/routing/cost-metrics.test.ts +565 -0
  1006. package/src/routing/cost-metrics.ts +408 -0
  1007. package/src/routing/do-connection-pool.test.ts +1109 -0
  1008. package/src/routing/do-connection-pool.ts +828 -0
  1009. package/src/routing/index.ts +158 -0
  1010. package/src/routing/query-complexity-estimator.test.ts +356 -0
  1011. package/src/routing/query-complexity-estimator.ts +444 -0
  1012. package/src/routing/request-coalescing.test.ts +738 -0
  1013. package/src/routing/request-coalescing.ts +475 -0
  1014. package/src/routing/runtime-router.test.ts +436 -0
  1015. package/src/routing/runtime-router.ts +357 -0
  1016. package/src/routing/tenant-router.test.ts +2493 -0
  1017. package/src/routing/tenant-router.ts +1908 -0
  1018. package/src/routing/websocket-pool.test.ts +551 -0
  1019. package/src/routing/websocket-pool.ts +577 -0
  1020. package/src/storage/access-pattern-tracker.test.ts +874 -0
  1021. package/src/storage/cache-layer.test.ts +560 -0
  1022. package/src/storage/cache-layer.ts +328 -0
  1023. package/src/storage/cost-aware-tiering.test.ts +652 -0
  1024. package/src/storage/cost-aware-tiering.ts +794 -0
  1025. package/src/storage/do-sqlite-blobs.test.ts +937 -0
  1026. package/src/storage/index.ts +272 -0
  1027. package/src/storage/interfaces.ts +974 -0
  1028. package/src/storage/r2-layer.test.ts +653 -0
  1029. package/src/storage/r2-layer.ts +434 -0
  1030. package/src/storage/r2-overflow.ts +920 -0
  1031. package/src/storage/r2-page-vfs.test.ts +2348 -0
  1032. package/src/storage/r2-page-vfs.ts +1054 -0
  1033. package/src/storage/swr-cache.test.ts +832 -0
  1034. package/src/storage/swr-cache.ts +398 -0
  1035. package/src/storage/swr-tiered-integration.test.ts +617 -0
  1036. package/src/storage/tiered-orchestrator.test.ts +2441 -0
  1037. package/src/storage/tiered-orchestrator.ts +2081 -0
  1038. package/src/storage/tiered-vfs-swr.test.ts +736 -0
  1039. package/src/storage/tiered-vfs-swr.ts +735 -0
  1040. package/src/storage/tiered-vfs.test.ts +793 -0
  1041. package/src/storage/tiered-vfs.ts +1082 -0
  1042. package/src/streaming/backpressure-controller.ts +452 -0
  1043. package/src/streaming/buffer-pool.ts +484 -0
  1044. package/src/streaming/cdc-iceberg-connector.ts +605 -0
  1045. package/src/streaming/index.ts +225 -0
  1046. package/src/streaming/live-cdc-stream.ts +985 -0
  1047. package/src/streaming/memory-bounded-stream.ts +443 -0
  1048. package/src/streaming/query-streamer.ts +662 -0
  1049. package/src/streaming/response-streaming.ts +557 -0
  1050. package/src/types/branded.ts +1075 -0
  1051. package/src/types/branded.ts.backup +273 -0
  1052. package/src/types/utilities.ts +1023 -0
  1053. package/src/types/wasm.d.ts +30 -0
  1054. package/src/validation/typed-errors.test.ts +420 -0
  1055. package/src/wal/replay-engine.ts +1264 -0
  1056. package/src/worker/__mocks__/capnweb.ts +15 -0
  1057. package/src/worker/__mocks__/pglite.data.ts +22 -0
  1058. package/src/worker/__mocks__/pglite.wasm.ts +33 -0
  1059. package/src/worker/auth-rate-limiter.test.ts +272 -0
  1060. package/src/worker/auth-rate-limiter.ts +448 -0
  1061. package/src/worker/auth.security-red.test.ts +1236 -0
  1062. package/src/worker/auth.security.test.ts +822 -0
  1063. package/src/worker/auth.test.ts +469 -0
  1064. package/src/worker/auth.ts +1104 -0
  1065. package/src/worker/cdc-backpressure.test.ts +726 -0
  1066. package/src/worker/cdc-backpressure.ts +866 -0
  1067. package/src/worker/cdc-sse.test.ts +780 -0
  1068. package/src/worker/cdc-sse.ts +728 -0
  1069. package/src/worker/cdc-websocket.ts +1229 -0
  1070. package/src/worker/cdc-ws.test.ts +1009 -0
  1071. package/src/worker/cdc.test.ts +327 -0
  1072. package/src/worker/cdc.ts +289 -0
  1073. package/src/worker/concerns/auth-concern.ts +179 -0
  1074. package/src/worker/concerns/cdc-concern.ts +247 -0
  1075. package/src/worker/concerns/index.ts +58 -0
  1076. package/src/worker/concerns/query-execution-concern.ts +194 -0
  1077. package/src/worker/concerns/storage-orchestration-concern.ts +373 -0
  1078. package/src/worker/discriminated-types.test.ts +280 -0
  1079. package/src/worker/do-auth-manager.ts +257 -0
  1080. package/src/worker/do-decomposition.test.ts +1236 -0
  1081. package/src/worker/do-pglite-manager.ts +302 -0
  1082. package/src/worker/do.test.ts +2254 -0
  1083. package/src/worker/do.ts +1878 -0
  1084. package/src/worker/entry.ts +417 -0
  1085. package/src/worker/errors.ts +285 -0
  1086. package/src/worker/health-check-manager.test.ts +261 -0
  1087. package/src/worker/health-check-manager.ts +231 -0
  1088. package/src/worker/index.ts +389 -0
  1089. package/src/worker/memory-pressure.test.ts +1460 -0
  1090. package/src/worker/memory-pressure.ts +2650 -0
  1091. package/src/worker/migration-manager.ts +582 -0
  1092. package/src/worker/neon-compat.test.ts +332 -0
  1093. package/src/worker/plugin-manager.ts +485 -0
  1094. package/src/worker/postgres.do-rpc.d.ts +76 -0
  1095. package/src/worker/proxy.ts +694 -0
  1096. package/src/worker/query-execution-manager.test.ts +303 -0
  1097. package/src/worker/query-execution-manager.ts +219 -0
  1098. package/src/worker/query-executor.test.ts +282 -0
  1099. package/src/worker/query-executor.ts +560 -0
  1100. package/src/worker/query-stats-manager.ts +229 -0
  1101. package/src/worker/result-handler.test.ts +364 -0
  1102. package/src/worker/result-handler.ts +510 -0
  1103. package/src/worker/routes.test.ts +795 -0
  1104. package/src/worker/routes.ts +650 -0
  1105. package/src/worker/rpc-methods-manager.test.ts +326 -0
  1106. package/src/worker/rpc-methods-manager.ts +276 -0
  1107. package/src/worker/rpc.ts +524 -0
  1108. package/src/worker/schema-version.ts +605 -0
  1109. package/src/worker/session-manager.test.ts +506 -0
  1110. package/src/worker/session-manager.ts +732 -0
  1111. package/src/worker/shutdown-manager.ts +469 -0
  1112. package/src/worker/sql-transform.test.ts +286 -0
  1113. package/src/worker/sql-transform.ts +368 -0
  1114. package/src/worker/supabase-compat.test.ts +621 -0
  1115. package/src/worker/types.test.ts +292 -0
  1116. package/src/worker/types.ts +873 -0
  1117. package/src/worker/user-routes.test.ts +703 -0
  1118. package/src/worker/user-routes.ts +303 -0
  1119. package/src/worker/wal-facade.ts +235 -0
  1120. package/src/worker/wal-r2.test.ts +570 -0
  1121. package/src/worker/wal-r2.ts +930 -0
  1122. package/src/worker/wal-replay.test.ts +845 -0
  1123. package/src/worker/wal-replay.ts +897 -0
  1124. package/src/worker/wal-retention.test.ts +758 -0
  1125. package/src/worker/wal-retention.ts +1075 -0
  1126. package/src/worker/wal.test.ts +618 -0
  1127. package/src/worker/wal.ts +697 -0
  1128. package/src/worker/websocket.test.ts +296 -0
  1129. package/src/worker/websocket.ts +284 -0
@@ -0,0 +1,1236 @@
1
+ /**
2
+ * RED PHASE: Worker Authentication Security Tests
3
+ *
4
+ * SECURITY CRITICAL: These tests protect against unauthorized access.
5
+ *
6
+ * Issue: postgres-8y64 - [P0-RED] Worker auth missing tests - auth bypass risk
7
+ *
8
+ * These tests are intentionally written to FAIL because the security features
9
+ * they verify are not yet implemented or have gaps. Each failing test represents
10
+ * a security vulnerability that needs to be addressed.
11
+ *
12
+ * Tests verify:
13
+ * 1. Token validation works correctly (cryptographic verification)
14
+ * 2. Expired tokens are rejected (with edge cases)
15
+ * 3. Invalid signatures are rejected (cryptographic validation)
16
+ * 4. Rate limiting prevents brute force (comprehensive scenarios)
17
+ * 5. SQL injection in claims is blocked (all injection vectors)
18
+ * 6. Clock skew handling (boundary conditions)
19
+ */
20
+
21
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
22
+ import { Hono } from 'hono'
23
+ import {
24
+ createAuthMiddleware,
25
+ requireAuth,
26
+ getAuth,
27
+ generateDatabaseId,
28
+ clearTokenCache,
29
+ clearRateLimitState,
30
+ type AuthConfig,
31
+ type AuthContext,
32
+ type AuthenticatedUser,
33
+ } from './auth'
34
+
35
+ // Mock fetch for testing
36
+ const mockFetch = vi.fn()
37
+ let originalFetch: typeof fetch
38
+
39
+ beforeEach(() => {
40
+ mockFetch.mockReset()
41
+ originalFetch = globalThis.fetch
42
+ globalThis.fetch = mockFetch
43
+ clearTokenCache()
44
+ clearRateLimitState()
45
+ })
46
+
47
+ afterEach(() => {
48
+ globalThis.fetch = originalFetch
49
+ })
50
+
51
+ /**
52
+ * Helper to create a test app with auth middleware
53
+ */
54
+ function createTestApp(config: AuthConfig = {}) {
55
+ const app = new Hono<{ Variables: { auth: AuthContext } }>()
56
+ app.use('*', createAuthMiddleware(config))
57
+
58
+ app.get('/api/protected', (c) => {
59
+ const auth = getAuth(c)
60
+ return c.json({
61
+ user: auth.user,
62
+ databaseId: auth.databaseId,
63
+ isAuthenticated: auth.isAuthenticated,
64
+ })
65
+ })
66
+
67
+ app.get('/api/admin', requireAuth(), (c) => {
68
+ const auth = getAuth(c)
69
+ return c.json({ admin: true, user: auth.user })
70
+ })
71
+
72
+ return app
73
+ }
74
+
75
+ /**
76
+ * Helper to create a JWT-like token for testing
77
+ */
78
+ function createTestJWT(
79
+ payload: Record<string, unknown>,
80
+ options: { header?: Record<string, unknown>; signature?: string } = {}
81
+ ): string {
82
+ const header = options.header ?? { alg: 'HS256', typ: 'JWT' }
83
+ const signature = options.signature ?? 'test-signature'
84
+
85
+ const headerB64 = btoa(JSON.stringify(header))
86
+ const payloadB64 = btoa(JSON.stringify(payload))
87
+
88
+ return `${headerB64}.${payloadB64}.${signature}`
89
+ }
90
+
91
+ // =============================================================================
92
+ // 1. TOKEN VALIDATION - CRYPTOGRAPHIC VERIFICATION
93
+ // =============================================================================
94
+
95
+ describe('[RED] Token Cryptographic Validation', () => {
96
+ describe('Signature verification', () => {
97
+ it.fails('should reject tokens with forged signatures when using default validator', async () => {
98
+ // RED: Default oauth.do validator should verify signatures cryptographically
99
+ // Currently, if oauth.do returns success, the forged token is accepted
100
+ // This test FAILS because we need proper signature verification
101
+ mockFetch.mockResolvedValueOnce({
102
+ ok: true,
103
+ json: async () => ({
104
+ user: { id: 'attacker', email: 'attacker@evil.com' },
105
+ }),
106
+ })
107
+
108
+ const app = createTestApp()
109
+
110
+ // Attacker creates a token with forged payload but mock oauth.do accepts it
111
+ const forgedToken = createTestJWT({
112
+ sub: 'admin',
113
+ role: 'super_admin',
114
+ exp: Math.floor(Date.now() / 1000) + 3600,
115
+ })
116
+
117
+ const res = await app.request('/api/protected', {
118
+ headers: { Authorization: `Bearer ${forgedToken}` },
119
+ })
120
+
121
+ // Should be 401 but currently returns 200 if oauth.do is mocked to accept
122
+ expect(res.status).toBe(401)
123
+ })
124
+
125
+ it.fails('should verify signature using the correct secret/public key', async () => {
126
+ // RED: Middleware should validate signatures locally before hitting oauth.do
127
+ // Currently relies entirely on external validation
128
+ const app = createTestApp({
129
+ validateToken: async (token: string) => {
130
+ // Simulates accepting any token without cryptographic verification
131
+ const parts = token.split('.')
132
+ if (parts.length !== 3) {
133
+ return { valid: false, error: 'Invalid format' }
134
+ }
135
+ const payload = JSON.parse(atob(parts[1]))
136
+ return { valid: true, user: { id: payload.sub, email: 'test@test.com' } }
137
+ },
138
+ })
139
+
140
+ // Token signed with wrong key should be rejected
141
+ const wrongKeyToken = createTestJWT({
142
+ sub: 'user123',
143
+ exp: Math.floor(Date.now() / 1000) + 3600,
144
+ }, { signature: 'signed-with-wrong-key' })
145
+
146
+ const res = await app.request('/api/protected', {
147
+ headers: { Authorization: `Bearer ${wrongKeyToken}` },
148
+ })
149
+
150
+ // This should fail because signature is not verified
151
+ expect(res.status).toBe(401)
152
+ })
153
+
154
+ it.fails('should reject tokens with truncated signatures', async () => {
155
+ // RED: Truncated signatures should be rejected
156
+ const app = createTestApp({
157
+ validateToken: async (token: string) => {
158
+ const parts = token.split('.')
159
+ if (parts.length !== 3) return { valid: false, error: 'Invalid' }
160
+ // Does not check signature length
161
+ const payload = JSON.parse(atob(parts[1]))
162
+ return { valid: true, user: { id: payload.sub, email: 'test@test.com' } }
163
+ },
164
+ })
165
+
166
+ // Very short signature (truncated attack)
167
+ const truncatedSigToken = createTestJWT(
168
+ { sub: 'user123', exp: Math.floor(Date.now() / 1000) + 3600 },
169
+ { signature: 'a' } // Truncated to 1 character
170
+ )
171
+
172
+ const res = await app.request('/api/protected', {
173
+ headers: { Authorization: `Bearer ${truncatedSigToken}` },
174
+ })
175
+
176
+ // Should reject truncated signatures
177
+ expect(res.status).toBe(401)
178
+ })
179
+
180
+ it.fails('should reject tokens with null signature (different from empty)', async () => {
181
+ // RED: null signature attack vector
182
+ const app = createTestApp({
183
+ validateToken: async (token: string) => {
184
+ const parts = token.split('.')
185
+ if (parts.length !== 3) return { valid: false, error: 'Invalid' }
186
+ const payload = JSON.parse(atob(parts[1]))
187
+ return { valid: true, user: { id: payload.sub, email: 'test@test.com' } }
188
+ },
189
+ })
190
+
191
+ // Signature that decodes to null
192
+ const nullSigToken = createTestJWT(
193
+ { sub: 'user123', exp: Math.floor(Date.now() / 1000) + 3600 },
194
+ { signature: btoa('null') }
195
+ )
196
+
197
+ const res = await app.request('/api/protected', {
198
+ headers: { Authorization: `Bearer ${nullSigToken}` },
199
+ })
200
+
201
+ expect(res.status).toBe(401)
202
+ })
203
+ })
204
+
205
+ describe('Algorithm enforcement', () => {
206
+ it.fails('should only accept explicitly configured algorithms', async () => {
207
+ // RED: Should have allowlist of algorithms, not just blocklist of 'none'
208
+ const app = createTestApp({
209
+ validateToken: async (token: string) => {
210
+ const parts = token.split('.')
211
+ if (parts.length !== 3) return { valid: false, error: 'Invalid' }
212
+ const header = JSON.parse(atob(parts[0]))
213
+ // Only blocks 'none', but accepts any other algorithm
214
+ if (header.alg === 'none') return { valid: false, error: 'Invalid algorithm' }
215
+ const payload = JSON.parse(atob(parts[1]))
216
+ return { valid: true, user: { id: payload.sub, email: 'test@test.com' } }
217
+ },
218
+ })
219
+
220
+ // Weak algorithms that should be rejected
221
+ const weakAlgorithms = ['HS1', 'MD5', 'SHA1', 'PS256-WEAK', 'CUSTOM']
222
+
223
+ for (const alg of weakAlgorithms) {
224
+ const token = createTestJWT(
225
+ { sub: 'user123', exp: Math.floor(Date.now() / 1000) + 3600 },
226
+ { header: { alg, typ: 'JWT' } }
227
+ )
228
+
229
+ const res = await app.request('/api/protected', {
230
+ headers: { Authorization: `Bearer ${token}` },
231
+ })
232
+
233
+ // Should reject weak/unknown algorithms
234
+ expect(res.status).toBe(401)
235
+ }
236
+ })
237
+
238
+ it.fails('should reject jwk header injection attack', async () => {
239
+ // RED: JWK header injection allows attacker to specify their own key
240
+ const app = createTestApp({
241
+ validateToken: async (token: string) => {
242
+ const parts = token.split('.')
243
+ if (parts.length !== 3) return { valid: false, error: 'Invalid' }
244
+ const header = JSON.parse(atob(parts[0]))
245
+ // Does not check for jwk header injection
246
+ if (header.alg === 'none') return { valid: false, error: 'Invalid algorithm' }
247
+ const payload = JSON.parse(atob(parts[1]))
248
+ return { valid: true, user: { id: payload.sub, email: 'test@test.com' } }
249
+ },
250
+ })
251
+
252
+ // Token with embedded JWK (attacker's key)
253
+ const jwkToken = createTestJWT(
254
+ { sub: 'admin', role: 'admin', exp: Math.floor(Date.now() / 1000) + 3600 },
255
+ {
256
+ header: {
257
+ alg: 'RS256',
258
+ typ: 'JWT',
259
+ jwk: {
260
+ kty: 'RSA',
261
+ n: 'attacker-public-key-n',
262
+ e: 'AQAB',
263
+ },
264
+ },
265
+ }
266
+ )
267
+
268
+ const res = await app.request('/api/protected', {
269
+ headers: { Authorization: `Bearer ${jwkToken}` },
270
+ })
271
+
272
+ // Should reject tokens with embedded JWK
273
+ expect(res.status).toBe(401)
274
+ })
275
+
276
+ it.fails('should reject jku header injection attack', async () => {
277
+ // RED: JKU header injection allows attacker to specify key URL
278
+ const app = createTestApp({
279
+ validateToken: async (token: string) => {
280
+ const parts = token.split('.')
281
+ if (parts.length !== 3) return { valid: false, error: 'Invalid' }
282
+ const header = JSON.parse(atob(parts[0]))
283
+ if (header.alg === 'none') return { valid: false, error: 'Invalid algorithm' }
284
+ const payload = JSON.parse(atob(parts[1]))
285
+ return { valid: true, user: { id: payload.sub, email: 'test@test.com' } }
286
+ },
287
+ })
288
+
289
+ // Token with JKU pointing to attacker's server
290
+ const jkuToken = createTestJWT(
291
+ { sub: 'admin', role: 'admin', exp: Math.floor(Date.now() / 1000) + 3600 },
292
+ {
293
+ header: {
294
+ alg: 'RS256',
295
+ typ: 'JWT',
296
+ jku: 'https://attacker.com/jwks.json',
297
+ },
298
+ }
299
+ )
300
+
301
+ const res = await app.request('/api/protected', {
302
+ headers: { Authorization: `Bearer ${jkuToken}` },
303
+ })
304
+
305
+ // Should reject tokens with jku header
306
+ expect(res.status).toBe(401)
307
+ })
308
+ })
309
+ })
310
+
311
+ // =============================================================================
312
+ // 2. EXPIRED TOKENS - EDGE CASES
313
+ // =============================================================================
314
+
315
+ describe('[RED] Expired Token Edge Cases', () => {
316
+ describe('Expiration boundary conditions', () => {
317
+ it.fails('should reject tokens that expire during request processing', async () => {
318
+ // RED: Race condition - token valid at start but expires during processing
319
+ const nowSeconds = Math.floor(Date.now() / 1000)
320
+
321
+ const app = createTestApp({
322
+ validateToken: async (token: string) => {
323
+ // Simulate slow validation (100ms)
324
+ await new Promise((resolve) => setTimeout(resolve, 100))
325
+
326
+ const parts = token.split('.')
327
+ const payload = JSON.parse(atob(parts[1]))
328
+
329
+ // Check expiration AFTER delay - token may have expired
330
+ const currentTime = Math.floor(Date.now() / 1000)
331
+ if (payload.exp && payload.exp < currentTime) {
332
+ return { valid: false, error: 'Token expired' }
333
+ }
334
+
335
+ return { valid: true, user: { id: payload.sub, email: 'test@test.com' } }
336
+ },
337
+ })
338
+
339
+ // Token that expires in 50ms (before validation completes)
340
+ const expiringToken = createTestJWT({
341
+ sub: 'user123',
342
+ exp: nowSeconds + 0.05, // Expires in 50ms
343
+ })
344
+
345
+ const res = await app.request('/api/protected', {
346
+ headers: { Authorization: `Bearer ${expiringToken}` },
347
+ })
348
+
349
+ // Should be rejected because token expired during processing
350
+ expect(res.status).toBe(401)
351
+ })
352
+
353
+ it.fails('should reject tokens with exp exactly at current time (boundary)', async () => {
354
+ // RED: Boundary condition - exp === now should be treated as expired
355
+ const nowSeconds = Math.floor(Date.now() / 1000)
356
+
357
+ const app = createTestApp({
358
+ validateToken: async (token: string) => {
359
+ const parts = token.split('.')
360
+ const payload = JSON.parse(atob(parts[1]))
361
+ // Bug: Uses >= instead of > allowing exp === now
362
+ if (payload.exp && payload.exp >= Math.floor(Date.now() / 1000)) {
363
+ return { valid: true, user: { id: payload.sub, email: 'test@test.com' } }
364
+ }
365
+ return { valid: false, error: 'Token expired' }
366
+ },
367
+ })
368
+
369
+ // Token that expires exactly now
370
+ const boundaryToken = createTestJWT({
371
+ sub: 'user123',
372
+ exp: nowSeconds,
373
+ })
374
+
375
+ const res = await app.request('/api/protected', {
376
+ headers: { Authorization: `Bearer ${boundaryToken}` },
377
+ })
378
+
379
+ // Should be rejected - exp === now means expired
380
+ expect(res.status).toBe(401)
381
+ })
382
+
383
+ it('should reject tokens with exp as string instead of number', async () => {
384
+ // RED: Type coercion attack - exp as string
385
+ const app = createTestApp({
386
+ validateToken: async (token: string) => {
387
+ const parts = token.split('.')
388
+ const payload = JSON.parse(atob(parts[1]))
389
+ // Bug: Doesn't validate exp is a number
390
+ if (payload.exp && payload.exp > Math.floor(Date.now() / 1000)) {
391
+ return { valid: true, user: { id: payload.sub, email: 'test@test.com' } }
392
+ }
393
+ return { valid: false, error: 'Token expired' }
394
+ },
395
+ })
396
+
397
+ // exp as string that coerces to large number
398
+ const stringExpToken = createTestJWT({
399
+ sub: 'user123',
400
+ exp: '9999999999', // String, not number
401
+ })
402
+
403
+ const res = await app.request('/api/protected', {
404
+ headers: { Authorization: `Bearer ${stringExpToken}` },
405
+ })
406
+
407
+ // Should reject - exp must be a number
408
+ expect(res.status).toBe(401)
409
+ })
410
+
411
+ it('should reject tokens with exp as array', async () => {
412
+ // RED: Type confusion - exp as array
413
+ const app = createTestApp({
414
+ validateToken: async (token: string) => {
415
+ const parts = token.split('.')
416
+ const payload = JSON.parse(atob(parts[1]))
417
+ // Bug: Doesn't check if exp is actually a number
418
+ if (payload.exp > Math.floor(Date.now() / 1000)) {
419
+ return { valid: true, user: { id: payload.sub, email: 'test@test.com' } }
420
+ }
421
+ return { valid: false, error: 'Token expired' }
422
+ },
423
+ })
424
+
425
+ // exp as array
426
+ const arrayExpToken = createTestJWT({
427
+ sub: 'user123',
428
+ exp: [9999999999],
429
+ })
430
+
431
+ const res = await app.request('/api/protected', {
432
+ headers: { Authorization: `Bearer ${arrayExpToken}` },
433
+ })
434
+
435
+ // Should reject - exp must be a number
436
+ expect(res.status).toBe(401)
437
+ })
438
+
439
+ it('should reject tokens with exp as object', async () => {
440
+ // RED: Type confusion - exp as object
441
+ const app = createTestApp({
442
+ validateToken: async (token: string) => {
443
+ const parts = token.split('.')
444
+ const payload = JSON.parse(atob(parts[1]))
445
+ if (payload.exp > Math.floor(Date.now() / 1000)) {
446
+ return { valid: true, user: { id: payload.sub, email: 'test@test.com' } }
447
+ }
448
+ return { valid: false, error: 'Token expired' }
449
+ },
450
+ })
451
+
452
+ // exp as object with valueOf
453
+ const objectExpToken = createTestJWT({
454
+ sub: 'user123',
455
+ exp: { valueOf: 9999999999 },
456
+ })
457
+
458
+ const res = await app.request('/api/protected', {
459
+ headers: { Authorization: `Bearer ${objectExpToken}` },
460
+ })
461
+
462
+ // Should reject - exp must be a number
463
+ expect(res.status).toBe(401)
464
+ })
465
+
466
+ it('should reject tokens with exp as Infinity', async () => {
467
+ // RED: Never-expiring token attack
468
+ const app = createTestApp({
469
+ validateToken: async (token: string) => {
470
+ const parts = token.split('.')
471
+ const payload = JSON.parse(atob(parts[1]))
472
+ if (!isFinite(payload.exp)) {
473
+ return { valid: false, error: 'Invalid expiration' }
474
+ }
475
+ if (payload.exp > Math.floor(Date.now() / 1000)) {
476
+ return { valid: true, user: { id: payload.sub, email: 'test@test.com' } }
477
+ }
478
+ return { valid: false, error: 'Token expired' }
479
+ },
480
+ })
481
+
482
+ // This test would need special handling since JSON doesn't support Infinity
483
+ // We test with a very large number instead
484
+ const infinityLikeToken = createTestJWT({
485
+ sub: 'user123',
486
+ exp: Number.MAX_SAFE_INTEGER,
487
+ })
488
+
489
+ const res = await app.request('/api/protected', {
490
+ headers: { Authorization: `Bearer ${infinityLikeToken}` },
491
+ })
492
+
493
+ // Should reject tokens with unreasonably far future exp
494
+ expect(res.status).toBe(401)
495
+ })
496
+
497
+ it('should enforce maximum token lifetime', async () => {
498
+ // RED: Tokens with exp too far in the future should be rejected
499
+ const app = createTestApp({
500
+ validateToken: async (token: string) => {
501
+ const parts = token.split('.')
502
+ const payload = JSON.parse(atob(parts[1]))
503
+ const now = Math.floor(Date.now() / 1000)
504
+ const maxLifetime = 24 * 60 * 60 // 24 hours max
505
+
506
+ // Bug: No maximum lifetime check
507
+ if (payload.exp && payload.exp > now) {
508
+ return { valid: true, user: { id: payload.sub, email: 'test@test.com' } }
509
+ }
510
+ return { valid: false, error: 'Token expired' }
511
+ },
512
+ })
513
+
514
+ // Token valid for 1 year (should be rejected)
515
+ const longLivedToken = createTestJWT({
516
+ sub: 'user123',
517
+ exp: Math.floor(Date.now() / 1000) + 365 * 24 * 60 * 60,
518
+ })
519
+
520
+ const res = await app.request('/api/protected', {
521
+ headers: { Authorization: `Bearer ${longLivedToken}` },
522
+ })
523
+
524
+ // Should reject - token lifetime exceeds maximum
525
+ expect(res.status).toBe(401)
526
+ })
527
+ })
528
+ })
529
+
530
+ // =============================================================================
531
+ // 3. INVALID SIGNATURES - COMPREHENSIVE
532
+ // =============================================================================
533
+
534
+ describe('[RED] Invalid Signature Handling', () => {
535
+ describe('Signature manipulation attacks', () => {
536
+ it.fails('should reject signature with appended data', async () => {
537
+ // RED: Appending data to valid signature
538
+ const app = createTestApp({
539
+ validateToken: async (token: string) => {
540
+ const parts = token.split('.')
541
+ if (parts.length !== 3) return { valid: false, error: 'Invalid' }
542
+ const payload = JSON.parse(atob(parts[1]))
543
+ // Bug: Doesn't verify signature integrity
544
+ return { valid: true, user: { id: payload.sub, email: 'test@test.com' } }
545
+ },
546
+ })
547
+
548
+ const tokenWithAppendedSig = createTestJWT(
549
+ { sub: 'user123', exp: Math.floor(Date.now() / 1000) + 3600 },
550
+ { signature: 'valid-signature-APPENDED_DATA' }
551
+ )
552
+
553
+ const res = await app.request('/api/protected', {
554
+ headers: { Authorization: `Bearer ${tokenWithAppendedSig}` },
555
+ })
556
+
557
+ expect(res.status).toBe(401)
558
+ })
559
+
560
+ it.fails('should reject signature with prepended data', async () => {
561
+ // RED: Prepending data to valid signature
562
+ const app = createTestApp({
563
+ validateToken: async (token: string) => {
564
+ const parts = token.split('.')
565
+ if (parts.length !== 3) return { valid: false, error: 'Invalid' }
566
+ const payload = JSON.parse(atob(parts[1]))
567
+ return { valid: true, user: { id: payload.sub, email: 'test@test.com' } }
568
+ },
569
+ })
570
+
571
+ const tokenWithPrependedSig = createTestJWT(
572
+ { sub: 'user123', exp: Math.floor(Date.now() / 1000) + 3600 },
573
+ { signature: 'PREPENDED_DATA-valid-signature' }
574
+ )
575
+
576
+ const res = await app.request('/api/protected', {
577
+ headers: { Authorization: `Bearer ${tokenWithPrependedSig}` },
578
+ })
579
+
580
+ expect(res.status).toBe(401)
581
+ })
582
+
583
+ it.fails('should reject signature with modified byte', async () => {
584
+ // RED: Single byte modification in signature
585
+ const app = createTestApp({
586
+ validateToken: async (token: string) => {
587
+ const parts = token.split('.')
588
+ if (parts.length !== 3) return { valid: false, error: 'Invalid' }
589
+ const payload = JSON.parse(atob(parts[1]))
590
+ return { valid: true, user: { id: payload.sub, email: 'test@test.com' } }
591
+ },
592
+ })
593
+
594
+ // Signature with one character changed
595
+ const modifiedSigToken = createTestJWT(
596
+ { sub: 'user123', exp: Math.floor(Date.now() / 1000) + 3600 },
597
+ { signature: 'valid-signaturX' } // X instead of e
598
+ )
599
+
600
+ const res = await app.request('/api/protected', {
601
+ headers: { Authorization: `Bearer ${modifiedSigToken}` },
602
+ })
603
+
604
+ expect(res.status).toBe(401)
605
+ })
606
+
607
+ it.fails('should reject base64url vs base64 confusion in signature', async () => {
608
+ // RED: Base64 encoding confusion attack
609
+ const app = createTestApp({
610
+ validateToken: async (token: string) => {
611
+ const parts = token.split('.')
612
+ if (parts.length !== 3) return { valid: false, error: 'Invalid' }
613
+ const payload = JSON.parse(atob(parts[1]))
614
+ return { valid: true, user: { id: payload.sub, email: 'test@test.com' } }
615
+ },
616
+ })
617
+
618
+ // Use standard base64 characters instead of base64url
619
+ const base64ConfusionToken = createTestJWT(
620
+ { sub: 'user123', exp: Math.floor(Date.now() / 1000) + 3600 },
621
+ { signature: 'sig+with/base64+chars==' } // + and / instead of - and _
622
+ )
623
+
624
+ const res = await app.request('/api/protected', {
625
+ headers: { Authorization: `Bearer ${base64ConfusionToken}` },
626
+ })
627
+
628
+ // Should normalize and reject if doesn't match
629
+ expect(res.status).toBe(401)
630
+ })
631
+ })
632
+ })
633
+
634
+ // =============================================================================
635
+ // 4. RATE LIMITING - BRUTE FORCE PREVENTION
636
+ // =============================================================================
637
+
638
+ describe('[RED] Rate Limiting Brute Force Prevention', () => {
639
+ describe('Rate limit bypass attempts', () => {
640
+ it('should rate limit by IP address, not just by token', async () => {
641
+ // RED: Current implementation rate limits by token prefix
642
+ // Attacker can bypass by using different tokens from same IP
643
+ const requestsFromIP = new Map<string, number>()
644
+ const ipRateLimit = 100
645
+
646
+ const app = new Hono<{ Variables: { auth: AuthContext } }>()
647
+ app.use('*', async (c, next) => {
648
+ const ip = c.req.header('CF-Connecting-IP') || '127.0.0.1'
649
+ const count = (requestsFromIP.get(ip) || 0) + 1
650
+ requestsFromIP.set(ip, count)
651
+
652
+ if (count > ipRateLimit) {
653
+ return c.json({ error: true, code: 'RATE_LIMITED' }, 429)
654
+ }
655
+ return next()
656
+ })
657
+ app.use('*', createAuthMiddleware({
658
+ validateToken: async () => ({ valid: false, error: 'Invalid' }),
659
+ }))
660
+ app.get('/api/protected', (c) => c.json({ success: true }))
661
+
662
+ // Attacker tries many different tokens from same IP
663
+ for (let i = 0; i < ipRateLimit + 10; i++) {
664
+ clearTokenCache()
665
+ const uniqueToken = createTestJWT({ sub: `attempt-${i}` })
666
+ const res = await app.request('/api/protected', {
667
+ headers: {
668
+ Authorization: `Bearer ${uniqueToken}`,
669
+ 'CF-Connecting-IP': '192.168.1.100',
670
+ },
671
+ })
672
+
673
+ if (i >= ipRateLimit) {
674
+ // Should be rate limited by IP
675
+ expect(res.status).toBe(429)
676
+ }
677
+ }
678
+ })
679
+
680
+ it.fails('should implement exponential backoff for repeated failures', async () => {
681
+ // RED: Should increase delay between allowed attempts after failures
682
+ const failureCount = new Map<string, { count: number; lastAttempt: number }>()
683
+
684
+ const app = createTestApp({
685
+ validateToken: async (token: string) => {
686
+ const key = token.slice(0, 20)
687
+ const entry = failureCount.get(key) || { count: 0, lastAttempt: 0 }
688
+ const now = Date.now()
689
+
690
+ // Exponential backoff: 2^failures seconds
691
+ const requiredDelay = Math.pow(2, entry.count) * 1000
692
+ if (now - entry.lastAttempt < requiredDelay) {
693
+ return { valid: false, error: 'Rate limited - exponential backoff' }
694
+ }
695
+
696
+ entry.count++
697
+ entry.lastAttempt = now
698
+ failureCount.set(key, entry)
699
+
700
+ return { valid: false, error: 'Invalid token' }
701
+ },
702
+ })
703
+
704
+ const token = createTestJWT({ sub: 'brute-force-attempt' })
705
+
706
+ // Rapid sequential requests should be blocked with increasing delays
707
+ const results: number[] = []
708
+ for (let i = 0; i < 5; i++) {
709
+ clearTokenCache()
710
+ const res = await app.request('/api/protected', {
711
+ headers: { Authorization: `Bearer ${token}` },
712
+ })
713
+ results.push(res.status)
714
+ }
715
+
716
+ // After several attempts, should see rate limiting
717
+ expect(results.filter((s) => s === 429).length).toBeGreaterThan(0)
718
+ })
719
+
720
+ it('should prevent distributed brute force from multiple IPs', async () => {
721
+ // RED: Should detect patterns across multiple IPs targeting same account
722
+ const targetUser = 'victim@example.com'
723
+ const attemptsByTarget = new Map<string, number>()
724
+ const distributedLimit = 50
725
+
726
+ const app = createTestApp({
727
+ validateToken: async (token: string) => {
728
+ const parts = token.split('.')
729
+ const payload = JSON.parse(atob(parts[1]))
730
+ const targetEmail = payload.email
731
+
732
+ if (targetEmail) {
733
+ const count = (attemptsByTarget.get(targetEmail) || 0) + 1
734
+ attemptsByTarget.set(targetEmail, count)
735
+
736
+ if (count > distributedLimit) {
737
+ return { valid: false, error: 'Account locked due to suspicious activity' }
738
+ }
739
+ }
740
+
741
+ return { valid: false, error: 'Invalid credentials' }
742
+ },
743
+ })
744
+
745
+ // Distributed attack from different IPs
746
+ for (let i = 0; i < distributedLimit + 10; i++) {
747
+ clearTokenCache()
748
+ const token = createTestJWT({
749
+ sub: 'unknown',
750
+ email: targetUser,
751
+ password_attempt: `password${i}`,
752
+ })
753
+
754
+ const res = await app.request('/api/protected', {
755
+ headers: {
756
+ Authorization: `Bearer ${token}`,
757
+ 'CF-Connecting-IP': `192.168.${Math.floor(i / 255)}.${i % 255}`,
758
+ },
759
+ })
760
+
761
+ if (i >= distributedLimit) {
762
+ // Should detect distributed attack and lock account
763
+ expect(res.status).toBe(429)
764
+ }
765
+ }
766
+ })
767
+
768
+ it('should apply stricter rate limits for sensitive operations', async () => {
769
+ // RED: Different rate limits for different endpoints
770
+ const requestCounts = new Map<string, number>()
771
+
772
+ const app = new Hono<{ Variables: { auth: AuthContext } }>()
773
+ app.use('*', createAuthMiddleware({
774
+ validateToken: async () => ({
775
+ valid: true,
776
+ user: { id: 'user123', email: 'test@test.com' },
777
+ }),
778
+ }))
779
+
780
+ // Stricter rate limit for sensitive endpoint
781
+ app.get('/api/admin', async (c, next) => {
782
+ const key = 'admin'
783
+ const count = (requestCounts.get(key) || 0) + 1
784
+ requestCounts.set(key, count)
785
+
786
+ if (count > 5) { // Only 5 requests allowed
787
+ return c.json({ error: true, code: 'RATE_LIMITED' }, 429)
788
+ }
789
+ return c.json({ admin: true })
790
+ })
791
+
792
+ const token = createTestJWT({ sub: 'user123' })
793
+
794
+ // Should hit rate limit quickly for admin endpoint
795
+ for (let i = 0; i < 10; i++) {
796
+ clearTokenCache()
797
+ const res = await app.request('/api/admin', {
798
+ headers: { Authorization: `Bearer ${token}` },
799
+ })
800
+
801
+ if (i >= 5) {
802
+ expect(res.status).toBe(429)
803
+ }
804
+ }
805
+ })
806
+ })
807
+ })
808
+
809
+ // =============================================================================
810
+ // 5. SQL INJECTION IN CLAIMS
811
+ // =============================================================================
812
+
813
+ describe('[RED] SQL Injection in Claims', () => {
814
+ describe('SQL injection vectors in user ID', () => {
815
+ it('should block union-based SQL injection in sub claim', async () => {
816
+ // RED: UNION injection in user ID
817
+ const app = createTestApp({
818
+ validateToken: async (token: string) => {
819
+ const parts = token.split('.')
820
+ const payload = JSON.parse(atob(parts[1]))
821
+ // Returns user with potentially malicious ID
822
+ return { valid: true, user: { id: payload.sub, email: 'test@test.com' } }
823
+ },
824
+ })
825
+
826
+ const unionInjectionToken = createTestJWT({
827
+ sub: "1' UNION SELECT * FROM users--",
828
+ exp: Math.floor(Date.now() / 1000) + 3600,
829
+ })
830
+
831
+ const res = await app.request('/api/protected', {
832
+ headers: { Authorization: `Bearer ${unionInjectionToken}` },
833
+ })
834
+
835
+ // Should reject SQL injection patterns
836
+ expect(res.status).toBe(401)
837
+ })
838
+
839
+ it('should block time-based blind SQL injection', async () => {
840
+ // RED: Time-based blind injection
841
+ const app = createTestApp({
842
+ validateToken: async (token: string) => {
843
+ const parts = token.split('.')
844
+ const payload = JSON.parse(atob(parts[1]))
845
+ return { valid: true, user: { id: payload.sub, email: 'test@test.com' } }
846
+ },
847
+ })
848
+
849
+ const blindInjectionToken = createTestJWT({
850
+ sub: "1'; WAITFOR DELAY '00:00:05'--",
851
+ exp: Math.floor(Date.now() / 1000) + 3600,
852
+ })
853
+
854
+ const res = await app.request('/api/protected', {
855
+ headers: { Authorization: `Bearer ${blindInjectionToken}` },
856
+ })
857
+
858
+ expect(res.status).toBe(401)
859
+ })
860
+
861
+ it('should block stacked queries injection', async () => {
862
+ // RED: Stacked queries
863
+ const app = createTestApp({
864
+ validateToken: async (token: string) => {
865
+ const parts = token.split('.')
866
+ const payload = JSON.parse(atob(parts[1]))
867
+ return { valid: true, user: { id: payload.sub, email: 'test@test.com' } }
868
+ },
869
+ })
870
+
871
+ const stackedToken = createTestJWT({
872
+ sub: "1'; DROP TABLE users; SELECT '1",
873
+ exp: Math.floor(Date.now() / 1000) + 3600,
874
+ })
875
+
876
+ const res = await app.request('/api/protected', {
877
+ headers: { Authorization: `Bearer ${stackedToken}` },
878
+ })
879
+
880
+ expect(res.status).toBe(401)
881
+ })
882
+
883
+ it('should block SQL injection in email claim', async () => {
884
+ // RED: Injection via email claim
885
+ const app = createTestApp({
886
+ validateToken: async (token: string) => {
887
+ const parts = token.split('.')
888
+ const payload = JSON.parse(atob(parts[1]))
889
+ return {
890
+ valid: true,
891
+ user: { id: payload.sub, email: payload.email },
892
+ }
893
+ },
894
+ })
895
+
896
+ const emailInjectionToken = createTestJWT({
897
+ sub: 'user123',
898
+ email: "test@test.com'; DELETE FROM logs--",
899
+ exp: Math.floor(Date.now() / 1000) + 3600,
900
+ })
901
+
902
+ const res = await app.request('/api/protected', {
903
+ headers: { Authorization: `Bearer ${emailInjectionToken}` },
904
+ })
905
+
906
+ expect(res.status).toBe(401)
907
+ })
908
+
909
+ it.fails('should block SQL injection in custom metadata claims', async () => {
910
+ // RED: Injection via custom claims
911
+ const app = createTestApp({
912
+ validateToken: async (token: string) => {
913
+ const parts = token.split('.')
914
+ const payload = JSON.parse(atob(parts[1]))
915
+ return {
916
+ valid: true,
917
+ user: {
918
+ id: payload.sub,
919
+ email: 'test@test.com',
920
+ metadata: { tenantId: payload.tenant_id },
921
+ },
922
+ }
923
+ },
924
+ })
925
+
926
+ const metadataInjectionToken = createTestJWT({
927
+ sub: 'user123',
928
+ tenant_id: "tenant-a' OR '1'='1",
929
+ exp: Math.floor(Date.now() / 1000) + 3600,
930
+ })
931
+
932
+ const res = await app.request('/api/protected', {
933
+ headers: { Authorization: `Bearer ${metadataInjectionToken}` },
934
+ })
935
+
936
+ expect(res.status).toBe(401)
937
+ })
938
+
939
+ it('should block NoSQL injection in claims', async () => {
940
+ // RED: NoSQL/MongoDB-style injection
941
+ const app = createTestApp({
942
+ validateToken: async (token: string) => {
943
+ const parts = token.split('.')
944
+ const payload = JSON.parse(atob(parts[1]))
945
+ return { valid: true, user: { id: payload.sub, email: 'test@test.com' } }
946
+ },
947
+ })
948
+
949
+ const nosqlInjectionToken = createTestJWT({
950
+ sub: { $gt: '' }, // MongoDB injection
951
+ exp: Math.floor(Date.now() / 1000) + 3600,
952
+ })
953
+
954
+ const res = await app.request('/api/protected', {
955
+ headers: { Authorization: `Bearer ${nosqlInjectionToken}` },
956
+ })
957
+
958
+ expect(res.status).toBe(401)
959
+ })
960
+
961
+ it.fails('should block LDAP injection in claims', async () => {
962
+ // RED: LDAP injection if claims are used in LDAP queries
963
+ const app = createTestApp({
964
+ validateToken: async (token: string) => {
965
+ const parts = token.split('.')
966
+ const payload = JSON.parse(atob(parts[1]))
967
+ return { valid: true, user: { id: payload.sub, email: 'test@test.com' } }
968
+ },
969
+ })
970
+
971
+ const ldapInjectionToken = createTestJWT({
972
+ sub: '*)(uid=*))(|(uid=*',
973
+ exp: Math.floor(Date.now() / 1000) + 3600,
974
+ })
975
+
976
+ const res = await app.request('/api/protected', {
977
+ headers: { Authorization: `Bearer ${ldapInjectionToken}` },
978
+ })
979
+
980
+ expect(res.status).toBe(401)
981
+ })
982
+ })
983
+
984
+ describe('Database ID generation security', () => {
985
+ it('should sanitize all SQL metacharacters in generateDatabaseId', async () => {
986
+ // RED: generateDatabaseId may not sanitize all dangerous patterns
987
+ const dangerousInputs = [
988
+ "user'; DROP TABLE--",
989
+ 'user/**/UNION/**/SELECT',
990
+ 'user%00admin',
991
+ 'user\x00admin',
992
+ 'user\nadmin',
993
+ 'user\radmin',
994
+ "user\\'admin",
995
+ 'user\\admin',
996
+ 'user`admin`',
997
+ 'user$(whoami)',
998
+ 'user|cat /etc/passwd',
999
+ 'user&& ls',
1000
+ 'user; ls',
1001
+ ]
1002
+
1003
+ for (const input of dangerousInputs) {
1004
+ const dbId = generateDatabaseId(input)
1005
+
1006
+ // Should not contain any dangerous characters
1007
+ expect(dbId).not.toMatch(/[';"\-\-\/\*\x00\n\r\\`$|&;]/)
1008
+ // Should be alphanumeric with underscores only
1009
+ expect(dbId).toMatch(/^[a-zA-Z0-9_]+$/)
1010
+ }
1011
+ })
1012
+ })
1013
+ })
1014
+
1015
+ // =============================================================================
1016
+ // 6. CLOCK SKEW HANDLING
1017
+ // =============================================================================
1018
+
1019
+ describe('[RED] Clock Skew Handling', () => {
1020
+ describe('Clock skew edge cases', () => {
1021
+ it('should reject tokens with exp exactly at clock skew boundary', async () => {
1022
+ // RED: Boundary condition at exactly MAX_CLOCK_SKEW_SECONDS
1023
+ const MAX_CLOCK_SKEW = 60 // From auth.ts
1024
+ const now = Math.floor(Date.now() / 1000)
1025
+
1026
+ const app = createTestApp({
1027
+ validateToken: async (token: string) => {
1028
+ const parts = token.split('.')
1029
+ const payload = JSON.parse(atob(parts[1]))
1030
+ // Uses <= which allows tokens at exactly the boundary
1031
+ if (payload.exp + MAX_CLOCK_SKEW >= now) {
1032
+ return { valid: true, user: { id: payload.sub, email: 'test@test.com' } }
1033
+ }
1034
+ return { valid: false, error: 'Token expired' }
1035
+ },
1036
+ })
1037
+
1038
+ // Token expired exactly MAX_CLOCK_SKEW seconds ago (boundary)
1039
+ const boundaryToken = createTestJWT({
1040
+ sub: 'user123',
1041
+ exp: now - MAX_CLOCK_SKEW,
1042
+ })
1043
+
1044
+ const res = await app.request('/api/protected', {
1045
+ headers: { Authorization: `Bearer ${boundaryToken}` },
1046
+ })
1047
+
1048
+ // Should be rejected at exactly the boundary
1049
+ expect(res.status).toBe(401)
1050
+ })
1051
+
1052
+ it('should reject tokens with nbf exactly at clock skew boundary', async () => {
1053
+ // RED: Boundary condition for not-before claim
1054
+ const MAX_CLOCK_SKEW = 60
1055
+ const now = Math.floor(Date.now() / 1000)
1056
+
1057
+ const app = createTestApp({
1058
+ validateToken: async (token: string) => {
1059
+ const parts = token.split('.')
1060
+ const payload = JSON.parse(atob(parts[1]))
1061
+ // Uses >= which allows tokens at exactly the boundary
1062
+ if (payload.nbf - MAX_CLOCK_SKEW <= now) {
1063
+ return { valid: true, user: { id: payload.sub, email: 'test@test.com' } }
1064
+ }
1065
+ return { valid: false, error: 'Token not yet valid' }
1066
+ },
1067
+ })
1068
+
1069
+ // Token becomes valid exactly MAX_CLOCK_SKEW seconds in the future (boundary)
1070
+ const boundaryToken = createTestJWT({
1071
+ sub: 'user123',
1072
+ nbf: now + MAX_CLOCK_SKEW,
1073
+ exp: now + 3600,
1074
+ })
1075
+
1076
+ const res = await app.request('/api/protected', {
1077
+ headers: { Authorization: `Bearer ${boundaryToken}` },
1078
+ })
1079
+
1080
+ // Should be rejected at exactly the boundary
1081
+ expect(res.status).toBe(401)
1082
+ })
1083
+
1084
+ it('should handle clock skew when iat is in the future', async () => {
1085
+ // RED: iat (issued at) in the future indicates clock issues or forgery
1086
+ const now = Math.floor(Date.now() / 1000)
1087
+ const MAX_CLOCK_SKEW = 60
1088
+
1089
+ const app = createTestApp({
1090
+ validateToken: async (token: string) => {
1091
+ const parts = token.split('.')
1092
+ const payload = JSON.parse(atob(parts[1]))
1093
+
1094
+ // Check if iat is unreasonably in the future
1095
+ if (payload.iat && payload.iat > now + MAX_CLOCK_SKEW) {
1096
+ return { valid: false, error: 'Token issued in the future' }
1097
+ }
1098
+
1099
+ return { valid: true, user: { id: payload.sub, email: 'test@test.com' } }
1100
+ },
1101
+ })
1102
+
1103
+ // Token with iat 5 minutes in the future
1104
+ const futureIatToken = createTestJWT({
1105
+ sub: 'user123',
1106
+ iat: now + 300,
1107
+ exp: now + 3600,
1108
+ })
1109
+
1110
+ const res = await app.request('/api/protected', {
1111
+ headers: { Authorization: `Bearer ${futureIatToken}` },
1112
+ })
1113
+
1114
+ // Should reject - iat too far in future
1115
+ expect(res.status).toBe(401)
1116
+ })
1117
+
1118
+ it('should apply clock skew consistently across all time claims', async () => {
1119
+ // RED: Clock skew should be applied to exp, nbf, and iat consistently
1120
+ const now = Math.floor(Date.now() / 1000)
1121
+ const MAX_CLOCK_SKEW = 60
1122
+
1123
+ const app = createTestApp({
1124
+ validateToken: async (token: string) => {
1125
+ const parts = token.split('.')
1126
+ const payload = JSON.parse(atob(parts[1]))
1127
+
1128
+ // Check all time claims with consistent skew
1129
+ const effectiveNow = now
1130
+
1131
+ // exp check (with skew)
1132
+ if (payload.exp && payload.exp + MAX_CLOCK_SKEW < effectiveNow) {
1133
+ return { valid: false, error: 'Token expired' }
1134
+ }
1135
+
1136
+ // nbf check (with skew)
1137
+ if (payload.nbf && payload.nbf - MAX_CLOCK_SKEW > effectiveNow) {
1138
+ return { valid: false, error: 'Token not yet valid' }
1139
+ }
1140
+
1141
+ // iat check (with skew)
1142
+ if (payload.iat && payload.iat - MAX_CLOCK_SKEW > effectiveNow) {
1143
+ return { valid: false, error: 'Token from future' }
1144
+ }
1145
+
1146
+ return { valid: true, user: { id: payload.sub, email: 'test@test.com' } }
1147
+ },
1148
+ })
1149
+
1150
+ // Token with slightly future iat but within skew
1151
+ const slightlyFutureToken = createTestJWT({
1152
+ sub: 'user123',
1153
+ iat: now + 30, // 30 seconds in future (within 60s skew)
1154
+ nbf: now - 10,
1155
+ exp: now + 3600,
1156
+ })
1157
+
1158
+ const res = await app.request('/api/protected', {
1159
+ headers: { Authorization: `Bearer ${slightlyFutureToken}` },
1160
+ })
1161
+
1162
+ // Should accept - within clock skew tolerance
1163
+ expect(res.status).toBe(200)
1164
+ })
1165
+
1166
+ it('should not allow clock skew to extend token lifetime', async () => {
1167
+ // RED: Clock skew should not effectively extend token lifetime
1168
+ const now = Math.floor(Date.now() / 1000)
1169
+ const MAX_CLOCK_SKEW = 60
1170
+
1171
+ const app = createTestApp({
1172
+ validateToken: async (token: string) => {
1173
+ const parts = token.split('.')
1174
+ const payload = JSON.parse(atob(parts[1]))
1175
+
1176
+ // Token lifetime should be measured from iat to exp
1177
+ const lifetime = payload.exp - payload.iat
1178
+ const maxLifetime = 24 * 60 * 60 // 24 hours
1179
+
1180
+ // Bug: Attacker can set iat in the past to extend effective lifetime
1181
+ if (lifetime > maxLifetime) {
1182
+ return { valid: false, error: 'Token lifetime too long' }
1183
+ }
1184
+
1185
+ return { valid: true, user: { id: payload.sub, email: 'test@test.com' } }
1186
+ },
1187
+ })
1188
+
1189
+ // Attacker sets iat far in past to get longer effective lifetime
1190
+ const extendedToken = createTestJWT({
1191
+ sub: 'user123',
1192
+ iat: now - 365 * 24 * 60 * 60, // 1 year ago
1193
+ exp: now + 3600,
1194
+ })
1195
+
1196
+ const res = await app.request('/api/protected', {
1197
+ headers: { Authorization: `Bearer ${extendedToken}` },
1198
+ })
1199
+
1200
+ // Should reject - effective lifetime exceeds maximum
1201
+ expect(res.status).toBe(401)
1202
+ })
1203
+
1204
+ it('should validate that exp > nbf', async () => {
1205
+ // RED: Invalid token where exp is before nbf
1206
+ const now = Math.floor(Date.now() / 1000)
1207
+
1208
+ const app = createTestApp({
1209
+ validateToken: async (token: string) => {
1210
+ const parts = token.split('.')
1211
+ const payload = JSON.parse(atob(parts[1]))
1212
+
1213
+ // Bug: Doesn't check that exp > nbf
1214
+ if (payload.exp > now) {
1215
+ return { valid: true, user: { id: payload.sub, email: 'test@test.com' } }
1216
+ }
1217
+ return { valid: false, error: 'Token expired' }
1218
+ },
1219
+ })
1220
+
1221
+ // Invalid: exp before nbf
1222
+ const invalidToken = createTestJWT({
1223
+ sub: 'user123',
1224
+ nbf: now + 7200,
1225
+ exp: now + 3600, // exp before nbf
1226
+ })
1227
+
1228
+ const res = await app.request('/api/protected', {
1229
+ headers: { Authorization: `Bearer ${invalidToken}` },
1230
+ })
1231
+
1232
+ // Should reject - logically invalid time claims
1233
+ expect(res.status).toBe(401)
1234
+ })
1235
+ })
1236
+ })