@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,1864 @@
1
+ /**
2
+ * Tests for External Database Migration Tooling (RED phase)
3
+ *
4
+ * These tests define the expected behavior for migrating from
5
+ * external databases (Neon, Supabase) to PGLite.
6
+ *
7
+ * Tests cover:
8
+ * 1. Schema export from external databases
9
+ * 2. Schema transformation to PGLite-compatible format
10
+ * 3. Data migration streaming
11
+ * 4. Connection string parsing
12
+ * 5. Progress reporting
13
+ */
14
+
15
+ import { describe, it, expect, beforeEach, vi } from 'vitest'
16
+
17
+ // These imports will fail until implementation exists
18
+ import {
19
+ // Schema export
20
+ SchemaExporter,
21
+ exportSchema,
22
+ type SchemaExportOptions,
23
+ type ExportedSchema,
24
+
25
+ // Schema transformation
26
+ SchemaTransformer,
27
+ transformSchema,
28
+ createPGLiteCompatibility,
29
+ type TransformOptions,
30
+ type TransformResult,
31
+ type PGLiteCompatibility,
32
+
33
+ // Schema validation
34
+ validateSchemaCompatibility,
35
+ type SchemaValidationResult,
36
+ type SchemaValidationOptions,
37
+ type SchemaValidationIssue,
38
+
39
+ // Data migration
40
+ DataMigrator,
41
+ createDataStream,
42
+ type DataMigrationOptions,
43
+ type MigrationStream,
44
+ type BatchConfig,
45
+
46
+ // Streaming metrics
47
+ createStreamingMetricsTracker,
48
+ type StreamingMetrics,
49
+ type ThroughputMetrics,
50
+
51
+ // Connection string parsing
52
+ parseConnectionString,
53
+ buildConnectionString,
54
+ detectProvider,
55
+ type ConnectionConfig,
56
+ type DatabaseProvider,
57
+
58
+ // Progress reporting
59
+ MigrationProgressReporter,
60
+ createProgressReporter,
61
+ type ProgressEvent,
62
+ type ProgressCallback,
63
+ type MigrationPhase,
64
+
65
+ // Error handling
66
+ MigrationError,
67
+ type MigrationErrorCode,
68
+ } from './external-migration'
69
+
70
+ // =============================================================================
71
+ // 1. SCHEMA EXPORT TESTS
72
+ // =============================================================================
73
+
74
+ describe('SchemaExporter', () => {
75
+ describe('exportSchema', () => {
76
+ it('should export all tables from a database', async () => {
77
+ const options: SchemaExportOptions = {
78
+ connectionString: 'postgresql://user:pass@host:5432/db',
79
+ includeData: false,
80
+ }
81
+
82
+ const result = await exportSchema(options)
83
+
84
+ expect(result).toBeDefined()
85
+ expect(result.tables).toBeDefined()
86
+ expect(Array.isArray(result.tables)).toBe(true)
87
+ })
88
+
89
+ it('should export table with columns and constraints', async () => {
90
+ const options: SchemaExportOptions = {
91
+ connectionString: 'postgresql://user:pass@host:5432/db',
92
+ tables: ['users'],
93
+ }
94
+
95
+ const result = await exportSchema(options)
96
+
97
+ expect(result.tables).toHaveLength(1)
98
+ const usersTable = result.tables[0]
99
+ expect(usersTable.name).toBe('users')
100
+ expect(usersTable.columns).toBeDefined()
101
+ expect(usersTable.primaryKey).toBeDefined()
102
+ expect(usersTable.foreignKeys).toBeDefined()
103
+ expect(usersTable.indexes).toBeDefined()
104
+ })
105
+
106
+ it('should export views', async () => {
107
+ const options: SchemaExportOptions = {
108
+ connectionString: 'postgresql://user:pass@host:5432/db',
109
+ includeViews: true,
110
+ }
111
+
112
+ const result = await exportSchema(options)
113
+
114
+ expect(result.views).toBeDefined()
115
+ expect(Array.isArray(result.views)).toBe(true)
116
+ })
117
+
118
+ it('should export functions and triggers', async () => {
119
+ const options: SchemaExportOptions = {
120
+ connectionString: 'postgresql://user:pass@host:5432/db',
121
+ includeFunctions: true,
122
+ includeTriggers: true,
123
+ }
124
+
125
+ const result = await exportSchema(options)
126
+
127
+ expect(result.functions).toBeDefined()
128
+ expect(result.triggers).toBeDefined()
129
+ })
130
+
131
+ it('should export extensions list', async () => {
132
+ const options: SchemaExportOptions = {
133
+ connectionString: 'postgresql://user:pass@host:5432/db',
134
+ includeExtensions: true,
135
+ }
136
+
137
+ const result = await exportSchema(options)
138
+
139
+ expect(result.extensions).toBeDefined()
140
+ expect(Array.isArray(result.extensions)).toBe(true)
141
+ })
142
+
143
+ it('should filter tables by schema', async () => {
144
+ const options: SchemaExportOptions = {
145
+ connectionString: 'postgresql://user:pass@host:5432/db',
146
+ schemas: ['public', 'auth'],
147
+ }
148
+
149
+ const result = await exportSchema(options)
150
+
151
+ result.tables.forEach((table) => {
152
+ expect(['public', 'auth']).toContain(table.schema)
153
+ })
154
+ })
155
+
156
+ it('should exclude specified tables', async () => {
157
+ const options: SchemaExportOptions = {
158
+ connectionString: 'postgresql://user:pass@host:5432/db',
159
+ excludeTables: ['_migrations', 'schema_migrations'],
160
+ }
161
+
162
+ const result = await exportSchema(options)
163
+
164
+ const tableNames = result.tables.map((t) => t.name)
165
+ expect(tableNames).not.toContain('_migrations')
166
+ expect(tableNames).not.toContain('schema_migrations')
167
+ })
168
+
169
+ it('should handle connection errors gracefully', async () => {
170
+ const options: SchemaExportOptions = {
171
+ connectionString: 'postgresql://invalid:invalid@nonexistent:5432/db',
172
+ }
173
+
174
+ await expect(exportSchema(options)).rejects.toThrow(/connection|connect|ENOTFOUND/i)
175
+ })
176
+
177
+ it('should timeout on slow connections', async () => {
178
+ const options: SchemaExportOptions = {
179
+ connectionString: 'postgresql://user:pass@slow-host:5432/db',
180
+ timeout: 100, // 100ms timeout
181
+ }
182
+
183
+ await expect(exportSchema(options)).rejects.toThrow(/timeout/i)
184
+ })
185
+ })
186
+
187
+ describe('SchemaExporter class', () => {
188
+ let exporter: SchemaExporter
189
+
190
+ beforeEach(() => {
191
+ exporter = new SchemaExporter({
192
+ connectionString: 'postgresql://user:pass@host:5432/db',
193
+ })
194
+ })
195
+
196
+ it('should be instantiable with connection config', () => {
197
+ expect(exporter).toBeInstanceOf(SchemaExporter)
198
+ })
199
+
200
+ it('should connect and disconnect', async () => {
201
+ await expect(exporter.connect()).resolves.not.toThrow()
202
+ await expect(exporter.disconnect()).resolves.not.toThrow()
203
+ })
204
+
205
+ it('should list available schemas', async () => {
206
+ await exporter.connect()
207
+ const schemas = await exporter.listSchemas()
208
+
209
+ expect(Array.isArray(schemas)).toBe(true)
210
+ expect(schemas).toContain('public')
211
+ await exporter.disconnect()
212
+ })
213
+
214
+ it('should list tables in a schema', async () => {
215
+ await exporter.connect()
216
+ const tables = await exporter.listTables('public')
217
+
218
+ expect(Array.isArray(tables)).toBe(true)
219
+ await exporter.disconnect()
220
+ })
221
+
222
+ it('should get table details', async () => {
223
+ await exporter.connect()
224
+ const table = await exporter.getTableDetails('public', 'users')
225
+
226
+ expect(table.name).toBe('users')
227
+ expect(table.columns).toBeDefined()
228
+ expect(table.constraints).toBeDefined()
229
+ await exporter.disconnect()
230
+ })
231
+
232
+ it('should export to SQL DDL format', async () => {
233
+ await exporter.connect()
234
+ const ddl = await exporter.exportToSQL()
235
+
236
+ expect(typeof ddl).toBe('string')
237
+ expect(ddl).toContain('CREATE TABLE')
238
+ await exporter.disconnect()
239
+ })
240
+ })
241
+ })
242
+
243
+ // =============================================================================
244
+ // 2. SCHEMA TRANSFORMATION TESTS
245
+ // =============================================================================
246
+
247
+ describe('SchemaTransformer', () => {
248
+ describe('transformSchema', () => {
249
+ it('should transform schema to PGLite-compatible format', async () => {
250
+ const schema: ExportedSchema = {
251
+ tables: [
252
+ {
253
+ name: 'users',
254
+ schema: 'public',
255
+ columns: [
256
+ { name: 'id', type: 'serial', nullable: false },
257
+ { name: 'email', type: 'varchar(255)', nullable: false },
258
+ ],
259
+ primaryKey: { columns: ['id'] },
260
+ foreignKeys: [],
261
+ indexes: [],
262
+ },
263
+ ],
264
+ views: [],
265
+ functions: [],
266
+ triggers: [],
267
+ extensions: [],
268
+ }
269
+
270
+ const result = await transformSchema(schema)
271
+
272
+ expect(result.schema).toBeDefined()
273
+ expect(result.sql).toBeDefined()
274
+ expect(result.warnings).toBeDefined()
275
+ })
276
+
277
+ it('should convert unsupported types to compatible alternatives', async () => {
278
+ const schema: ExportedSchema = {
279
+ tables: [
280
+ {
281
+ name: 'data',
282
+ schema: 'public',
283
+ columns: [
284
+ { name: 'id', type: 'serial', nullable: false },
285
+ { name: 'location', type: 'geography(point)', nullable: true }, // PostGIS
286
+ { name: 'metadata', type: 'jsonb', nullable: true },
287
+ ],
288
+ primaryKey: { columns: ['id'] },
289
+ foreignKeys: [],
290
+ indexes: [],
291
+ },
292
+ ],
293
+ views: [],
294
+ functions: [],
295
+ triggers: [],
296
+ extensions: ['postgis'],
297
+ }
298
+
299
+ const result = await transformSchema(schema)
300
+
301
+ // geography should be converted to text or similar
302
+ const dataTable = result.schema.tables.find((t) => t.name === 'data')
303
+ const locationCol = dataTable?.columns.find((c) => c.name === 'location')
304
+ expect(locationCol?.type).not.toBe('geography(point)')
305
+ expect(result.warnings.length).toBeGreaterThan(0)
306
+ })
307
+
308
+ it('should handle partitioned tables', async () => {
309
+ const schema: ExportedSchema = {
310
+ tables: [
311
+ {
312
+ name: 'events',
313
+ schema: 'public',
314
+ columns: [
315
+ { name: 'id', type: 'serial', nullable: false },
316
+ { name: 'created_at', type: 'timestamp', nullable: false },
317
+ ],
318
+ primaryKey: { columns: ['id', 'created_at'] },
319
+ foreignKeys: [],
320
+ indexes: [],
321
+ partitioning: {
322
+ type: 'RANGE',
323
+ columns: ['created_at'],
324
+ },
325
+ },
326
+ ],
327
+ views: [],
328
+ functions: [],
329
+ triggers: [],
330
+ extensions: [],
331
+ }
332
+
333
+ const result = await transformSchema(schema)
334
+
335
+ // PGLite doesn't support partitioning - should convert to regular table
336
+ expect(result.schema.tables[0].partitioning).toBeUndefined()
337
+ expect(result.warnings).toContainEqual(
338
+ expect.objectContaining({
339
+ type: 'unsupported_feature',
340
+ feature: 'partitioning',
341
+ })
342
+ )
343
+ })
344
+
345
+ it('should warn about unsupported extensions', async () => {
346
+ const schema: ExportedSchema = {
347
+ tables: [],
348
+ views: [],
349
+ functions: [],
350
+ triggers: [],
351
+ extensions: ['postgis', 'pg_trgm', 'uuid-ossp'],
352
+ }
353
+
354
+ const result = await transformSchema(schema)
355
+
356
+ expect(result.warnings.some((w) => w.type === 'unsupported_extension')).toBe(true)
357
+ expect(result.unsupportedExtensions).toBeDefined()
358
+ })
359
+
360
+ it('should transform views to materialized table definitions', async () => {
361
+ const schema: ExportedSchema = {
362
+ tables: [],
363
+ views: [
364
+ {
365
+ name: 'active_users',
366
+ schema: 'public',
367
+ definition: 'SELECT * FROM users WHERE active = true',
368
+ },
369
+ ],
370
+ functions: [],
371
+ triggers: [],
372
+ extensions: [],
373
+ }
374
+
375
+ const options: TransformOptions = {
376
+ viewStrategy: 'materialize',
377
+ }
378
+
379
+ const result = await transformSchema(schema, options)
380
+
381
+ // View should be converted to a table
382
+ expect(result.schema.tables.some((t) => t.name === 'active_users')).toBe(true)
383
+ expect(result.warnings.some((w) => w.type === 'view_materialized')).toBe(true)
384
+ })
385
+
386
+ it('should preserve views when strategy is preserve', async () => {
387
+ const schema: ExportedSchema = {
388
+ tables: [],
389
+ views: [
390
+ {
391
+ name: 'active_users',
392
+ schema: 'public',
393
+ definition: 'SELECT * FROM users WHERE active = true',
394
+ },
395
+ ],
396
+ functions: [],
397
+ triggers: [],
398
+ extensions: [],
399
+ }
400
+
401
+ const options: TransformOptions = {
402
+ viewStrategy: 'preserve',
403
+ }
404
+
405
+ const result = await transformSchema(schema, options)
406
+
407
+ expect(result.schema.views).toHaveLength(1)
408
+ })
409
+
410
+ it('should handle circular foreign key dependencies', async () => {
411
+ const schema: ExportedSchema = {
412
+ tables: [
413
+ {
414
+ name: 'orders',
415
+ schema: 'public',
416
+ columns: [
417
+ { name: 'id', type: 'serial', nullable: false },
418
+ { name: 'customer_id', type: 'integer', nullable: false },
419
+ ],
420
+ primaryKey: { columns: ['id'] },
421
+ foreignKeys: [
422
+ { columns: ['customer_id'], references: { table: 'customers', columns: ['id'] } },
423
+ ],
424
+ indexes: [],
425
+ },
426
+ {
427
+ name: 'customers',
428
+ schema: 'public',
429
+ columns: [
430
+ { name: 'id', type: 'serial', nullable: false },
431
+ { name: 'latest_order_id', type: 'integer', nullable: true },
432
+ ],
433
+ primaryKey: { columns: ['id'] },
434
+ foreignKeys: [
435
+ { columns: ['latest_order_id'], references: { table: 'orders', columns: ['id'] } },
436
+ ],
437
+ indexes: [],
438
+ },
439
+ ],
440
+ views: [],
441
+ functions: [],
442
+ triggers: [],
443
+ extensions: [],
444
+ }
445
+
446
+ const result = await transformSchema(schema)
447
+
448
+ // Should detect and handle circular dependency
449
+ expect(result.dependencyOrder).toBeDefined()
450
+ expect(result.warnings.some((w) => w.type === 'circular_dependency')).toBe(true)
451
+ })
452
+
453
+ it('should generate valid SQL output', async () => {
454
+ const schema: ExportedSchema = {
455
+ tables: [
456
+ {
457
+ name: 'users',
458
+ schema: 'public',
459
+ columns: [
460
+ { name: 'id', type: 'serial', nullable: false },
461
+ { name: 'email', type: 'varchar(255)', nullable: false, unique: true },
462
+ { name: 'created_at', type: 'timestamp', nullable: false, default: 'now()' },
463
+ ],
464
+ primaryKey: { columns: ['id'] },
465
+ foreignKeys: [],
466
+ indexes: [{ name: 'idx_users_email', columns: ['email'], unique: true }],
467
+ },
468
+ ],
469
+ views: [],
470
+ functions: [],
471
+ triggers: [],
472
+ extensions: [],
473
+ }
474
+
475
+ const result = await transformSchema(schema)
476
+
477
+ expect(result.sql).toContain('CREATE TABLE')
478
+ expect(result.sql).toContain('users')
479
+ expect(result.sql).toContain('PRIMARY KEY')
480
+ expect(result.sql).toMatch(/CREATE\s+(UNIQUE\s+)?INDEX/)
481
+ })
482
+ })
483
+
484
+ describe('PGLiteCompatibility', () => {
485
+ it('should check type compatibility', () => {
486
+ // This test defines the expected interface for PGLiteCompatibility
487
+ // The implementation should provide these methods
488
+ const supportedTypes = ['integer', 'varchar', 'text', 'jsonb', 'boolean', 'timestamp']
489
+ const unsupportedTypes = ['geography', 'geometry', 'ltree', 'cube']
490
+ const typeAlternatives: Record<string, string> = {
491
+ geography: 'text',
492
+ geometry: 'text',
493
+ ltree: 'text',
494
+ cube: 'text[]',
495
+ }
496
+
497
+ // Use the real implementation (already imported at top of file)
498
+ const compat: PGLiteCompatibility = createPGLiteCompatibility()
499
+
500
+ // These should be supported
501
+ expect(compat.isTypeSupported('integer')).toBe(true)
502
+ expect(compat.isTypeSupported('varchar(255)')).toBe(true)
503
+ expect(compat.isTypeSupported('jsonb')).toBe(true)
504
+
505
+ // These may not be fully supported
506
+ expect(compat.isTypeSupported('geography')).toBe(false)
507
+ expect(compat.getAlternativeType('geography')).toBe('text')
508
+ })
509
+ })
510
+ })
511
+
512
+ // =============================================================================
513
+ // 3. DATA MIGRATION STREAMING TESTS
514
+ // =============================================================================
515
+
516
+ describe('DataMigrator', () => {
517
+ describe('createDataStream', () => {
518
+ it('should create a readable stream for table data', async () => {
519
+ const options: DataMigrationOptions = {
520
+ sourceConnection: 'postgresql://user:pass@source:5432/db',
521
+ table: 'users',
522
+ batchSize: 1000,
523
+ }
524
+
525
+ const stream = await createDataStream(options)
526
+
527
+ expect(stream).toBeDefined()
528
+ expect(typeof stream[Symbol.asyncIterator]).toBe('function')
529
+ })
530
+
531
+ it('should stream data in batches', async () => {
532
+ const options: DataMigrationOptions = {
533
+ sourceConnection: 'postgresql://user:pass@source:5432/db',
534
+ table: 'users',
535
+ batchSize: 100,
536
+ }
537
+
538
+ const stream = await createDataStream(options)
539
+ const batches: unknown[][] = []
540
+
541
+ for await (const batch of stream) {
542
+ batches.push(batch)
543
+ expect(batch.length).toBeLessThanOrEqual(100)
544
+ }
545
+
546
+ expect(batches.length).toBeGreaterThan(0)
547
+ })
548
+
549
+ it('should support cursor-based pagination', async () => {
550
+ const options: DataMigrationOptions = {
551
+ sourceConnection: 'postgresql://user:pass@source:5432/db',
552
+ table: 'users',
553
+ batchSize: 100,
554
+ cursorColumn: 'id',
555
+ }
556
+
557
+ const stream = await createDataStream(options)
558
+ let lastId = 0
559
+
560
+ for await (const batch of stream) {
561
+ const ids = batch.map((row: any) => row.id)
562
+ expect(Math.min(...ids)).toBeGreaterThan(lastId)
563
+ lastId = Math.max(...ids)
564
+ }
565
+ })
566
+
567
+ it('should support WHERE clause filtering', async () => {
568
+ const options: DataMigrationOptions = {
569
+ sourceConnection: 'postgresql://user:pass@source:5432/db',
570
+ table: 'users',
571
+ where: 'active = true AND created_at > $1',
572
+ whereParams: ['2024-01-01'],
573
+ }
574
+
575
+ const stream = await createDataStream(options)
576
+
577
+ for await (const batch of stream) {
578
+ for (const row of batch) {
579
+ expect(row.active).toBe(true)
580
+ }
581
+ }
582
+ })
583
+
584
+ it('should handle large blob/bytea columns', async () => {
585
+ const options: DataMigrationOptions = {
586
+ sourceConnection: 'postgresql://user:pass@source:5432/db',
587
+ table: 'files',
588
+ batchSize: 10, // Smaller batches for large data
589
+ }
590
+
591
+ const stream = await createDataStream(options)
592
+
593
+ for await (const batch of stream) {
594
+ for (const row of batch) {
595
+ if (row.content) {
596
+ expect(row.content).toBeInstanceOf(Buffer)
597
+ }
598
+ }
599
+ }
600
+ })
601
+
602
+ it('should resume from a checkpoint', async () => {
603
+ const options: DataMigrationOptions = {
604
+ sourceConnection: 'postgresql://user:pass@source:5432/db',
605
+ table: 'users',
606
+ batchSize: 100,
607
+ cursorColumn: 'id',
608
+ resumeFrom: { id: 500 }, // Resume from row 500
609
+ }
610
+
611
+ const stream = await createDataStream(options)
612
+ const firstBatch = await stream[Symbol.asyncIterator]().next()
613
+
614
+ if (!firstBatch.done) {
615
+ const ids = firstBatch.value.map((row: any) => row.id)
616
+ expect(Math.min(...ids)).toBeGreaterThan(500)
617
+ }
618
+ })
619
+ })
620
+
621
+ describe('DataMigrator class', () => {
622
+ let migrator: DataMigrator
623
+
624
+ beforeEach(() => {
625
+ migrator = new DataMigrator({
626
+ sourceConnection: 'postgresql://user:pass@source:5432/sourcedb',
627
+ targetConnection: 'pglite://local',
628
+ })
629
+ })
630
+
631
+ it('should migrate a single table', async () => {
632
+ const result = await migrator.migrateTable('users')
633
+
634
+ expect(result.table).toBe('users')
635
+ expect(result.rowsProcessed).toBeGreaterThan(0)
636
+ expect(result.success).toBe(true)
637
+ })
638
+
639
+ it('should migrate multiple tables in dependency order', async () => {
640
+ const result = await migrator.migrateTables(['orders', 'customers', 'products'])
641
+
642
+ expect(result.tablesProcessed).toHaveLength(3)
643
+ // customers should be migrated before orders due to FK
644
+ const customerIdx = result.tablesProcessed.findIndex((t) => t.table === 'customers')
645
+ const orderIdx = result.tablesProcessed.findIndex((t) => t.table === 'orders')
646
+ expect(customerIdx).toBeLessThan(orderIdx)
647
+ })
648
+
649
+ it('should support data transformation during migration', async () => {
650
+ const result = await migrator.migrateTable('users', {
651
+ transform: (row) => ({
652
+ ...row,
653
+ email: row.email.toLowerCase(),
654
+ migrated_at: new Date().toISOString(),
655
+ }),
656
+ })
657
+
658
+ expect(result.success).toBe(true)
659
+ })
660
+
661
+ it('should handle migration errors with rollback', async () => {
662
+ const result = await migrator.migrateTable('invalid_table')
663
+
664
+ expect(result.success).toBe(false)
665
+ expect(result.error).toBeDefined()
666
+ expect(result.rolledBack).toBe(true)
667
+ })
668
+
669
+ it('should support parallel table migrations', async () => {
670
+ const result = await migrator.migrateTables(['table_a', 'table_b', 'table_c'], {
671
+ parallel: true,
672
+ maxConcurrency: 2,
673
+ })
674
+
675
+ expect(result.tablesProcessed).toHaveLength(3)
676
+ expect(result.parallelExecution).toBe(true)
677
+ })
678
+
679
+ it('should validate data integrity after migration', async () => {
680
+ const result = await migrator.migrateTable('users', {
681
+ validateIntegrity: true,
682
+ })
683
+
684
+ expect(result.integrityChecks).toBeDefined()
685
+ expect(result.integrityChecks.rowCount).toBeDefined()
686
+ expect(result.integrityChecks.checksumValid).toBe(true)
687
+ })
688
+
689
+ it('should handle schema changes during migration', async () => {
690
+ // Simulate a schema where source has more columns than target
691
+ const result = await migrator.migrateTable('users', {
692
+ schemaMapping: {
693
+ ignoreColumns: ['internal_id', 'deleted_at'],
694
+ columnRenames: { user_name: 'username' },
695
+ },
696
+ })
697
+
698
+ expect(result.success).toBe(true)
699
+ expect(result.schemaWarnings).toBeDefined()
700
+ })
701
+ })
702
+
703
+ describe('BatchConfig', () => {
704
+ it('should configure optimal batch size based on table size', async () => {
705
+ const migrator = new DataMigrator({
706
+ sourceConnection: 'postgresql://user:pass@source:5432/db',
707
+ targetConnection: 'pglite://local',
708
+ })
709
+
710
+ const config = await migrator.calculateOptimalBatchConfig('large_table')
711
+
712
+ expect(config.batchSize).toBeDefined()
713
+ expect(config.batchSize).toBeGreaterThan(0)
714
+ expect(config.estimatedBatches).toBeDefined()
715
+ })
716
+ })
717
+ })
718
+
719
+ // =============================================================================
720
+ // 4. CONNECTION STRING PARSING TESTS
721
+ // =============================================================================
722
+
723
+ describe('Connection String Parsing', () => {
724
+ describe('parseConnectionString', () => {
725
+ it('should parse standard PostgreSQL connection string', () => {
726
+ const connString = 'postgresql://user:password@localhost:5432/mydb'
727
+ const config = parseConnectionString(connString)
728
+
729
+ expect(config.host).toBe('localhost')
730
+ expect(config.port).toBe(5432)
731
+ expect(config.user).toBe('user')
732
+ expect(config.password).toBe('password')
733
+ expect(config.database).toBe('mydb')
734
+ })
735
+
736
+ it('should parse postgres:// protocol', () => {
737
+ const connString = 'postgres://user:pass@host:5432/db'
738
+ const config = parseConnectionString(connString)
739
+
740
+ expect(config.host).toBe('host')
741
+ expect(config.protocol).toBe('postgres')
742
+ })
743
+
744
+ it('should parse connection string with SSL parameters', () => {
745
+ const connString = 'postgresql://user:pass@host:5432/db?sslmode=require&sslrootcert=/path/to/cert'
746
+ const config = parseConnectionString(connString)
747
+
748
+ expect(config.ssl).toBeDefined()
749
+ expect(config.ssl?.mode).toBe('require')
750
+ expect(config.ssl?.rootCert).toBe('/path/to/cert')
751
+ })
752
+
753
+ it('should handle URL-encoded passwords', () => {
754
+ const connString = 'postgresql://user:p%40ss%2Fword@host:5432/db'
755
+ const config = parseConnectionString(connString)
756
+
757
+ expect(config.password).toBe('p@ss/word')
758
+ })
759
+
760
+ it('should parse Neon connection string format', () => {
761
+ const connString =
762
+ 'postgresql://user:pass@ep-cool-name-123456.us-east-2.aws.neon.tech/neondb?sslmode=require'
763
+ const config = parseConnectionString(connString)
764
+
765
+ expect(config.host).toBe('ep-cool-name-123456.us-east-2.aws.neon.tech')
766
+ expect(config.provider).toBe('neon')
767
+ expect(config.ssl?.mode).toBe('require')
768
+ })
769
+
770
+ it('should parse Supabase connection string format', () => {
771
+ const connString =
772
+ 'postgresql://postgres:password@db.projectref.supabase.co:5432/postgres'
773
+ const config = parseConnectionString(connString)
774
+
775
+ expect(config.host).toBe('db.projectref.supabase.co')
776
+ expect(config.provider).toBe('supabase')
777
+ })
778
+
779
+ it('should parse connection string with schema option', () => {
780
+ const connString = 'postgresql://user:pass@host:5432/db?schema=custom_schema'
781
+ const config = parseConnectionString(connString)
782
+
783
+ expect(config.schema).toBe('custom_schema')
784
+ })
785
+
786
+ it('should handle connection string with options', () => {
787
+ const connString =
788
+ 'postgresql://user:pass@host:5432/db?connect_timeout=10&application_name=migrator'
789
+ const config = parseConnectionString(connString)
790
+
791
+ expect(config.options?.connect_timeout).toBe('10')
792
+ expect(config.options?.application_name).toBe('migrator')
793
+ })
794
+
795
+ it('should throw on invalid connection string', () => {
796
+ expect(() => parseConnectionString('invalid')).toThrow(/invalid/i)
797
+ expect(() => parseConnectionString('')).toThrow()
798
+ expect(() => parseConnectionString('http://not-postgres')).toThrow()
799
+ })
800
+
801
+ it('should handle connection string without port', () => {
802
+ const connString = 'postgresql://user:pass@host/db'
803
+ const config = parseConnectionString(connString)
804
+
805
+ expect(config.port).toBe(5432) // Default PostgreSQL port
806
+ })
807
+
808
+ it('should parse Unix socket connection', () => {
809
+ // Unix socket connections use a special format with empty host
810
+ const connString = 'postgresql://user:pass@localhost/db?host=/var/run/postgresql'
811
+ const config = parseConnectionString(connString)
812
+
813
+ expect(config.socketPath).toBe('/var/run/postgresql')
814
+ })
815
+ })
816
+
817
+ describe('buildConnectionString', () => {
818
+ it('should build connection string from config', () => {
819
+ const config: ConnectionConfig = {
820
+ host: 'localhost',
821
+ port: 5432,
822
+ user: 'user',
823
+ password: 'password',
824
+ database: 'mydb',
825
+ }
826
+
827
+ const connString = buildConnectionString(config)
828
+
829
+ expect(connString).toBe('postgresql://user:password@localhost:5432/mydb')
830
+ })
831
+
832
+ it('should URL-encode special characters in password', () => {
833
+ const config: ConnectionConfig = {
834
+ host: 'localhost',
835
+ port: 5432,
836
+ user: 'user',
837
+ password: 'p@ss/word',
838
+ database: 'mydb',
839
+ }
840
+
841
+ const connString = buildConnectionString(config)
842
+
843
+ expect(connString).toContain('p%40ss%2Fword')
844
+ })
845
+
846
+ it('should include SSL options', () => {
847
+ const config: ConnectionConfig = {
848
+ host: 'localhost',
849
+ port: 5432,
850
+ user: 'user',
851
+ password: 'pass',
852
+ database: 'db',
853
+ ssl: { mode: 'require' },
854
+ }
855
+
856
+ const connString = buildConnectionString(config)
857
+
858
+ expect(connString).toContain('sslmode=require')
859
+ })
860
+ })
861
+
862
+ describe('detectProvider', () => {
863
+ it('should detect Neon provider', () => {
864
+ const connString =
865
+ 'postgresql://user:pass@ep-cool-name.us-east-2.aws.neon.tech/db'
866
+ expect(detectProvider(connString)).toBe('neon')
867
+ })
868
+
869
+ it('should detect Supabase provider', () => {
870
+ const connString = 'postgresql://postgres:pass@db.xyz.supabase.co:5432/postgres'
871
+ expect(detectProvider(connString)).toBe('supabase')
872
+ })
873
+
874
+ it('should detect Railway provider', () => {
875
+ const connString =
876
+ 'postgresql://postgres:pass@containers-us-west-1.railway.app:5432/railway'
877
+ expect(detectProvider(connString)).toBe('railway')
878
+ })
879
+
880
+ it('should detect Render provider', () => {
881
+ const connString = 'postgresql://user:pass@dpg-abc.oregon-postgres.render.com/db'
882
+ expect(detectProvider(connString)).toBe('render')
883
+ })
884
+
885
+ it('should return generic for unknown providers', () => {
886
+ const connString = 'postgresql://user:pass@localhost:5432/db'
887
+ expect(detectProvider(connString)).toBe('generic')
888
+ })
889
+
890
+ it('should detect AWS RDS', () => {
891
+ const connString =
892
+ 'postgresql://user:pass@mydb.123456789012.us-east-1.rds.amazonaws.com:5432/db'
893
+ expect(detectProvider(connString)).toBe('aws-rds')
894
+ })
895
+
896
+ it('should detect Google Cloud SQL', () => {
897
+ const connString =
898
+ 'postgresql://user:pass@/db?host=/cloudsql/project:region:instance'
899
+ expect(detectProvider(connString)).toBe('gcp-cloudsql')
900
+ })
901
+ })
902
+ })
903
+
904
+ // =============================================================================
905
+ // 5. PROGRESS REPORTING TESTS
906
+ // =============================================================================
907
+
908
+ describe('MigrationProgressReporter', () => {
909
+ describe('createProgressReporter', () => {
910
+ it('should create a progress reporter instance', () => {
911
+ const reporter = createProgressReporter()
912
+
913
+ expect(reporter).toBeDefined()
914
+ expect(typeof reporter.onProgress).toBe('function')
915
+ expect(typeof reporter.report).toBe('function')
916
+ })
917
+
918
+ it('should emit progress events', async () => {
919
+ const reporter = createProgressReporter()
920
+ const events: ProgressEvent[] = []
921
+
922
+ reporter.onProgress((event) => {
923
+ events.push(event)
924
+ })
925
+
926
+ reporter.report({
927
+ phase: 'schema_export',
928
+ progress: 50,
929
+ message: 'Exporting tables...',
930
+ })
931
+
932
+ expect(events).toHaveLength(1)
933
+ expect(events[0].phase).toBe('schema_export')
934
+ expect(events[0].progress).toBe(50)
935
+ })
936
+
937
+ it('should support multiple listeners', async () => {
938
+ const reporter = createProgressReporter()
939
+ let count = 0
940
+
941
+ reporter.onProgress(() => count++)
942
+ reporter.onProgress(() => count++)
943
+
944
+ reporter.report({ phase: 'schema_export', progress: 0 })
945
+
946
+ expect(count).toBe(2)
947
+ })
948
+
949
+ it('should allow unsubscribing from events', () => {
950
+ const reporter = createProgressReporter()
951
+ const events: ProgressEvent[] = []
952
+
953
+ const unsubscribe = reporter.onProgress((event) => events.push(event))
954
+
955
+ reporter.report({ phase: 'schema_export', progress: 0 })
956
+ expect(events).toHaveLength(1)
957
+
958
+ unsubscribe()
959
+
960
+ reporter.report({ phase: 'schema_export', progress: 50 })
961
+ expect(events).toHaveLength(1) // Should not have increased
962
+ })
963
+ })
964
+
965
+ describe('Progress phases', () => {
966
+ let reporter: MigrationProgressReporter
967
+
968
+ beforeEach(() => {
969
+ reporter = createProgressReporter()
970
+ })
971
+
972
+ it('should report schema export progress', () => {
973
+ const events: ProgressEvent[] = []
974
+ reporter.onProgress((e) => events.push(e))
975
+
976
+ reporter.startPhase('schema_export')
977
+ reporter.report({ phase: 'schema_export', progress: 50, message: 'Exporting tables' })
978
+ reporter.endPhase('schema_export')
979
+
980
+ expect(events.some((e) => e.phase === 'schema_export' && e.progress === 0)).toBe(true)
981
+ expect(events.some((e) => e.phase === 'schema_export' && e.progress === 100)).toBe(true)
982
+ })
983
+
984
+ it('should report schema transformation progress', () => {
985
+ const events: ProgressEvent[] = []
986
+ reporter.onProgress((e) => events.push(e))
987
+
988
+ reporter.startPhase('schema_transform')
989
+ reporter.report({
990
+ phase: 'schema_transform',
991
+ progress: 30,
992
+ details: { currentTable: 'users' },
993
+ })
994
+ reporter.endPhase('schema_transform')
995
+
996
+ expect(events.some((e) => e.phase === 'schema_transform')).toBe(true)
997
+ })
998
+
999
+ it('should report data migration progress', () => {
1000
+ const events: ProgressEvent[] = []
1001
+ reporter.onProgress((e) => events.push(e))
1002
+
1003
+ reporter.startPhase('data_migration')
1004
+ reporter.report({
1005
+ phase: 'data_migration',
1006
+ progress: 25,
1007
+ details: {
1008
+ table: 'users',
1009
+ rowsProcessed: 2500,
1010
+ totalRows: 10000,
1011
+ bytesTransferred: 1024000,
1012
+ },
1013
+ })
1014
+
1015
+ expect(events.some((e) => e.details?.rowsProcessed === 2500)).toBe(true)
1016
+ })
1017
+
1018
+ it('should report validation progress', () => {
1019
+ const events: ProgressEvent[] = []
1020
+ reporter.onProgress((e) => events.push(e))
1021
+
1022
+ reporter.startPhase('validation')
1023
+ reporter.report({
1024
+ phase: 'validation',
1025
+ progress: 75,
1026
+ details: { checksCompleted: 3, totalChecks: 4 },
1027
+ })
1028
+
1029
+ expect(events.some((e) => e.phase === 'validation')).toBe(true)
1030
+ })
1031
+
1032
+ it('should report errors', () => {
1033
+ const events: ProgressEvent[] = []
1034
+ reporter.onProgress((e) => events.push(e))
1035
+
1036
+ reporter.reportError({
1037
+ phase: 'data_migration',
1038
+ error: new Error('Connection lost'),
1039
+ recoverable: true,
1040
+ })
1041
+
1042
+ const errorEvent = events.find((e) => e.error)
1043
+ expect(errorEvent).toBeDefined()
1044
+ expect(errorEvent?.error?.message).toBe('Connection lost')
1045
+ expect(errorEvent?.recoverable).toBe(true)
1046
+ })
1047
+
1048
+ it('should track overall progress across phases', () => {
1049
+ const events: ProgressEvent[] = []
1050
+ reporter.onProgress((e) => events.push(e))
1051
+
1052
+ reporter.startPhase('schema_export')
1053
+ reporter.endPhase('schema_export')
1054
+ reporter.startPhase('schema_transform')
1055
+ reporter.endPhase('schema_transform')
1056
+ reporter.startPhase('data_migration')
1057
+
1058
+ const lastEvent = events[events.length - 1]
1059
+ expect(lastEvent.overallProgress).toBeDefined()
1060
+ expect(lastEvent.overallProgress).toBeGreaterThan(0)
1061
+ })
1062
+ })
1063
+
1064
+ describe('MigrationProgressReporter class', () => {
1065
+ it('should support progress callbacks during migration', async () => {
1066
+ const migrator = new DataMigrator({
1067
+ sourceConnection: 'postgresql://user:pass@source:5432/db',
1068
+ targetConnection: 'pglite://local',
1069
+ })
1070
+
1071
+ const progressEvents: ProgressEvent[] = []
1072
+
1073
+ await migrator.migrateTable('users', {
1074
+ onProgress: (event) => progressEvents.push(event),
1075
+ })
1076
+
1077
+ expect(progressEvents.length).toBeGreaterThan(0)
1078
+ expect(progressEvents.some((e) => e.phase === 'data_migration')).toBe(true)
1079
+ })
1080
+
1081
+ it('should provide ETA estimation', () => {
1082
+ const reporter = createProgressReporter()
1083
+ const events: ProgressEvent[] = []
1084
+ reporter.onProgress((e) => events.push(e))
1085
+
1086
+ // Simulate progress over time
1087
+ reporter.startPhase('data_migration')
1088
+ reporter.report({
1089
+ phase: 'data_migration',
1090
+ progress: 25,
1091
+ details: { rowsProcessed: 2500, totalRows: 10000 },
1092
+ })
1093
+
1094
+ // Wait a bit and report more progress
1095
+ reporter.report({
1096
+ phase: 'data_migration',
1097
+ progress: 50,
1098
+ details: { rowsProcessed: 5000, totalRows: 10000 },
1099
+ })
1100
+
1101
+ const lastEvent = events[events.length - 1]
1102
+ expect(lastEvent.estimatedTimeRemaining).toBeDefined()
1103
+ })
1104
+
1105
+ it('should provide throughput metrics', () => {
1106
+ const reporter = createProgressReporter()
1107
+ const events: ProgressEvent[] = []
1108
+ reporter.onProgress((e) => events.push(e))
1109
+
1110
+ reporter.startPhase('data_migration')
1111
+ reporter.report({
1112
+ phase: 'data_migration',
1113
+ progress: 50,
1114
+ details: {
1115
+ rowsProcessed: 5000,
1116
+ totalRows: 10000,
1117
+ bytesTransferred: 5000000,
1118
+ elapsedMs: 5000,
1119
+ },
1120
+ })
1121
+
1122
+ const lastEvent = events[events.length - 1]
1123
+ expect(lastEvent.throughput).toBeDefined()
1124
+ expect(lastEvent.throughput?.rowsPerSecond).toBeDefined()
1125
+ expect(lastEvent.throughput?.bytesPerSecond).toBeDefined()
1126
+ })
1127
+
1128
+ it('should generate migration summary', async () => {
1129
+ const reporter = createProgressReporter()
1130
+
1131
+ reporter.startPhase('schema_export')
1132
+ reporter.endPhase('schema_export')
1133
+ reporter.startPhase('data_migration')
1134
+ reporter.endPhase('data_migration')
1135
+ reporter.startPhase('validation')
1136
+ reporter.endPhase('validation')
1137
+
1138
+ const summary = reporter.getSummary()
1139
+
1140
+ expect(summary.phases).toBeDefined()
1141
+ expect(summary.totalDuration).toBeDefined()
1142
+ expect(summary.phaseDurations).toBeDefined()
1143
+ expect(summary.success).toBe(true)
1144
+ })
1145
+ })
1146
+
1147
+ describe('ProgressEvent types', () => {
1148
+ it('should have correct structure for schema export events', () => {
1149
+ const event: ProgressEvent = {
1150
+ phase: 'schema_export',
1151
+ progress: 50,
1152
+ timestamp: Date.now(),
1153
+ message: 'Exporting tables',
1154
+ details: {
1155
+ tablesExported: 5,
1156
+ totalTables: 10,
1157
+ },
1158
+ }
1159
+
1160
+ expect(event.phase).toBe('schema_export')
1161
+ expect(event.details?.tablesExported).toBe(5)
1162
+ })
1163
+
1164
+ it('should have correct structure for data migration events', () => {
1165
+ const event: ProgressEvent = {
1166
+ phase: 'data_migration',
1167
+ progress: 75,
1168
+ timestamp: Date.now(),
1169
+ message: 'Migrating users table',
1170
+ details: {
1171
+ table: 'users',
1172
+ rowsProcessed: 7500,
1173
+ totalRows: 10000,
1174
+ bytesTransferred: 15000000,
1175
+ currentBatch: 8,
1176
+ totalBatches: 10,
1177
+ },
1178
+ }
1179
+
1180
+ expect(event.phase).toBe('data_migration')
1181
+ expect(event.details?.table).toBe('users')
1182
+ })
1183
+ })
1184
+ })
1185
+
1186
+ // =============================================================================
1187
+ // INTEGRATION TESTS
1188
+ // =============================================================================
1189
+
1190
+ describe('Migration Tooling Integration', () => {
1191
+ it('should perform full migration from Neon to PGLite', async () => {
1192
+ const sourceConnection =
1193
+ 'postgresql://user:pass@ep-cool-name.us-east-2.aws.neon.tech/neondb?sslmode=require'
1194
+
1195
+ // 1. Export schema
1196
+ const schema = await exportSchema({
1197
+ connectionString: sourceConnection,
1198
+ includeData: false,
1199
+ })
1200
+
1201
+ // 2. Transform schema
1202
+ const transformed = await transformSchema(schema)
1203
+
1204
+ // 3. Create data migrator
1205
+ const migrator = new DataMigrator({
1206
+ sourceConnection,
1207
+ targetConnection: 'pglite://local',
1208
+ })
1209
+
1210
+ // 4. Track progress
1211
+ const progressEvents: ProgressEvent[] = []
1212
+
1213
+ // 5. Migrate data
1214
+ const result = await migrator.migrateAll({
1215
+ schema: transformed.schema,
1216
+ onProgress: (event) => progressEvents.push(event),
1217
+ })
1218
+
1219
+ expect(result.success).toBe(true)
1220
+ expect(progressEvents.length).toBeGreaterThan(0)
1221
+ })
1222
+
1223
+ it('should perform full migration from Supabase to PGLite', async () => {
1224
+ const sourceConnection =
1225
+ 'postgresql://postgres:pass@db.projectref.supabase.co:5432/postgres'
1226
+
1227
+ const schema = await exportSchema({
1228
+ connectionString: sourceConnection,
1229
+ excludeTables: ['auth.users', 'storage.objects'], // Supabase internal tables
1230
+ })
1231
+
1232
+ const transformed = await transformSchema(schema, {
1233
+ viewStrategy: 'preserve',
1234
+ })
1235
+
1236
+ const migrator = new DataMigrator({
1237
+ sourceConnection,
1238
+ targetConnection: 'pglite://local',
1239
+ })
1240
+
1241
+ const result = await migrator.migrateAll({
1242
+ schema: transformed.schema,
1243
+ validateIntegrity: true,
1244
+ })
1245
+
1246
+ expect(result.success).toBe(true)
1247
+ expect(result.integrityChecks?.checksumValid).toBe(true)
1248
+ })
1249
+
1250
+ it('should handle incremental migration with checkpoints', async () => {
1251
+ const sourceConnection = 'postgresql://user:pass@host:5432/db'
1252
+
1253
+ const migrator = new DataMigrator({
1254
+ sourceConnection,
1255
+ targetConnection: 'pglite://local',
1256
+ })
1257
+
1258
+ // Start migration
1259
+ const checkpoint1 = await migrator.migrateTable('large_table', {
1260
+ batchSize: 1000,
1261
+ stopAfterBatches: 5,
1262
+ })
1263
+
1264
+ expect(checkpoint1.checkpoint).toBeDefined()
1265
+ expect(checkpoint1.completed).toBe(false)
1266
+
1267
+ // Resume from checkpoint
1268
+ const checkpoint2 = await migrator.migrateTable('large_table', {
1269
+ batchSize: 1000,
1270
+ resumeFrom: checkpoint1.checkpoint,
1271
+ })
1272
+
1273
+ expect(checkpoint2.rowsProcessed).toBeGreaterThan(checkpoint1.rowsProcessed)
1274
+ })
1275
+ })
1276
+
1277
+ // =============================================================================
1278
+ // 6. SCHEMA COMPATIBILITY VALIDATION TESTS
1279
+ // =============================================================================
1280
+
1281
+ describe('Schema Compatibility Validation', () => {
1282
+ describe('validateSchemaCompatibility', () => {
1283
+ it('should validate a compatible schema successfully', () => {
1284
+ const schema: ExportedSchema = {
1285
+ tables: [
1286
+ {
1287
+ name: 'users',
1288
+ schema: 'public',
1289
+ columns: [
1290
+ { name: 'id', type: 'serial', nullable: false },
1291
+ { name: 'email', type: 'varchar(255)', nullable: false },
1292
+ { name: 'created_at', type: 'timestamp', nullable: false },
1293
+ ],
1294
+ primaryKey: { columns: ['id'] },
1295
+ foreignKeys: [],
1296
+ indexes: [],
1297
+ },
1298
+ ],
1299
+ views: [],
1300
+ functions: [],
1301
+ triggers: [],
1302
+ extensions: ['uuid-ossp'],
1303
+ }
1304
+
1305
+ const result = validateSchemaCompatibility(schema)
1306
+
1307
+ expect(result.isCompatible).toBe(true)
1308
+ expect(result.errorCount).toBe(0)
1309
+ })
1310
+
1311
+ it('should detect unsupported types', () => {
1312
+ const schema: ExportedSchema = {
1313
+ tables: [
1314
+ {
1315
+ name: 'geo_data',
1316
+ schema: 'public',
1317
+ columns: [
1318
+ { name: 'id', type: 'serial', nullable: false },
1319
+ { name: 'location', type: 'geography', nullable: true },
1320
+ { name: 'boundary', type: 'geometry', nullable: true },
1321
+ ],
1322
+ primaryKey: { columns: ['id'] },
1323
+ foreignKeys: [],
1324
+ indexes: [],
1325
+ },
1326
+ ],
1327
+ views: [],
1328
+ functions: [],
1329
+ triggers: [],
1330
+ extensions: [],
1331
+ }
1332
+
1333
+ const result = validateSchemaCompatibility(schema)
1334
+
1335
+ expect(result.summary.unsupportedTypes).toBeGreaterThan(0)
1336
+ expect(result.issues.some(i => i.code === 'UNSUPPORTED_TYPE')).toBe(true)
1337
+ expect(result.issues.some(i => i.column === 'location')).toBe(true)
1338
+ })
1339
+
1340
+ it('should detect unsupported extensions', () => {
1341
+ const schema: ExportedSchema = {
1342
+ tables: [],
1343
+ views: [],
1344
+ functions: [],
1345
+ triggers: [],
1346
+ extensions: ['postgis', 'pg_trgm', 'vector'],
1347
+ }
1348
+
1349
+ const result = validateSchemaCompatibility(schema)
1350
+
1351
+ expect(result.summary.unsupportedExtensions).toBe(3)
1352
+ expect(result.issues.filter(i => i.code === 'UNSUPPORTED_EXTENSION')).toHaveLength(3)
1353
+ })
1354
+
1355
+ it('should detect unsupported features like partitioning', () => {
1356
+ const schema: ExportedSchema = {
1357
+ tables: [
1358
+ {
1359
+ name: 'events',
1360
+ schema: 'public',
1361
+ columns: [
1362
+ { name: 'id', type: 'serial', nullable: false },
1363
+ { name: 'created_at', type: 'timestamp', nullable: false },
1364
+ ],
1365
+ primaryKey: { columns: ['id'] },
1366
+ foreignKeys: [],
1367
+ indexes: [],
1368
+ partitioning: {
1369
+ type: 'RANGE',
1370
+ columns: ['created_at'],
1371
+ },
1372
+ },
1373
+ ],
1374
+ views: [],
1375
+ functions: [],
1376
+ triggers: [],
1377
+ extensions: [],
1378
+ }
1379
+
1380
+ const result = validateSchemaCompatibility(schema)
1381
+
1382
+ expect(result.summary.unsupportedFeatures).toBe(1)
1383
+ expect(result.issues.some(i => i.code === 'UNSUPPORTED_FEATURE')).toBe(true)
1384
+ })
1385
+
1386
+ it('should detect reserved keyword names', () => {
1387
+ const schema: ExportedSchema = {
1388
+ tables: [
1389
+ {
1390
+ name: 'order', // Reserved keyword
1391
+ schema: 'public',
1392
+ columns: [
1393
+ { name: 'id', type: 'serial', nullable: false },
1394
+ { name: 'user', type: 'integer', nullable: false }, // Reserved keyword
1395
+ ],
1396
+ primaryKey: { columns: ['id'] },
1397
+ foreignKeys: [],
1398
+ indexes: [],
1399
+ },
1400
+ ],
1401
+ views: [],
1402
+ functions: [],
1403
+ triggers: [],
1404
+ extensions: [],
1405
+ }
1406
+
1407
+ const result = validateSchemaCompatibility(schema)
1408
+
1409
+ expect(result.summary.namingIssues).toBeGreaterThan(0)
1410
+ expect(result.issues.some(i => i.code === 'RESERVED_KEYWORD_NAME')).toBe(true)
1411
+ })
1412
+
1413
+ it('should detect missing referenced tables in foreign keys', () => {
1414
+ const schema: ExportedSchema = {
1415
+ tables: [
1416
+ {
1417
+ name: 'orders',
1418
+ schema: 'public',
1419
+ columns: [
1420
+ { name: 'id', type: 'serial', nullable: false },
1421
+ { name: 'customer_id', type: 'integer', nullable: false },
1422
+ ],
1423
+ primaryKey: { columns: ['id'] },
1424
+ foreignKeys: [
1425
+ { columns: ['customer_id'], references: { table: 'customers', columns: ['id'] } },
1426
+ ],
1427
+ indexes: [],
1428
+ },
1429
+ ],
1430
+ views: [],
1431
+ functions: [],
1432
+ triggers: [],
1433
+ extensions: [],
1434
+ }
1435
+
1436
+ const result = validateSchemaCompatibility(schema)
1437
+
1438
+ expect(result.summary.constraintIssues).toBe(1)
1439
+ expect(result.issues.some(i => i.code === 'MISSING_REFERENCED_TABLE')).toBe(true)
1440
+ })
1441
+
1442
+ it('should support strict mode treating warnings as errors', () => {
1443
+ const schema: ExportedSchema = {
1444
+ tables: [
1445
+ {
1446
+ name: 'data',
1447
+ schema: 'public',
1448
+ columns: [
1449
+ { name: 'id', type: 'serial', nullable: false },
1450
+ { name: 'location', type: 'geography', nullable: true }, // Has alternative
1451
+ ],
1452
+ primaryKey: { columns: ['id'] },
1453
+ foreignKeys: [],
1454
+ indexes: [],
1455
+ },
1456
+ ],
1457
+ views: [],
1458
+ functions: [],
1459
+ triggers: [],
1460
+ extensions: [],
1461
+ }
1462
+
1463
+ const normalResult = validateSchemaCompatibility(schema)
1464
+ expect(normalResult.isCompatible).toBe(true) // Warning only, not an error
1465
+
1466
+ const strictResult = validateSchemaCompatibility(schema, { strict: true })
1467
+ expect(strictResult.isCompatible).toBe(false) // Warning becomes error in strict mode
1468
+ })
1469
+
1470
+ it('should allow skipping specific validation checks', () => {
1471
+ const schema: ExportedSchema = {
1472
+ tables: [
1473
+ {
1474
+ name: 'data',
1475
+ schema: 'public',
1476
+ columns: [
1477
+ { name: 'id', type: 'serial', nullable: false },
1478
+ { name: 'location', type: 'geography', nullable: true },
1479
+ ],
1480
+ primaryKey: { columns: ['id'] },
1481
+ foreignKeys: [],
1482
+ indexes: [],
1483
+ },
1484
+ ],
1485
+ views: [],
1486
+ functions: [],
1487
+ triggers: [],
1488
+ extensions: ['postgis'],
1489
+ }
1490
+
1491
+ const fullResult = validateSchemaCompatibility(schema)
1492
+ const skippedResult = validateSchemaCompatibility(schema, {
1493
+ skipChecks: ['types', 'extensions'],
1494
+ })
1495
+
1496
+ expect(fullResult.totalIssues).toBeGreaterThan(skippedResult.totalIssues)
1497
+ expect(skippedResult.summary.unsupportedTypes).toBe(0)
1498
+ expect(skippedResult.summary.unsupportedExtensions).toBe(0)
1499
+ })
1500
+
1501
+ it('should support custom type mappings', () => {
1502
+ const schema: ExportedSchema = {
1503
+ tables: [
1504
+ {
1505
+ name: 'data',
1506
+ schema: 'public',
1507
+ columns: [
1508
+ { name: 'id', type: 'serial', nullable: false },
1509
+ { name: 'custom_type', type: 'my_custom_type', nullable: true },
1510
+ ],
1511
+ primaryKey: { columns: ['id'] },
1512
+ foreignKeys: [],
1513
+ indexes: [],
1514
+ },
1515
+ ],
1516
+ views: [],
1517
+ functions: [],
1518
+ triggers: [],
1519
+ extensions: [],
1520
+ }
1521
+
1522
+ const withoutMapping = validateSchemaCompatibility(schema)
1523
+ const withMapping = validateSchemaCompatibility(schema, {
1524
+ customTypeMappings: { 'my_custom_type': 'text' },
1525
+ })
1526
+
1527
+ expect(withoutMapping.summary.unsupportedTypes).toBe(1)
1528
+ expect(withMapping.summary.unsupportedTypes).toBe(0)
1529
+ })
1530
+
1531
+ it('should calculate complexity score', () => {
1532
+ const simpleSchema: ExportedSchema = {
1533
+ tables: [
1534
+ {
1535
+ name: 'simple',
1536
+ schema: 'public',
1537
+ columns: [{ name: 'id', type: 'serial', nullable: false }],
1538
+ primaryKey: { columns: ['id'] },
1539
+ foreignKeys: [],
1540
+ indexes: [],
1541
+ },
1542
+ ],
1543
+ views: [],
1544
+ functions: [],
1545
+ triggers: [],
1546
+ extensions: [],
1547
+ }
1548
+
1549
+ const complexSchema: ExportedSchema = {
1550
+ tables: Array(15).fill(null).map((_, i) => ({
1551
+ name: `table_${i}`,
1552
+ schema: 'public',
1553
+ columns: [
1554
+ { name: 'id', type: 'serial', nullable: false },
1555
+ { name: 'location', type: 'geography', nullable: true },
1556
+ ],
1557
+ primaryKey: { columns: ['id'] },
1558
+ foreignKeys: [],
1559
+ indexes: [],
1560
+ })),
1561
+ views: [],
1562
+ functions: Array(10).fill(null).map((_, i) => ({
1563
+ name: `func_${i}`,
1564
+ schema: 'public',
1565
+ definition: 'SELECT 1',
1566
+ language: 'sql',
1567
+ })),
1568
+ triggers: [],
1569
+ extensions: ['postgis', 'pg_trgm'],
1570
+ }
1571
+
1572
+ const simpleResult = validateSchemaCompatibility(simpleSchema)
1573
+ const complexResult = validateSchemaCompatibility(complexSchema)
1574
+
1575
+ expect(simpleResult.complexityScore).toBeLessThan(complexResult.complexityScore)
1576
+ expect(complexResult.complexityScore).toBeGreaterThanOrEqual(1)
1577
+ expect(complexResult.complexityScore).toBeLessThanOrEqual(10)
1578
+ })
1579
+
1580
+ it('should provide suggestions for issues', () => {
1581
+ const schema: ExportedSchema = {
1582
+ tables: [
1583
+ {
1584
+ name: 'data',
1585
+ schema: 'public',
1586
+ columns: [
1587
+ { name: 'id', type: 'serial', nullable: false },
1588
+ { name: 'location', type: 'geography', nullable: true },
1589
+ ],
1590
+ primaryKey: { columns: ['id'] },
1591
+ foreignKeys: [],
1592
+ indexes: [],
1593
+ },
1594
+ ],
1595
+ views: [],
1596
+ functions: [],
1597
+ triggers: [],
1598
+ extensions: [],
1599
+ }
1600
+
1601
+ const result = validateSchemaCompatibility(schema)
1602
+ const typeIssue = result.issues.find(i => i.code === 'UNSUPPORTED_TYPE')
1603
+
1604
+ expect(typeIssue).toBeDefined()
1605
+ expect(typeIssue?.suggestion).toBeDefined()
1606
+ expect(typeIssue?.suggestion?.length).toBeGreaterThan(0)
1607
+ })
1608
+
1609
+ it('should indicate which issues are auto-fixable', () => {
1610
+ const schema: ExportedSchema = {
1611
+ tables: [
1612
+ {
1613
+ name: 'data',
1614
+ schema: 'public',
1615
+ columns: [
1616
+ { name: 'id', type: 'serial', nullable: false },
1617
+ { name: 'location', type: 'geography', nullable: true }, // Has alternative - auto-fixable
1618
+ { name: 'custom', type: 'unknown_type', nullable: true }, // No alternative - not auto-fixable
1619
+ ],
1620
+ primaryKey: { columns: ['id'] },
1621
+ foreignKeys: [],
1622
+ indexes: [],
1623
+ },
1624
+ ],
1625
+ views: [],
1626
+ functions: [],
1627
+ triggers: [],
1628
+ extensions: [],
1629
+ }
1630
+
1631
+ const result = validateSchemaCompatibility(schema)
1632
+
1633
+ const locationIssue = result.issues.find(i => i.column === 'location')
1634
+ const customIssue = result.issues.find(i => i.column === 'custom')
1635
+
1636
+ expect(locationIssue?.autoFixable).toBe(true)
1637
+ expect(customIssue?.autoFixable).toBe(false)
1638
+ })
1639
+ })
1640
+ })
1641
+
1642
+ // =============================================================================
1643
+ // 7. STREAMING METRICS TESTS
1644
+ // =============================================================================
1645
+
1646
+ describe('Streaming Metrics Tracker', () => {
1647
+ describe('createStreamingMetricsTracker', () => {
1648
+ it('should create a metrics tracker', () => {
1649
+ const tracker = createStreamingMetricsTracker()
1650
+
1651
+ expect(tracker).toBeDefined()
1652
+ expect(typeof tracker.start).toBe('function')
1653
+ expect(typeof tracker.recordBatch).toBe('function')
1654
+ expect(typeof tracker.getMetrics).toBe('function')
1655
+ expect(typeof tracker.reset).toBe('function')
1656
+ })
1657
+
1658
+ it('should track batch processing', () => {
1659
+ const tracker = createStreamingMetricsTracker()
1660
+
1661
+ tracker.start()
1662
+ tracker.recordBatch(100, 10000, 50)
1663
+ tracker.recordBatch(100, 10000, 45)
1664
+ tracker.recordBatch(100, 10000, 55)
1665
+
1666
+ const metrics = tracker.getMetrics()
1667
+
1668
+ expect(metrics.rowsProcessed).toBe(300)
1669
+ expect(metrics.bytesTransferred).toBe(30000)
1670
+ expect(metrics.batchesCompleted).toBe(3)
1671
+ expect(metrics.avgRowsPerBatch).toBe(100)
1672
+ })
1673
+
1674
+ it('should calculate throughput metrics', () => {
1675
+ const tracker = createStreamingMetricsTracker()
1676
+
1677
+ tracker.start()
1678
+ tracker.recordBatch(1000, 100000, 100)
1679
+
1680
+ const metrics = tracker.getMetrics()
1681
+
1682
+ expect(metrics.throughput).toBeDefined()
1683
+ expect(metrics.throughput.rowsPerSecond).toBeGreaterThan(0)
1684
+ expect(metrics.throughput.bytesPerSecond).toBeGreaterThan(0)
1685
+ })
1686
+
1687
+ it('should track batch timing statistics', () => {
1688
+ const tracker = createStreamingMetricsTracker()
1689
+
1690
+ tracker.start()
1691
+ tracker.recordBatch(100, 10000, 50)
1692
+ tracker.recordBatch(100, 10000, 100)
1693
+ tracker.recordBatch(100, 10000, 25)
1694
+
1695
+ const metrics = tracker.getMetrics()
1696
+
1697
+ expect(metrics.batchTimings.min).toBe(25)
1698
+ expect(metrics.batchTimings.max).toBe(100)
1699
+ expect(metrics.batchTimings.avg).toBeCloseTo(58.33, 1)
1700
+ expect(metrics.batchTimings.last).toBe(25)
1701
+ })
1702
+
1703
+ it('should track memory usage', () => {
1704
+ const tracker = createStreamingMetricsTracker()
1705
+
1706
+ tracker.start()
1707
+ tracker.recordBatch(100, 10000, 50)
1708
+
1709
+ const metrics = tracker.getMetrics()
1710
+
1711
+ expect(metrics.memoryUsage).toBeDefined()
1712
+ expect(metrics.memoryUsage.current).toBeGreaterThanOrEqual(0)
1713
+ expect(metrics.memoryUsage.peak).toBeGreaterThanOrEqual(0)
1714
+ expect(metrics.memoryUsage.available).toBeGreaterThan(0)
1715
+ })
1716
+
1717
+ it('should reset all metrics', () => {
1718
+ const tracker = createStreamingMetricsTracker()
1719
+
1720
+ tracker.start()
1721
+ tracker.recordBatch(100, 10000, 50)
1722
+ tracker.reset()
1723
+
1724
+ const metrics = tracker.getMetrics()
1725
+
1726
+ expect(metrics.rowsProcessed).toBe(0)
1727
+ expect(metrics.bytesTransferred).toBe(0)
1728
+ expect(metrics.batchesCompleted).toBe(0)
1729
+ })
1730
+
1731
+ it('should calculate elapsed time', () => {
1732
+ const tracker = createStreamingMetricsTracker()
1733
+
1734
+ tracker.start()
1735
+ tracker.recordBatch(100, 10000, 50)
1736
+
1737
+ const metrics = tracker.getMetrics()
1738
+
1739
+ expect(metrics.startTime).toBeGreaterThan(0)
1740
+ expect(metrics.lastUpdateTime).toBeGreaterThanOrEqual(metrics.startTime)
1741
+ expect(metrics.elapsedMs).toBeGreaterThanOrEqual(0)
1742
+ })
1743
+ })
1744
+ })
1745
+
1746
+ // =============================================================================
1747
+ // 8. MIGRATION ERROR TESTS
1748
+ // =============================================================================
1749
+
1750
+ describe('MigrationError', () => {
1751
+ describe('constructor', () => {
1752
+ it('should create an error with code and message', () => {
1753
+ const error = new MigrationError('CONNECTION_FAILED', 'Could not connect to database')
1754
+
1755
+ expect(error).toBeInstanceOf(Error)
1756
+ expect(error).toBeInstanceOf(MigrationError)
1757
+ expect(error.code).toBe('CONNECTION_FAILED')
1758
+ expect(error.message).toContain('Could not connect to database')
1759
+ expect(error.name).toBe('MigrationError')
1760
+ })
1761
+
1762
+ it('should include context in the error message', () => {
1763
+ const error = new MigrationError('TABLE_NOT_FOUND', 'Table does not exist', {
1764
+ context: {
1765
+ table: 'users',
1766
+ connectionString: 'postgresql://user:pass@host:5432/db',
1767
+ },
1768
+ })
1769
+
1770
+ expect(error.message).toContain('table: users')
1771
+ expect(error.message).toContain('connection:')
1772
+ expect(error.message).not.toContain('pass') // Password should be masked
1773
+ })
1774
+
1775
+ it('should have default suggestions for error codes', () => {
1776
+ const error = new MigrationError('CONNECTION_TIMEOUT', 'Connection timed out')
1777
+
1778
+ expect(error.suggestions).toBeDefined()
1779
+ expect(error.suggestions.length).toBeGreaterThan(0)
1780
+ expect(error.suggestions.some(s => s.toLowerCase().includes('timeout'))).toBe(true)
1781
+ })
1782
+
1783
+ it('should allow custom suggestions', () => {
1784
+ const error = new MigrationError('UNKNOWN_ERROR', 'Something went wrong', {
1785
+ suggestions: ['Try again later', 'Check the logs'],
1786
+ })
1787
+
1788
+ expect(error.suggestions).toEqual(['Try again later', 'Check the logs'])
1789
+ })
1790
+
1791
+ it('should track recoverability', () => {
1792
+ const recoverableError = new MigrationError('NETWORK_ERROR', 'Network issue', {
1793
+ recoverable: true,
1794
+ })
1795
+
1796
+ const unrecoverableError = new MigrationError('SCHEMA_INCOMPATIBLE', 'Schema mismatch', {
1797
+ recoverable: false,
1798
+ })
1799
+
1800
+ expect(recoverableError.recoverable).toBe(true)
1801
+ expect(unrecoverableError.recoverable).toBe(false)
1802
+ })
1803
+
1804
+ it('should preserve the original cause', () => {
1805
+ const originalError = new Error('Original error')
1806
+ const migrationError = new MigrationError('UNKNOWN_ERROR', 'Wrapped error', {
1807
+ cause: originalError,
1808
+ })
1809
+
1810
+ expect(migrationError.cause).toBe(originalError)
1811
+ })
1812
+ })
1813
+
1814
+ describe('toUserMessage', () => {
1815
+ it('should format a user-friendly message', () => {
1816
+ const error = new MigrationError('TABLE_NOT_FOUND', 'Table users not found', {
1817
+ context: { table: 'users' },
1818
+ })
1819
+
1820
+ const userMessage = error.toUserMessage()
1821
+
1822
+ expect(userMessage).toContain('Migration Error')
1823
+ expect(userMessage).toContain('TABLE_NOT_FOUND')
1824
+ expect(userMessage).toContain('Suggested actions')
1825
+ })
1826
+
1827
+ it('should number the suggestions', () => {
1828
+ const error = new MigrationError('CONNECTION_FAILED', 'Could not connect')
1829
+
1830
+ const userMessage = error.toUserMessage()
1831
+
1832
+ expect(userMessage).toMatch(/1\.\s+\w/)
1833
+ expect(userMessage).toMatch(/2\.\s+\w/)
1834
+ })
1835
+ })
1836
+
1837
+ describe('error codes', () => {
1838
+ const errorCodes: MigrationErrorCode[] = [
1839
+ 'CONNECTION_FAILED',
1840
+ 'CONNECTION_TIMEOUT',
1841
+ 'AUTHENTICATION_FAILED',
1842
+ 'DATABASE_NOT_FOUND',
1843
+ 'TABLE_NOT_FOUND',
1844
+ 'COLUMN_NOT_FOUND',
1845
+ 'SCHEMA_INCOMPATIBLE',
1846
+ 'DATA_VALIDATION_FAILED',
1847
+ 'MEMORY_LIMIT_EXCEEDED',
1848
+ 'NETWORK_ERROR',
1849
+ 'PERMISSION_DENIED',
1850
+ 'CONSTRAINT_VIOLATION',
1851
+ 'TYPE_CONVERSION_FAILED',
1852
+ 'BATCH_PROCESSING_FAILED',
1853
+ 'CHECKPOINT_INVALID',
1854
+ 'UNKNOWN_ERROR',
1855
+ ]
1856
+
1857
+ it.each(errorCodes)('should have default suggestions for %s', (code) => {
1858
+ const error = new MigrationError(code, 'Test error')
1859
+
1860
+ expect(error.suggestions).toBeDefined()
1861
+ expect(error.suggestions.length).toBeGreaterThan(0)
1862
+ })
1863
+ })
1864
+ })