@mistriwork/engine 0.0.0-stage → 1.0.0-rc.10

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 (546) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +17 -2
  3. package/dist/adapters/adapter.d.ts +693 -0
  4. package/dist/adapters/adapter.js +444 -0
  5. package/dist/adapters/cache/cacheStore.d.ts +75 -0
  6. package/dist/adapters/cache/cacheStore.js +160 -0
  7. package/dist/adapters/cache/resp.d.ts +52 -0
  8. package/dist/adapters/cache/resp.js +237 -0
  9. package/dist/adapters/commands/canonicalJson.d.ts +19 -0
  10. package/dist/adapters/commands/canonicalJson.js +154 -0
  11. package/dist/adapters/connect.d.ts +29 -0
  12. package/dist/adapters/connect.js +40 -0
  13. package/dist/adapters/connectionBudget.d.ts +101 -0
  14. package/dist/adapters/connectionBudget.js +128 -0
  15. package/dist/adapters/dbLatency.d.ts +35 -0
  16. package/dist/adapters/dbLatency.js +79 -0
  17. package/dist/adapters/epochCache.d.ts +50 -0
  18. package/dist/adapters/epochCache.js +85 -0
  19. package/dist/adapters/http/egress.d.ts +48 -0
  20. package/dist/adapters/http/egress.js +175 -0
  21. package/dist/adapters/http/httpAdapter.d.ts +71 -0
  22. package/dist/adapters/http/httpAdapter.js +512 -0
  23. package/dist/adapters/http/httpDescription.d.ts +32 -0
  24. package/dist/adapters/http/httpDescription.js +246 -0
  25. package/dist/adapters/http/openapi.d.ts +98 -0
  26. package/dist/adapters/http/openapi.js +487 -0
  27. package/dist/adapters/layoutRefusal.d.ts +24 -0
  28. package/dist/adapters/layoutRefusal.js +35 -0
  29. package/dist/adapters/net/networkPolicy.d.ts +44 -0
  30. package/dist/adapters/net/networkPolicy.js +123 -0
  31. package/dist/adapters/net/untrustedDatabase.d.ts +18 -0
  32. package/dist/adapters/net/untrustedDatabase.js +120 -0
  33. package/dist/adapters/poolAdmission.d.ts +43 -0
  34. package/dist/adapters/poolAdmission.js +184 -0
  35. package/dist/adapters/poolMetrics.d.ts +121 -0
  36. package/dist/adapters/poolMetrics.js +185 -0
  37. package/dist/adapters/postgres.d.ts +436 -0
  38. package/dist/adapters/postgres.js +1890 -0
  39. package/dist/adapters/postgresCatalog.d.ts +96 -0
  40. package/dist/adapters/postgresCatalog.js +387 -0
  41. package/dist/adapters/postgresCatalogDigest.d.ts +30 -0
  42. package/dist/adapters/postgresCatalogDigest.js +87 -0
  43. package/dist/adapters/postgresCatalogRows.d.ts +62 -0
  44. package/dist/adapters/postgresCatalogRows.js +37 -0
  45. package/dist/adapters/postgresDates.d.ts +1 -0
  46. package/dist/adapters/postgresDates.js +39 -0
  47. package/dist/adapters/postgresMaintenance.d.ts +33 -0
  48. package/dist/adapters/postgresMaintenance.js +179 -0
  49. package/dist/adapters/postgresPool.d.ts +255 -0
  50. package/dist/adapters/postgresPool.js +838 -0
  51. package/dist/adapters/postgresPooler.d.ts +28 -0
  52. package/dist/adapters/postgresPooler.js +267 -0
  53. package/dist/adapters/postgresReadCatalog.d.ts +31 -0
  54. package/dist/adapters/postgresReadCatalog.js +226 -0
  55. package/dist/adapters/postgresReadSnapshot.d.ts +46 -0
  56. package/dist/adapters/postgresReadSnapshot.js +133 -0
  57. package/dist/adapters/postgresSchemaEpoch.d.ts +24 -0
  58. package/dist/adapters/postgresSchemaEpoch.js +149 -0
  59. package/dist/adapters/postgresTransactionHandle.d.ts +173 -0
  60. package/dist/adapters/postgresTransactionHandle.js +524 -0
  61. package/dist/adapters/postgresValues.d.ts +30 -0
  62. package/dist/adapters/postgresValues.js +75 -0
  63. package/dist/adapters/replicas.d.ts +70 -0
  64. package/dist/adapters/replicas.js +208 -0
  65. package/dist/adapters/reservedSql.d.ts +38 -0
  66. package/dist/adapters/reservedSql.js +264 -0
  67. package/dist/adapters/rolePrivileges.d.ts +17 -0
  68. package/dist/adapters/rolePrivileges.js +22 -0
  69. package/dist/adapters/scoped/keyRows.d.ts +65 -0
  70. package/dist/adapters/scoped/keyRows.js +173 -0
  71. package/dist/adapters/scoped/postgresScopeCatalog.d.ts +16 -0
  72. package/dist/adapters/scoped/postgresScopeCatalog.js +117 -0
  73. package/dist/adapters/scoped/scopedCommandOperations.d.ts +5 -0
  74. package/dist/adapters/scoped/scopedCommandOperations.js +48 -0
  75. package/dist/adapters/scoped/scopedReads.d.ts +20 -0
  76. package/dist/adapters/scoped/scopedReads.js +174 -0
  77. package/dist/adapters/scoped/scopedTransaction.d.ts +89 -0
  78. package/dist/adapters/scoped/scopedTransaction.js +303 -0
  79. package/dist/adapters/scoped/sqliteScopeCatalog.d.ts +16 -0
  80. package/dist/adapters/scoped/sqliteScopeCatalog.js +241 -0
  81. package/dist/adapters/scoped/updateGuard.d.ts +3 -0
  82. package/dist/adapters/scoped/updateGuard.js +40 -0
  83. package/dist/adapters/serverSettings.d.ts +45 -0
  84. package/dist/adapters/serverSettings.js +46 -0
  85. package/dist/adapters/sqlite.d.ts +262 -0
  86. package/dist/adapters/sqlite.js +1434 -0
  87. package/dist/adapters/sqliteCostlyReads.d.ts +33 -0
  88. package/dist/adapters/sqliteCostlyReads.js +49 -0
  89. package/dist/adapters/sqliteDecimals.d.ts +22 -0
  90. package/dist/adapters/sqliteDecimals.js +57 -0
  91. package/dist/adapters/sqliteHandles.d.ts +43 -0
  92. package/dist/adapters/sqliteHandles.js +143 -0
  93. package/dist/adapters/sqliteStatementProcess.d.ts +29 -0
  94. package/dist/adapters/sqliteStatementProcess.js +131 -0
  95. package/dist/adapters/statementControl.d.ts +34 -0
  96. package/dist/adapters/statementControl.js +90 -0
  97. package/dist/adapters/storeHost.d.ts +130 -0
  98. package/dist/adapters/storeHost.js +13 -0
  99. package/dist/adapters/telemetry/drivers.d.ts +21 -0
  100. package/dist/adapters/telemetry/drivers.js +321 -0
  101. package/dist/adapters/telemetry/metrics.d.ts +63 -0
  102. package/dist/adapters/telemetry/metrics.js +122 -0
  103. package/dist/adapters/telemetry/otlp.d.ts +12 -0
  104. package/dist/adapters/telemetry/otlp.js +320 -0
  105. package/dist/adapters/telemetry/otlpEncode.d.ts +48 -0
  106. package/dist/adapters/telemetry/otlpEncode.js +366 -0
  107. package/dist/adapters/telemetry/otlpEnv.d.ts +1 -0
  108. package/dist/adapters/telemetry/otlpEnv.js +12 -0
  109. package/dist/adapters/telemetry/serverTiming.d.ts +83 -0
  110. package/dist/adapters/telemetry/serverTiming.js +503 -0
  111. package/dist/adapters/telemetry/start.d.ts +10 -0
  112. package/dist/adapters/telemetry/start.js +25 -0
  113. package/dist/adapters/telemetry/statement.d.ts +16 -0
  114. package/dist/adapters/telemetry/statement.js +134 -0
  115. package/dist/adapters/telemetry/trace.d.ts +127 -0
  116. package/dist/adapters/telemetry/trace.js +295 -0
  117. package/dist/adapters/writeAhead.d.ts +27 -0
  118. package/dist/adapters/writeAhead.js +46 -0
  119. package/dist/adapters/writeAttribution.d.ts +18 -0
  120. package/dist/adapters/writeAttribution.js +23 -0
  121. package/dist/adapters/writeCapture.d.ts +73 -0
  122. package/dist/adapters/writeCapture.js +20 -0
  123. package/dist/adapters/writeLanes.d.ts +94 -0
  124. package/dist/adapters/writeLanes.js +232 -0
  125. package/dist/engine.d.ts +15 -0
  126. package/dist/engine.js +13 -0
  127. package/dist/server/auth/credentials.d.ts +61 -0
  128. package/dist/server/auth/credentials.js +260 -0
  129. package/dist/server/cacheService.d.ts +50 -0
  130. package/dist/server/cacheService.js +110 -0
  131. package/dist/server/cli/args.d.ts +176 -0
  132. package/dist/server/cli/args.js +342 -0
  133. package/dist/server/cli/bin.d.ts +5 -0
  134. package/dist/server/cli/bin.js +66 -0
  135. package/dist/server/cli/browser.d.ts +15 -0
  136. package/dist/server/cli/browser.js +37 -0
  137. package/dist/server/cli/config.d.ts +50 -0
  138. package/dist/server/cli/config.js +206 -0
  139. package/dist/server/cli/startup.d.ts +36 -0
  140. package/dist/server/cli/startup.js +128 -0
  141. package/dist/server/cli/startupOptions.d.ts +63 -0
  142. package/dist/server/cli/startupOptions.js +143 -0
  143. package/dist/server/cli/subcommand.d.ts +28 -0
  144. package/dist/server/cli/subcommand.js +32 -0
  145. package/dist/server/cli/usage.d.ts +13 -0
  146. package/dist/server/cli/usage.js +31 -0
  147. package/dist/server/clientHttp.d.ts +184 -0
  148. package/dist/server/clientHttp.js +700 -0
  149. package/dist/server/clientSurface.d.ts +128 -0
  150. package/dist/server/clientSurface.js +182 -0
  151. package/dist/server/columnGrants.d.ts +103 -0
  152. package/dist/server/columnGrants.js +730 -0
  153. package/dist/server/compileCache.d.ts +1 -0
  154. package/dist/server/compileCache.js +30 -0
  155. package/dist/server/config/locations.d.ts +1 -0
  156. package/dist/server/config/locations.js +15 -0
  157. package/dist/server/configPaths.d.ts +7 -0
  158. package/dist/server/configPaths.js +34 -0
  159. package/dist/server/configSections.d.ts +64 -0
  160. package/dist/server/configSections.js +72 -0
  161. package/dist/server/connectionRedaction.d.ts +30 -0
  162. package/dist/server/connectionRedaction.js +77 -0
  163. package/dist/server/connections.d.ts +353 -0
  164. package/dist/server/connections.js +978 -0
  165. package/dist/server/constraints.d.ts +82 -0
  166. package/dist/server/constraints.js +169 -0
  167. package/dist/server/demo.d.ts +9 -0
  168. package/dist/server/demo.js +554 -0
  169. package/dist/server/devclient.d.ts +108 -0
  170. package/dist/server/devclient.js +361 -0
  171. package/dist/server/evidence.d.ts +55 -0
  172. package/dist/server/evidence.js +323 -0
  173. package/dist/server/hiddenColumns.d.ts +32 -0
  174. package/dist/server/hiddenColumns.js +238 -0
  175. package/dist/server/http/baselineHeaders.d.ts +24 -0
  176. package/dist/server/http/baselineHeaders.js +12 -0
  177. package/dist/server/http/captured.d.ts +35 -0
  178. package/dist/server/http/captured.js +73 -0
  179. package/dist/server/http/clock.d.ts +1 -0
  180. package/dist/server/http/clock.js +14 -0
  181. package/dist/server/http/connectionSource.d.ts +4 -0
  182. package/dist/server/http/connectionSource.js +48 -0
  183. package/dist/server/http/context.d.ts +189 -0
  184. package/dist/server/http/context.js +11 -0
  185. package/dist/server/http/crawlerText.d.ts +15 -0
  186. package/dist/server/http/crawlerText.js +32 -0
  187. package/dist/server/http/dataRoutes.d.ts +88 -0
  188. package/dist/server/http/dataRoutes.js +137 -0
  189. package/dist/server/http/door.d.ts +57 -0
  190. package/dist/server/http/door.js +39 -0
  191. package/dist/server/http/exportRoute.d.ts +15 -0
  192. package/dist/server/http/exportRoute.js +320 -0
  193. package/dist/server/http/firstPaint.d.ts +108 -0
  194. package/dist/server/http/firstPaint.js +262 -0
  195. package/dist/server/http/httpOperationRoutes.d.ts +11 -0
  196. package/dist/server/http/httpOperationRoutes.js +50 -0
  197. package/dist/server/http/pageReads.d.ts +20 -0
  198. package/dist/server/http/pageReads.js +205 -0
  199. package/dist/server/http/pageRoutes.d.ts +39 -0
  200. package/dist/server/http/pageRoutes.js +291 -0
  201. package/dist/server/http/probes.d.ts +22 -0
  202. package/dist/server/http/probes.js +27 -0
  203. package/dist/server/http/rateLimit.d.ts +131 -0
  204. package/dist/server/http/rateLimit.js +351 -0
  205. package/dist/server/http/readRoutes.d.ts +9 -0
  206. package/dist/server/http/readRoutes.js +131 -0
  207. package/dist/server/http/readRouting.d.ts +20 -0
  208. package/dist/server/http/readRouting.js +80 -0
  209. package/dist/server/http/recordCompose.d.ts +67 -0
  210. package/dist/server/http/recordCompose.js +167 -0
  211. package/dist/server/http/recordWrites.d.ts +89 -0
  212. package/dist/server/http/recordWrites.js +298 -0
  213. package/dist/server/http/refusalReport.d.ts +38 -0
  214. package/dist/server/http/refusalReport.js +63 -0
  215. package/dist/server/http/reply.d.ts +130 -0
  216. package/dist/server/http/reply.js +394 -0
  217. package/dist/server/http/requestOrigin.d.ts +11 -0
  218. package/dist/server/http/requestOrigin.js +8 -0
  219. package/dist/server/http/router.d.ts +45 -0
  220. package/dist/server/http/router.js +22 -0
  221. package/dist/server/http/serverCore.d.ts +68 -0
  222. package/dist/server/http/serverCore.js +177 -0
  223. package/dist/server/http/traceRequest.d.ts +30 -0
  224. package/dist/server/http/traceRequest.js +224 -0
  225. package/dist/server/http/trust.d.ts +261 -0
  226. package/dist/server/http/trust.js +472 -0
  227. package/dist/server/http/writeRefusal.d.ts +33 -0
  228. package/dist/server/http/writeRefusal.js +24 -0
  229. package/dist/server/httpConnection.d.ts +49 -0
  230. package/dist/server/httpConnection.js +170 -0
  231. package/dist/server/impact.d.ts +55 -0
  232. package/dist/server/impact.js +47 -0
  233. package/dist/server/journal.d.ts +134 -0
  234. package/dist/server/journal.js +398 -0
  235. package/dist/server/keysetReadHttp.d.ts +52 -0
  236. package/dist/server/keysetReadHttp.js +85 -0
  237. package/dist/server/layouts.d.ts +49 -0
  238. package/dist/server/layouts.js +192 -0
  239. package/dist/server/migrate/cli.d.ts +55 -0
  240. package/dist/server/migrate/cli.js +517 -0
  241. package/dist/server/migrate/database.d.ts +37 -0
  242. package/dist/server/migrate/database.js +247 -0
  243. package/dist/server/migrate/desired.d.ts +76 -0
  244. package/dist/server/migrate/desired.js +292 -0
  245. package/dist/server/migrate/files.d.ts +34 -0
  246. package/dist/server/migrate/files.js +141 -0
  247. package/dist/server/migrate/flyway.d.ts +7 -0
  248. package/dist/server/migrate/flyway.js +69 -0
  249. package/dist/server/migrate/history.d.ts +70 -0
  250. package/dist/server/migrate/history.js +211 -0
  251. package/dist/server/migrate/runner.d.ts +100 -0
  252. package/dist/server/migrate/runner.js +409 -0
  253. package/dist/server/migrate/snapshot.d.ts +30 -0
  254. package/dist/server/migrate/snapshot.js +239 -0
  255. package/dist/server/migrate/target.d.ts +33 -0
  256. package/dist/server/migrate/target.js +82 -0
  257. package/dist/server/openapiDraft.d.ts +25 -0
  258. package/dist/server/openapiDraft.js +171 -0
  259. package/dist/server/operations/diagnostics.d.ts +101 -0
  260. package/dist/server/operations/diagnostics.js +284 -0
  261. package/dist/server/operations/requestMetrics.d.ts +33 -0
  262. package/dist/server/operations/requestMetrics.js +94 -0
  263. package/dist/server/packageVersion.d.ts +1 -0
  264. package/dist/server/packageVersion.js +11 -0
  265. package/dist/server/poolConfig.d.ts +34 -0
  266. package/dist/server/poolConfig.js +114 -0
  267. package/dist/server/product.d.ts +20 -0
  268. package/dist/server/product.js +12 -0
  269. package/dist/server/recordHistoryOperations.d.ts +39 -0
  270. package/dist/server/recordHistoryOperations.js +43 -0
  271. package/dist/server/recordWriteOperations.d.ts +111 -0
  272. package/dist/server/recordWriteOperations.js +329 -0
  273. package/dist/server/resourceReadHttp.d.ts +81 -0
  274. package/dist/server/resourceReadHttp.js +606 -0
  275. package/dist/server/resourceReadOperations.d.ts +147 -0
  276. package/dist/server/resourceReadOperations.js +452 -0
  277. package/dist/server/scaffoldMachine.d.ts +54 -0
  278. package/dist/server/scaffoldMachine.js +184 -0
  279. package/dist/server/seed/cli.d.ts +20 -0
  280. package/dist/server/seed/cli.js +164 -0
  281. package/dist/server/seed/lexicon.d.ts +26 -0
  282. package/dist/server/seed/lexicon.js +585 -0
  283. package/dist/server/seed/seed.d.ts +70 -0
  284. package/dist/server/seed/seed.js +779 -0
  285. package/dist/server/seed/words.d.ts +21 -0
  286. package/dist/server/seed/words.js +164 -0
  287. package/dist/server/serverRequests.d.ts +6 -0
  288. package/dist/server/serverRequests.js +33 -0
  289. package/dist/server/serverTimeouts.d.ts +33 -0
  290. package/dist/server/serverTimeouts.js +32 -0
  291. package/dist/server/shapeonly.d.ts +32 -0
  292. package/dist/server/shapeonly.js +110 -0
  293. package/dist/server/startupWarnings.d.ts +32 -0
  294. package/dist/server/startupWarnings.js +92 -0
  295. package/dist/shared/addressParams.d.ts +28 -0
  296. package/dist/shared/addressParams.js +47 -0
  297. package/dist/shared/appCards.d.ts +123 -0
  298. package/dist/shared/appCards.js +385 -0
  299. package/dist/shared/appComponents.d.ts +177 -0
  300. package/dist/shared/appComponents.js +422 -0
  301. package/dist/shared/appDocuments.d.ts +43 -0
  302. package/dist/shared/appDocuments.js +131 -0
  303. package/dist/shared/appEmbeds.d.ts +21 -0
  304. package/dist/shared/appEmbeds.js +24 -0
  305. package/dist/shared/appIcons.d.ts +28 -0
  306. package/dist/shared/appIcons.js +223 -0
  307. package/dist/shared/appLinks.d.ts +17 -0
  308. package/dist/shared/appLinks.js +124 -0
  309. package/dist/shared/appListColumns.d.ts +3 -0
  310. package/dist/shared/appListColumns.js +66 -0
  311. package/dist/shared/appLocale.d.ts +36 -0
  312. package/dist/shared/appLocale.js +86 -0
  313. package/dist/shared/appMessages.d.ts +44 -0
  314. package/dist/shared/appMessages.js +78 -0
  315. package/dist/shared/appNoun.d.ts +21 -0
  316. package/dist/shared/appNoun.js +32 -0
  317. package/dist/shared/autoBucket.d.ts +98 -0
  318. package/dist/shared/autoBucket.js +305 -0
  319. package/dist/shared/autoValues.d.ts +25 -0
  320. package/dist/shared/autoValues.js +25 -0
  321. package/dist/shared/breakdown.d.ts +228 -0
  322. package/dist/shared/breakdown.js +557 -0
  323. package/dist/shared/breakdowntext.d.ts +41 -0
  324. package/dist/shared/breakdowntext.js +400 -0
  325. package/dist/shared/builtInThemes.d.ts +2 -0
  326. package/dist/shared/builtInThemes.js +771 -0
  327. package/dist/shared/chartSeparation.d.ts +11 -0
  328. package/dist/shared/chartSeparation.js +58 -0
  329. package/dist/shared/clauses.d.ts +22 -0
  330. package/dist/shared/clauses.js +97 -0
  331. package/dist/shared/columnCaption.d.ts +16 -0
  332. package/dist/shared/columnCaption.js +90 -0
  333. package/dist/shared/commandFieldPath.d.ts +2 -0
  334. package/dist/shared/commandFieldPath.js +7 -0
  335. package/dist/shared/commandWire.d.ts +26 -0
  336. package/dist/shared/commandWire.js +41 -0
  337. package/dist/shared/computed.d.ts +161 -0
  338. package/dist/shared/computed.js +378 -0
  339. package/dist/shared/computedParse.d.ts +13 -0
  340. package/dist/shared/computedParse.js +278 -0
  341. package/dist/shared/computedValue.d.ts +47 -0
  342. package/dist/shared/computedValue.js +191 -0
  343. package/dist/shared/connection.d.ts +30 -0
  344. package/dist/shared/connection.js +1 -0
  345. package/dist/shared/csv.d.ts +20 -0
  346. package/dist/shared/csv.js +63 -0
  347. package/dist/shared/dashLayout.d.ts +30 -0
  348. package/dist/shared/dashLayout.js +132 -0
  349. package/dist/shared/dashboardAsks.d.ts +93 -0
  350. package/dist/shared/dashboardAsks.js +129 -0
  351. package/dist/shared/dashboardTrend.d.ts +20 -0
  352. package/dist/shared/dashboardTrend.js +50 -0
  353. package/dist/shared/declaredReferences.d.ts +50 -0
  354. package/dist/shared/declaredReferences.js +202 -0
  355. package/dist/shared/definedFields.d.ts +63 -0
  356. package/dist/shared/definedFields.js +103 -0
  357. package/dist/shared/definedValues.d.ts +63 -0
  358. package/dist/shared/definedValues.js +184 -0
  359. package/dist/shared/displayDefaults.d.ts +135 -0
  360. package/dist/shared/displayDefaults.js +529 -0
  361. package/dist/shared/dueDate.d.ts +6 -0
  362. package/dist/shared/dueDate.js +6 -0
  363. package/dist/shared/duration.d.ts +4 -0
  364. package/dist/shared/duration.js +23 -0
  365. package/dist/shared/fileBounds.d.ts +9 -0
  366. package/dist/shared/fileBounds.js +9 -0
  367. package/dist/shared/filter.d.ts +217 -0
  368. package/dist/shared/filter.js +305 -0
  369. package/dist/shared/firstPaint.d.ts +24 -0
  370. package/dist/shared/firstPaint.js +33 -0
  371. package/dist/shared/form.d.ts +21 -0
  372. package/dist/shared/form.js +25 -0
  373. package/dist/shared/formValues.d.ts +104 -0
  374. package/dist/shared/formValues.js +352 -0
  375. package/dist/shared/funnel.d.ts +45 -0
  376. package/dist/shared/funnel.js +108 -0
  377. package/dist/shared/httpOperations.d.ts +48 -0
  378. package/dist/shared/httpOperations.js +9 -0
  379. package/dist/shared/iconGlyphs.d.ts +4 -0
  380. package/dist/shared/iconGlyphs.js +151 -0
  381. package/dist/shared/iconWeights.d.ts +3 -0
  382. package/dist/shared/iconWeights.js +162 -0
  383. package/dist/shared/imageWidths.d.ts +32 -0
  384. package/dist/shared/imageWidths.js +38 -0
  385. package/dist/shared/keysetPage.d.ts +64 -0
  386. package/dist/shared/keysetPage.js +161 -0
  387. package/dist/shared/like.d.ts +20 -0
  388. package/dist/shared/like.js +29 -0
  389. package/dist/shared/listEmpty.d.ts +12 -0
  390. package/dist/shared/listEmpty.js +36 -0
  391. package/dist/shared/listFilters.d.ts +28 -0
  392. package/dist/shared/listFilters.js +84 -0
  393. package/dist/shared/listPresentations.d.ts +199 -0
  394. package/dist/shared/listPresentations.js +7 -0
  395. package/dist/shared/listQuestion.d.ts +52 -0
  396. package/dist/shared/listQuestion.js +137 -0
  397. package/dist/shared/lookPalettes.d.ts +62 -0
  398. package/dist/shared/lookPalettes.js +306 -0
  399. package/dist/shared/maskQuoted.d.ts +24 -0
  400. package/dist/shared/maskQuoted.js +48 -0
  401. package/dist/shared/mentionLabel.d.ts +19 -0
  402. package/dist/shared/mentionLabel.js +38 -0
  403. package/dist/shared/mentionLookup.d.ts +17 -0
  404. package/dist/shared/mentionLookup.js +64 -0
  405. package/dist/shared/menuCounts.d.ts +16 -0
  406. package/dist/shared/menuCounts.js +74 -0
  407. package/dist/shared/model.d.ts +79 -0
  408. package/dist/shared/model.js +153 -0
  409. package/dist/shared/money.d.ts +44 -0
  410. package/dist/shared/money.js +81 -0
  411. package/dist/shared/moneyEntry.d.ts +7 -0
  412. package/dist/shared/moneyEntry.js +27 -0
  413. package/dist/shared/mount.d.ts +118 -0
  414. package/dist/shared/mount.js +248 -0
  415. package/dist/shared/niceTicks.d.ts +26 -0
  416. package/dist/shared/niceTicks.js +50 -0
  417. package/dist/shared/order.d.ts +59 -0
  418. package/dist/shared/order.js +133 -0
  419. package/dist/shared/page.d.ts +135 -0
  420. package/dist/shared/page.js +1187 -0
  421. package/dist/shared/pageAnatomy.d.ts +99 -0
  422. package/dist/shared/pageAnatomy.js +370 -0
  423. package/dist/shared/pageConfig.d.ts +25 -0
  424. package/dist/shared/pageConfig.js +1308 -0
  425. package/dist/shared/pageEmptyActions.d.ts +12 -0
  426. package/dist/shared/pageEmptyActions.js +20 -0
  427. package/dist/shared/pageLayouts.d.ts +72 -0
  428. package/dist/shared/pageLayouts.js +205 -0
  429. package/dist/shared/pageModel.d.ts +785 -0
  430. package/dist/shared/pageModel.js +121 -0
  431. package/dist/shared/pagePaths.d.ts +180 -0
  432. package/dist/shared/pagePaths.js +869 -0
  433. package/dist/shared/pagePlans.d.ts +52 -0
  434. package/dist/shared/pagePlans.js +108 -0
  435. package/dist/shared/pageRoutes.d.ts +9 -0
  436. package/dist/shared/pageRoutes.js +9 -0
  437. package/dist/shared/query.d.ts +166 -0
  438. package/dist/shared/query.js +1302 -0
  439. package/dist/shared/queryDates.d.ts +12 -0
  440. package/dist/shared/queryDates.js +101 -0
  441. package/dist/shared/queryOperands.d.ts +99 -0
  442. package/dist/shared/queryOperands.js +131 -0
  443. package/dist/shared/reads.d.ts +103 -0
  444. package/dist/shared/reads.js +154 -0
  445. package/dist/shared/recordLabel.d.ts +51 -0
  446. package/dist/shared/recordLabel.js +123 -0
  447. package/dist/shared/recordReadKeys.d.ts +30 -0
  448. package/dist/shared/recordReadKeys.js +51 -0
  449. package/dist/shared/recordReads.d.ts +268 -0
  450. package/dist/shared/recordReads.js +368 -0
  451. package/dist/shared/recordview.d.ts +198 -0
  452. package/dist/shared/recordview.js +356 -0
  453. package/dist/shared/referenceModel.d.ts +58 -0
  454. package/dist/shared/referenceModel.js +194 -0
  455. package/dist/shared/refusal.d.ts +64 -0
  456. package/dist/shared/refusal.js +144 -0
  457. package/dist/shared/relatedCreate.d.ts +30 -0
  458. package/dist/shared/relatedCreate.js +162 -0
  459. package/dist/shared/resourceHttp.d.ts +464 -0
  460. package/dist/shared/resourceHttp.js +1 -0
  461. package/dist/shared/richText.d.ts +85 -0
  462. package/dist/shared/richText.js +305 -0
  463. package/dist/shared/rollups.d.ts +143 -0
  464. package/dist/shared/rollups.js +64 -0
  465. package/dist/shared/rowScope.d.ts +72 -0
  466. package/dist/shared/rowScope.js +376 -0
  467. package/dist/shared/runtimeTables.d.ts +44 -0
  468. package/dist/shared/runtimeTables.js +79 -0
  469. package/dist/shared/schema.d.ts +523 -0
  470. package/dist/shared/schema.js +627 -0
  471. package/dist/shared/schematext.d.ts +38 -0
  472. package/dist/shared/schematext.js +101 -0
  473. package/dist/shared/scopeCatalog.d.ts +29 -0
  474. package/dist/shared/scopeCatalog.js +468 -0
  475. package/dist/shared/servedApp.d.ts +681 -0
  476. package/dist/shared/servedApp.js +45 -0
  477. package/dist/shared/sessionLease.d.ts +34 -0
  478. package/dist/shared/sessionLease.js +3 -0
  479. package/dist/shared/shape.d.ts +55 -0
  480. package/dist/shared/shape.js +168 -0
  481. package/dist/shared/slug.d.ts +1 -0
  482. package/dist/shared/slug.js +12 -0
  483. package/dist/shared/sortText.d.ts +14 -0
  484. package/dist/shared/sortText.js +26 -0
  485. package/dist/shared/sqlRelation.d.ts +4 -0
  486. package/dist/shared/sqlRelation.js +8 -0
  487. package/dist/shared/sqlsaved.d.ts +44 -0
  488. package/dist/shared/sqlsaved.js +63 -0
  489. package/dist/shared/stitchedPaths.d.ts +27 -0
  490. package/dist/shared/stitchedPaths.js +38 -0
  491. package/dist/shared/structuredFilter.d.ts +22 -0
  492. package/dist/shared/structuredFilter.js +1 -0
  493. package/dist/shared/subtitlePath.d.ts +20 -0
  494. package/dist/shared/subtitlePath.js +24 -0
  495. package/dist/shared/suggest.d.ts +18 -0
  496. package/dist/shared/suggest.js +59 -0
  497. package/dist/shared/tableSizing.d.ts +4 -0
  498. package/dist/shared/tableSizing.js +9 -0
  499. package/dist/shared/tagLists.d.ts +57 -0
  500. package/dist/shared/tagLists.js +34 -0
  501. package/dist/shared/textRules.d.ts +54 -0
  502. package/dist/shared/textRules.js +133 -0
  503. package/dist/shared/theme.d.ts +94 -0
  504. package/dist/shared/theme.js +800 -0
  505. package/dist/shared/themeColor.d.ts +34 -0
  506. package/dist/shared/themeColor.js +109 -0
  507. package/dist/shared/themeFaces.d.ts +30 -0
  508. package/dist/shared/themeFaces.js +42 -0
  509. package/dist/shared/themeInk.d.ts +20 -0
  510. package/dist/shared/themeInk.js +52 -0
  511. package/dist/shared/themeLooks.d.ts +9 -0
  512. package/dist/shared/themeLooks.js +572 -0
  513. package/dist/shared/themeParts.d.ts +26 -0
  514. package/dist/shared/themeParts.js +71 -0
  515. package/dist/shared/themePartsCheck.d.ts +21 -0
  516. package/dist/shared/themePartsCheck.js +91 -0
  517. package/dist/shared/themePresets.d.ts +85 -0
  518. package/dist/shared/themePresets.js +139 -0
  519. package/dist/shared/themeRecipeWords.d.ts +156 -0
  520. package/dist/shared/themeRecipeWords.js +156 -0
  521. package/dist/shared/themeRecipes.d.ts +213 -0
  522. package/dist/shared/themeRecipes.js +234 -0
  523. package/dist/shared/themeResolve.d.ts +55 -0
  524. package/dist/shared/themeResolve.js +52 -0
  525. package/dist/shared/themeTokens.d.ts +107 -0
  526. package/dist/shared/themeTokens.js +116 -0
  527. package/dist/shared/themeType.d.ts +38 -0
  528. package/dist/shared/themeType.js +205 -0
  529. package/dist/shared/unitWord.d.ts +4 -0
  530. package/dist/shared/unitWord.js +37 -0
  531. package/dist/shared/view.d.ts +195 -0
  532. package/dist/shared/view.js +987 -0
  533. package/dist/shared/viewLabels.d.ts +47 -0
  534. package/dist/shared/viewLabels.js +459 -0
  535. package/dist/shared/viewPaths.d.ts +248 -0
  536. package/dist/shared/viewPaths.js +294 -0
  537. package/dist/shared/viewtext.d.ts +57 -0
  538. package/dist/shared/viewtext.js +282 -0
  539. package/dist/shared/vocabulary.d.ts +71 -0
  540. package/dist/shared/vocabulary.js +249 -0
  541. package/dist/shared/weekStart.d.ts +7 -0
  542. package/dist/shared/weekStart.js +36 -0
  543. package/mark.svg +1 -0
  544. package/package.json +261 -4
  545. package/schema/model.d.ts +298 -0
  546. package/schema/theme.d.ts +587 -0
@@ -0,0 +1,239 @@
1
+ /**
2
+ * The schema as a flat list of what is in it — each table, column,
3
+ * constraint, index, view, trigger and enum, keyed by name, with its
4
+ * definition as the engine prints it — so two readings compare as maps.
5
+ *
6
+ * That is what drift is: the live schema against the one migrations left.
7
+ * The one they left is recorded in the database after every run (a row per
8
+ * history table in `__mistri_schema_snapshot`), because a migration's
9
+ * effect cannot be known from its text and a file beside the migrations
10
+ * would be one environment's truth checked into every environment's
11
+ * repository. `baseline` writes the first reading beside the migrations as
12
+ * well, read-only, as the record of what the database was when tablewalk
13
+ * started owning its changes.
14
+ *
15
+ * Scoped to the schemas the run is given (the App's sources, the
16
+ * connection's "schemas", --schema), never tablewalk's own reserved tables
17
+ * or sign-in schema, which tablewalk upgrades whatever a baseline says, and
18
+ * never the history table itself.
19
+ */
20
+ import { isRuntimeTable } from '../../shared/runtimeTables.js';
21
+ import { RESERVED_SCHEMAS } from '../../adapters/reservedSql.js';
22
+ import { qualified } from './history.js';
23
+ const SNAPSHOT_TABLE = '__mistri_schema_snapshot';
24
+ /* A plain name stays plain; one with a dot, a space, a capital or a quote is
25
+ quoted, so a key never reads as a different path. */
26
+ const q = (name) => (/^[a-z_][a-z0-9_$]*$/.test(name) ? name : `"${name.replace(/"/g, '""')}"`);
27
+ const squash = (sql) => (sql ?? '').replace(/\s+/g, ' ').trim();
28
+ export async function readSchema(db, scope, history) {
29
+ const skip = (table) => isRuntimeTable(table) || table === history;
30
+ if (db.dialect === 'sqlite')
31
+ return readSqlite(db, skip);
32
+ const schemas = [...new Set(scope.length ? scope : [db.home])].filter((schema) => !RESERVED_SCHEMAS.includes(schema.toLowerCase()));
33
+ return readPostgres(db, schemas, skip);
34
+ }
35
+ async function readSqlite(db, skip) {
36
+ const out = {};
37
+ const master = await db.all("SELECT type, name, tbl_name, sql FROM sqlite_master WHERE name NOT LIKE 'sqlite_%' ORDER BY name");
38
+ for (const object of master) {
39
+ if (skip(object.tbl_name))
40
+ continue;
41
+ if (object.type === 'view')
42
+ out[`view ${q(object.name)}`] = squash(object.sql);
43
+ if (object.type === 'trigger')
44
+ out[`trigger ${q(object.tbl_name)}.${q(object.name)}`] = squash(object.sql);
45
+ if (object.type === 'index' && object.sql)
46
+ out[`index ${q(object.tbl_name)}.${q(object.name)}`] = squash(object.sql);
47
+ if (object.type !== 'table')
48
+ continue;
49
+ const table = q(object.name);
50
+ out[`table ${table}`] = /\bWITHOUT\s+ROWID\s*$/i.test(squash(object.sql)) ? 'table without rowid' : 'table';
51
+ for (const column of await db.all('SELECT name, type, "notnull", dflt_value, pk, hidden FROM pragma_table_xinfo(?)', [object.name])) {
52
+ out[`column ${table}.${q(column.name)}`] = [
53
+ column.type || 'any',
54
+ column.notnull ? 'not null' : '',
55
+ column.dflt_value !== null ? `default ${column.dflt_value}` : '',
56
+ column.pk ? 'primary key' : '',
57
+ column.hidden >= 2 ? 'generated' : '',
58
+ ]
59
+ .filter(Boolean)
60
+ .join(' ');
61
+ }
62
+ const keys = new Map();
63
+ for (const fk of await db.all('SELECT id, "table", "from", "to", on_update, on_delete FROM pragma_foreign_key_list(?) ORDER BY id, seq', [object.name])) {
64
+ const key = keys.get(fk.id) ?? {
65
+ parent: fk.table,
66
+ from: [],
67
+ to: [],
68
+ rule: `on update ${fk.on_update.toLowerCase()} on delete ${fk.on_delete.toLowerCase()}`,
69
+ };
70
+ key.from.push(fk.from);
71
+ if (fk.to)
72
+ key.to.push(fk.to);
73
+ keys.set(fk.id, key);
74
+ }
75
+ for (const key of keys.values()) {
76
+ out[`foreign key ${table}(${key.from.map(q).join(', ')})`] =
77
+ `references ${q(key.parent)}${key.to.length ? `(${key.to.map(q).join(', ')})` : ''} ${key.rule}`;
78
+ }
79
+ for (const index of await db.all('SELECT name, origin FROM pragma_index_list(?)', [object.name])) {
80
+ if (index.origin !== 'u')
81
+ continue;
82
+ const columns = await db.all('SELECT name FROM pragma_index_info(?) ORDER BY seqno', [index.name]);
83
+ out[`unique ${table}(${columns.map((column) => q(column.name ?? '<expression>')).join(', ')})`] = 'unique';
84
+ }
85
+ }
86
+ return out;
87
+ }
88
+ async function readPostgres(db, schemas, skip) {
89
+ const out = {};
90
+ /* The definitions as pg_get_*def prints them, with every name qualified:
91
+ read with an empty search path, so a reading never depends on the path
92
+ the session happened to have. */
93
+ const [{ path }] = await db.all("SELECT current_setting('search_path') AS path");
94
+ await db.run("SELECT set_config('search_path', 'pg_catalog', false)");
95
+ try {
96
+ const where = 'n.nspname = ANY(?::text[])';
97
+ const name = (schema, relation) => `${q(schema)}.${q(relation)}`;
98
+ for (const row of await db.all(`SELECT n.nspname AS s, c.relname AS t, c.relkind AS k FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace
99
+ WHERE ${where} AND c.relkind IN ('r', 'p', 'f')`, [schemas])) {
100
+ if (!skip(row.t))
101
+ out[`table ${name(row.s, row.t)}`] = row.k === 'p' ? 'partitioned table' : row.k === 'f' ? 'foreign table' : 'table';
102
+ }
103
+ for (const row of await db.all(`SELECT n.nspname AS s, c.relname AS t, a.attname AS c, format_type(a.atttypid, a.atttypmod) AS ty, a.attnotnull AS nn,
104
+ pg_get_expr(d.adbin, d.adrelid) AS df, a.attidentity AS id, a.attgenerated AS gen
105
+ FROM pg_attribute a JOIN pg_class c ON c.oid = a.attrelid JOIN pg_namespace n ON n.oid = c.relnamespace
106
+ LEFT JOIN pg_attrdef d ON d.adrelid = a.attrelid AND d.adnum = a.attnum
107
+ WHERE ${where} AND c.relkind IN ('r', 'p', 'f') AND a.attnum > 0 AND NOT a.attisdropped`, [schemas])) {
108
+ if (skip(row.t))
109
+ continue;
110
+ out[`column ${name(row.s, row.t)}.${q(row.c)}`] = [
111
+ row.ty,
112
+ row.nn ? 'not null' : '',
113
+ row.gen === 's' ? `generated always as ${row.df}` : row.df !== null ? `default ${row.df}` : '',
114
+ row.id === 'a' ? 'generated always as identity' : row.id === 'd' ? 'generated by default as identity' : '',
115
+ ]
116
+ .filter(Boolean)
117
+ .join(' ');
118
+ }
119
+ for (const row of await db.all(`SELECT n.nspname AS s, c.relname AS t, co.conname AS name, pg_get_constraintdef(co.oid, true) AS def
120
+ FROM pg_constraint co JOIN pg_class c ON c.oid = co.conrelid JOIN pg_namespace n ON n.oid = c.relnamespace
121
+ WHERE ${where} AND co.contype IN ('p', 'u', 'f', 'c', 'x')`, [schemas])) {
122
+ if (!skip(row.t))
123
+ out[`constraint ${name(row.s, row.t)}.${q(row.name)}`] = row.def;
124
+ }
125
+ // An index a constraint owns is said by the constraint.
126
+ for (const row of await db.all(`SELECT n.nspname AS s, t.relname AS t, i.relname AS name, pg_get_indexdef(i.oid) AS def
127
+ FROM pg_index x JOIN pg_class i ON i.oid = x.indexrelid JOIN pg_class t ON t.oid = x.indrelid JOIN pg_namespace n ON n.oid = i.relnamespace
128
+ WHERE ${where} AND NOT EXISTS (SELECT 1 FROM pg_constraint co WHERE co.conindid = x.indexrelid AND co.contype IN ('p', 'u', 'x'))`, [schemas])) {
129
+ if (!skip(row.t))
130
+ out[`index ${name(row.s, row.t)}.${q(row.name)}`] = row.def;
131
+ }
132
+ for (const row of await db.all(`SELECT n.nspname AS s, c.relname AS v, c.relkind AS k, pg_get_viewdef(c.oid, true) AS def
133
+ FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE ${where} AND c.relkind IN ('v', 'm')`, [schemas])) {
134
+ if (!skip(row.v))
135
+ out[`${row.k === 'm' ? 'materialized view' : 'view'} ${name(row.s, row.v)}`] = squash(row.def);
136
+ }
137
+ for (const row of await db.all(`SELECT n.nspname AS s, c.relname AS t, tg.tgname AS name, pg_get_triggerdef(tg.oid, true) AS def
138
+ FROM pg_trigger tg JOIN pg_class c ON c.oid = tg.tgrelid JOIN pg_namespace n ON n.oid = c.relnamespace
139
+ WHERE ${where} AND NOT tg.tgisinternal`, [schemas])) {
140
+ if (!skip(row.t))
141
+ out[`trigger ${name(row.s, row.t)}.${q(row.name)}`] = row.def;
142
+ }
143
+ for (const row of await db.all(`SELECT n.nspname AS s, t.typname AS t, string_agg(quote_literal(e.enumlabel), ', ' ORDER BY e.enumsortorder) AS labels
144
+ FROM pg_type t JOIN pg_enum e ON e.enumtypid = t.oid JOIN pg_namespace n ON n.oid = t.typnamespace
145
+ WHERE ${where} GROUP BY n.nspname, t.typname`, [schemas])) {
146
+ out[`enum ${name(row.s, row.t)}`] = `(${row.labels})`;
147
+ }
148
+ }
149
+ finally {
150
+ await db.run("SELECT set_config('search_path', ?, false)", [path]);
151
+ }
152
+ return out;
153
+ }
154
+ /** What differs between the schema migrations left and the one there now. A new or dropped table is one line, not one per column. */
155
+ export function drift(expected, live) {
156
+ const changes = [];
157
+ for (const key of [...new Set([...Object.keys(expected), ...Object.keys(live)])].sort()) {
158
+ if (expected[key] !== live[key])
159
+ changes.push({
160
+ key,
161
+ ...(expected[key] !== undefined ? { was: expected[key] } : {}),
162
+ ...(live[key] !== undefined ? { now: live[key] } : {}),
163
+ });
164
+ }
165
+ const whole = new Set(changes
166
+ .filter((change) => change.key.startsWith('table ') && (change.was === undefined || change.now === undefined))
167
+ .map((change) => change.key.slice(6)));
168
+ return changes.filter((change) => {
169
+ const owner = /^(?:column|constraint|index|trigger) (.+)\.[^.]+$/.exec(change.key)?.[1] ??
170
+ /^(?:foreign key|unique) ([^(]+)\(/.exec(change.key)?.[1];
171
+ return !(owner !== undefined && whole.has(owner) && !change.key.startsWith('table '));
172
+ });
173
+ }
174
+ export function sayChange(change) {
175
+ if (change.was === undefined)
176
+ return `+ ${change.key} ${change.now} (added outside migrations)`;
177
+ if (change.now === undefined)
178
+ return `- ${change.key} (dropped outside migrations)`;
179
+ return `~ ${change.key} ${change.was} → ${change.now} (changed outside migrations)`;
180
+ }
181
+ /**
182
+ * The schema to record after a run: what the database is now, except where
183
+ * it had drifted before the run and the run left that alone — that stays
184
+ * drift, so a run never quietly blesses a column someone added by hand. A
185
+ * migration that changed the drifted object (putting it back, or altering
186
+ * it) settles it, and so does one that names it: adopting a hand-made column
187
+ * is `ADD COLUMN IF NOT EXISTS note`, which changes nothing here and makes
188
+ * the column everywhere else. `applied` is the text of the files the run
189
+ * applied.
190
+ */
191
+ export function carryForward(expected, before, after, applied = []) {
192
+ const next = { ...after };
193
+ const texts = applied.map((text) => text.toLowerCase());
194
+ for (const key of new Set([...Object.keys(expected), ...Object.keys(before)])) {
195
+ if (expected[key] === before[key] || after[key] !== before[key])
196
+ continue;
197
+ if (named(key, texts))
198
+ continue;
199
+ if (expected[key] === undefined)
200
+ delete next[key];
201
+ else
202
+ next[key] = expected[key];
203
+ }
204
+ return next;
205
+ }
206
+ /* Whether a migration's text names the object a key is about: its own name,
207
+ and for a column or a key its table's too. Words, not SQL: a name inside a
208
+ comment counts, which errs toward settling what a person wrote about. */
209
+ function named(key, texts) {
210
+ const kind = /^(foreign key|unique|materialized view|[a-z]+) /.exec(key)?.[1] ?? '';
211
+ const idents = [...key.slice(kind.length + 1).matchAll(/"((?:[^"]|"")*)"|([^."(),\s]+)/g)].map((match) => (match[1] ?? match[2]).replace(/""/g, '"').toLowerCase());
212
+ const wanted = kind === 'column' ? idents.slice(-2) : kind === 'foreign key' || kind === 'unique' ? idents : idents.slice(-1);
213
+ const word = (name) => new RegExp(`(^|[^a-z0-9_$])${name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}($|[^a-z0-9_$])`);
214
+ return texts.some((text) => wanted.every((name) => word(name).test(text)));
215
+ }
216
+ export async function readSnapshot(db, history) {
217
+ const exists = db.dialect === 'sqlite'
218
+ ? await db.all("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?", [SNAPSHOT_TABLE])
219
+ : db.dialect === 'postgres'
220
+ ? await db.all('SELECT 1 FROM pg_catalog.pg_tables WHERE schemaname = ? AND tablename = ?', [db.home, SNAPSHOT_TABLE])
221
+ : [];
222
+ if (!exists.length)
223
+ return undefined;
224
+ const [row] = await db.all(`SELECT installed_rank, taken_on, objects FROM ${qualified(db, SNAPSHOT_TABLE)} WHERE history_table = ?`, [history]);
225
+ return row ? { rank: Number(row.installed_rank), takenOn: row.taken_on, objects: JSON.parse(row.objects) } : undefined;
226
+ }
227
+ export async function writeSnapshot(db, history, rank, objects) {
228
+ const table = qualified(db, SNAPSHOT_TABLE);
229
+ await db.run(`CREATE TABLE IF NOT EXISTS ${table} (history_table TEXT NOT NULL PRIMARY KEY, installed_rank INT NOT NULL, taken_on VARCHAR(32) NOT NULL, objects TEXT NOT NULL)`);
230
+ // One statement, so two runs finishing together cannot both find the row gone and both insert it.
231
+ const upsert = 'ON CONFLICT (history_table) DO UPDATE SET installed_rank = excluded.installed_rank, taken_on = excluded.taken_on, objects = excluded.objects';
232
+ await db.run(`INSERT INTO ${table} (history_table, installed_rank, taken_on, objects) VALUES (?, ?, ?, ?) ${upsert}`, [
233
+ history,
234
+ rank,
235
+ new Date().toISOString().replace('T', ' ').slice(0, 19),
236
+ JSON.stringify(sorted(objects)),
237
+ ]);
238
+ }
239
+ export const sorted = (objects) => Object.fromEntries(Object.entries(objects).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)));
@@ -0,0 +1,33 @@
1
+ import type { ConnectionConfig, Registry } from '../connections.js';
2
+ import type { StartupConfig } from '../cli/config.js';
3
+ import type { MigrateTarget } from './runner.js';
4
+ interface TargetFlags {
5
+ readonly connection?: string;
6
+ /** The id of the connection the command line named (`<db>`, --db, DATABASE_URL): it wins over a config's. */
7
+ readonly argument?: string;
8
+ readonly migrations?: string;
9
+ readonly table?: string;
10
+ /** --schema, as parsed: wins over what the App and the connection say. */
11
+ readonly schemas: readonly string[];
12
+ }
13
+ /**
14
+ * What an App says about the database a run is about, without the engine reading the App: the connection it binds
15
+ * (its own, or its home source's) and the schemas its sources keep, home source first. The App framework derives it
16
+ * from a loaded App (cli/appTargets.ts); a run with no App has none.
17
+ */
18
+ export interface TargetBinding {
19
+ readonly connection?: string;
20
+ readonly schemas?: ReadonlyArray<Readonly<{
21
+ connection: string;
22
+ schema: string;
23
+ }>>;
24
+ }
25
+ interface ResolvedTarget extends MigrateTarget {
26
+ readonly connection: ConnectionConfig;
27
+ }
28
+ /** The connection the run is about: named, the App's home source's, or the only one. `tablewalk seed` reads it the same way. */
29
+ export declare function targetConnection(registry: Registry, flags: Pick<TargetFlags, 'connection' | 'argument'>, binding?: TargetBinding, purpose?: string): ConnectionConfig;
30
+ /** The directory alone, for `migrate new`, which writes a file and opens no database. */
31
+ export declare function targetDir(registry: Registry, config: StartupConfig, flags: TargetFlags, appDir?: string, binding?: TargetBinding): string;
32
+ export declare function resolveTarget(registry: Registry, config: StartupConfig, flags: TargetFlags, appDir?: string, binding?: TargetBinding): Promise<ResolvedTarget>;
33
+ export {};
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Which database a migration run is about, and which of its schemas, which
3
+ * directory and which history table: read the way a start reads a
4
+ * connection, so `tablewalk migrate` and `mistri check --pending` agree
5
+ * with the server about what "the App's database" is.
6
+ *
7
+ * The directory defaults to `migrations/` inside the App's directory. It is
8
+ * the one place the App's other derived facts already live (its generated
9
+ * `mistri-schema.d.ts`, its `authority.lock`), it travels with the App in
10
+ * version control, and a change to it is reviewed beside the App code that
11
+ * needs it. A connection that says otherwise (`"migrations": { "dir": … }`
12
+ * in tablewalk.json, relative to that file) wins, which is how several Apps
13
+ * over one database share its migrations, and `--migrations` wins over both.
14
+ */
15
+ import { dirname, resolve } from 'node:path';
16
+ import { resolveConnection } from '../auth/credentials.js';
17
+ import { DEFAULT_HISTORY_TABLE } from './history.js';
18
+ import { configFileName } from '../product.js';
19
+ /** The connection the run is about: named, the App's home source's, or the only one. `tablewalk seed` reads it the same way. */
20
+ export function targetConnection(registry, flags, binding, purpose = 'migrate') {
21
+ const find = (name) => registry.configs().find((config) => config.id === name || config.name === name);
22
+ const bound = flags.connection ?? binding?.connection;
23
+ if (bound !== undefined) {
24
+ const found = find(bound);
25
+ if (!found)
26
+ throw new Error(`there is no connection "${bound}". Known: ${registry
27
+ .configs()
28
+ .map((config) => config.name)
29
+ .join(', ') || 'none'}.`);
30
+ return found;
31
+ }
32
+ if (flags.argument)
33
+ return registry.configOf(flags.argument);
34
+ const configs = registry.configs();
35
+ if (configs.length === 1)
36
+ return configs[0];
37
+ if (configs.length > 1)
38
+ throw new Error(`several connections are configured (${configs.map((config) => config.name).join(', ')}): name one with --connection.`);
39
+ throw new Error(`no database to ${purpose}. Name it — a SQLite file, --db <url>, or --config <file> — or keep a ${configFileName()} beside where you run it.`);
40
+ }
41
+ function directoryOf(connection, config, flags, appDir) {
42
+ const base = config.configPath ? dirname(config.configPath) : process.cwd();
43
+ return flags.migrations !== undefined
44
+ ? resolve(flags.migrations)
45
+ : connection?.migrations
46
+ ? resolve(base, connection.migrations.dir)
47
+ : appDir !== undefined
48
+ ? resolve(appDir, 'migrations')
49
+ : resolve('migrations');
50
+ }
51
+ /** The directory alone, for `migrate new`, which writes a file and opens no database. */
52
+ export function targetDir(registry, config, flags, appDir, binding) {
53
+ let connection;
54
+ try {
55
+ connection = targetConnection(registry, flags, binding);
56
+ }
57
+ catch {
58
+ connection = undefined;
59
+ }
60
+ return directoryOf(connection, config, flags, appDir);
61
+ }
62
+ export async function resolveTarget(registry, config, flags, appDir, binding) {
63
+ const connection = targetConnection(registry, flags, binding);
64
+ if (connection.http)
65
+ throw new Error(`"${connection.name}" is an HTTP API, which has no schema of its own to migrate.`);
66
+ const { url } = await resolveConnection(connection.name, connection.url, { secrets: true });
67
+ /* The App's schemas on this connection, home source first: an App that
68
+ keeps a source per schema owns those and nothing else of a shared
69
+ database. */
70
+ const appSchemas = (binding?.schemas ?? [])
71
+ .filter((source) => {
72
+ const bound = registry.configs().find((config) => config.id === source.connection || config.name === source.connection);
73
+ return bound?.id === connection.id;
74
+ })
75
+ .map((source) => source.schema);
76
+ const schemas = [...new Set(flags.schemas.length ? flags.schemas : appSchemas.length ? appSchemas : (connection.schemas ?? []))];
77
+ const dir = directoryOf(connection, config, flags, appDir);
78
+ const table = flags.table ?? connection.migrations?.table ?? DEFAULT_HISTORY_TABLE;
79
+ if (!/^[A-Za-z_][A-Za-z0-9_$]{0,62}$/.test(table))
80
+ throw new Error(`"${table}" is not a table name the history can have: letters, digits and _, at most 63.`);
81
+ return { url, schemas, dir, table, connection };
82
+ }
@@ -0,0 +1,25 @@
1
+ import type { HttpConnectionConfig } from './httpConnection.js';
2
+ interface Writer {
3
+ write(text: string): unknown;
4
+ }
5
+ /** `--from-openapi`: drafts and prints; answers the exit code, 0 with at least one resource, 1 otherwise. */
6
+ export declare function draftFromOpenapi(source: string, out?: Writer, err?: Writer): Promise<number>;
7
+ interface OpenapiBootOptions {
8
+ /** The API's base URL, when the spec's `servers` does not give a usable one. */
9
+ apiUrl?: string;
10
+ /** The environment variable holding a bearer token; only its name is kept. */
11
+ tokenEnv?: string;
12
+ }
13
+ /**
14
+ * `--openapi`: a connection straight from a spec. The description is drafted
15
+ * in memory (and said on stderr, as `--from-openapi` says it), the base URL is
16
+ * `--api-url` or the spec's server, and the token is a `${VAR}` reference,
17
+ * expanded when the connection opens, as a config's is. Throws with a reason
18
+ * a person can act on.
19
+ */
20
+ export declare function openapiConnection(source: string, options: OpenapiBootOptions, err?: Writer): Promise<{
21
+ name: string;
22
+ url: string;
23
+ http: HttpConnectionConfig;
24
+ }>;
25
+ export {};
@@ -0,0 +1,171 @@
1
+ /**
2
+ * An API's OpenAPI spec, turned into what tablewalk reads.
3
+ *
4
+ * `--from-openapi` drafts the description and prints it: the description goes
5
+ * to stdout and nothing else does, so redirecting it is the whole workflow
6
+ * (`--from-openapi crm.json > crm.http.json`). `--openapi` drafts the same
7
+ * description in memory and serves the API as a connection straight away, with
8
+ * no config file and no description on disk. Either way, what was guessed and
9
+ * what was skipped goes to stderr, where a person reads it before trusting the
10
+ * result — a draft to confirm, as `--scaffold-app` is.
11
+ */
12
+ import { createHash } from 'node:crypto';
13
+ import { readFile } from 'node:fs/promises';
14
+ import { basename } from 'node:path';
15
+ import { isIP } from 'node:net';
16
+ import { DEFAULT_POLICY, HttpSourceError, send } from '../adapters/http/egress.js';
17
+ import { OpenApiError, readOpenApi } from '../adapters/http/openapi.js';
18
+ import { draftDescription } from '../adapters/http/httpDescription.js';
19
+ import { product } from './product.js';
20
+ /* Specs run to megabytes (a large public API's is several), well past what one
21
+ API answer may be, so a spec fetch gets a cap of its own. */
22
+ const SPEC_MAX_BYTES = 25 * 1024 * 1024;
23
+ const isLoopback = (host) => {
24
+ const bare = host.replace(/^\[|\]$/g, '');
25
+ return bare === 'localhost' || (isIP(bare) === 4 && bare.startsWith('127.')) || bare === '::1';
26
+ };
27
+ /**
28
+ * Read a spec from a file or an http(s) URL. A URL is fetched through egress,
29
+ * under the rules every API request follows, with no credential: a spec that
30
+ * needs one is downloaded first and named as a file. Throws with a reason.
31
+ */
32
+ async function loadSpec(source) {
33
+ if (!source)
34
+ throw new Error('needs a spec: a JSON file or an https URL (OpenAPI 3.0 or 3.1).');
35
+ if (/^https?:\/\//i.test(source)) {
36
+ let url;
37
+ try {
38
+ url = new URL(source);
39
+ }
40
+ catch {
41
+ throw new Error(`${source} is not a URL.`);
42
+ }
43
+ const policy = { ...DEFAULT_POLICY, maxBytes: SPEC_MAX_BYTES, insecure: url.protocol === 'http:' && isLoopback(url.hostname) };
44
+ let reply;
45
+ try {
46
+ reply = await send(url, { accept: 'application/json' }, policy);
47
+ }
48
+ catch (error) {
49
+ if (error instanceof HttpSourceError)
50
+ throw new Error(`${url.host}: ${error.message}`);
51
+ throw error;
52
+ }
53
+ if (reply.status < 200 || reply.status > 299)
54
+ throw new Error(`${source} answered ${reply.status}.`);
55
+ // The hash of the document as parsed: the bytes on the wire are egress's to keep.
56
+ const sha256 = createHash('sha256').update(JSON.stringify(reply.json)).digest('hex');
57
+ return { document: reply.json, name: source, sha256, url };
58
+ }
59
+ let bytes;
60
+ try {
61
+ bytes = await readFile(source);
62
+ }
63
+ catch {
64
+ throw new Error(`no spec file at ${source}`);
65
+ }
66
+ let document;
67
+ try {
68
+ document = JSON.parse(bytes.toString('utf8'));
69
+ }
70
+ catch (error) {
71
+ // YAML is the usual reason; tablewalk takes no YAML dependency for it.
72
+ throw new Error(`${source} is not JSON (${error.message}). Specs are read as JSON; convert a YAML one first.`);
73
+ }
74
+ // The hash of the exact bytes read, so a description can say which spec it came from.
75
+ return { document, name: basename(source), sha256: createHash('sha256').update(bytes).digest('hex') };
76
+ }
77
+ /* Read the spec's resources and say, on stderr, what was guessed and what was
78
+ skipped. Throws when nothing could be drafted, since a description with no
79
+ resources is not one a connection can read. */
80
+ function draft(spec, source, err) {
81
+ let catalog;
82
+ try {
83
+ catalog = readOpenApi(spec.document);
84
+ }
85
+ catch (error) {
86
+ if (!(error instanceof OpenApiError))
87
+ throw error;
88
+ throw new Error(`${source}: ${error.message}`);
89
+ }
90
+ for (const resource of catalog.resources) {
91
+ for (const guess of resource.guesses)
92
+ err.write(`guessed ${resource.name}: ${guess}\n`);
93
+ }
94
+ for (const skip of catalog.skipped)
95
+ err.write(`skipped ${skip.operation}: ${skip.reason}\n`);
96
+ if (!catalog.resources.length)
97
+ throw new Error(`No resource could be drafted from ${source}: every operation was skipped, for the reasons above.`);
98
+ return { catalog, description: draftDescription(catalog, { file: spec.name, sha256: spec.sha256 }) };
99
+ }
100
+ const drafted = (catalog) => {
101
+ const count = catalog.resources.length;
102
+ return `${count} resource${count === 1 ? '' : 's'} drafted from ${catalog.title}${catalog.version ? ` ${catalog.version}` : ''}`;
103
+ };
104
+ /** `--from-openapi`: drafts and prints; answers the exit code, 0 with at least one resource, 1 otherwise. */
105
+ export async function draftFromOpenapi(source, out = process.stdout, err = process.stderr) {
106
+ try {
107
+ const { catalog, description } = draft(await loadSpec(source), source, err);
108
+ out.write(`${JSON.stringify(description, null, 2)}\n`);
109
+ err.write(`${drafted(catalog)}. Confirm the guesses above before using it.\n`);
110
+ return 0;
111
+ }
112
+ catch (error) {
113
+ err.write(`${product()}: --from-openapi ${error.message}\n`);
114
+ return 1;
115
+ }
116
+ }
117
+ /* The base every description path resolves under: `--api-url`, else the
118
+ spec's first server, resolved against the spec's own URL when it came from
119
+ one. A server with `{variables}` is a template, not an address. */
120
+ function baseOf(spec, options) {
121
+ const servers = spec.document.servers;
122
+ const written = options.apiUrl ?? (Array.isArray(servers) && typeof servers[0]?.url === 'string' ? servers[0].url : undefined);
123
+ if (!written)
124
+ throw new Error('The spec names no server. Pass --api-url <base URL> to say where the API is.');
125
+ if (!options.apiUrl && /\{[^}]*\}/.test(written)) {
126
+ throw new Error(`The spec's server "${written}" has variables. Pass --api-url with the address filled in.`);
127
+ }
128
+ let url;
129
+ try {
130
+ url = spec.url && !options.apiUrl ? new URL(written, spec.url) : new URL(written);
131
+ }
132
+ catch {
133
+ throw new Error(`The spec's server "${written}" is not an address on its own. Pass --api-url <base URL> to say where the API is.`);
134
+ }
135
+ if (url.protocol !== 'https:' && url.protocol !== 'http:')
136
+ throw new Error(`${url.protocol}// is not an API address; use https.`);
137
+ if (url.username || url.password)
138
+ throw new Error('A credential belongs in --api-token-env, not in the URL.');
139
+ if (url.protocol === 'http:' && !isLoopback(url.hostname)) {
140
+ throw new Error(`${url.host} would be reached over plain http. From the command line that is allowed only to this machine; use https, or a config with "insecure": true.`);
141
+ }
142
+ url.search = '';
143
+ url.hash = '';
144
+ return url;
145
+ }
146
+ /**
147
+ * `--openapi`: a connection straight from a spec. The description is drafted
148
+ * in memory (and said on stderr, as `--from-openapi` says it), the base URL is
149
+ * `--api-url` or the spec's server, and the token is a `${VAR}` reference,
150
+ * expanded when the connection opens, as a config's is. Throws with a reason
151
+ * a person can act on.
152
+ */
153
+ export async function openapiConnection(source, options, err = process.stderr) {
154
+ const spec = await loadSpec(source);
155
+ const { catalog, description } = draft(spec, source, err);
156
+ const base = baseOf(spec, options);
157
+ let auth;
158
+ if (options.tokenEnv !== undefined) {
159
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(options.tokenEnv))
160
+ throw new Error(`--api-token-env takes a variable's name, not "${options.tokenEnv}".`);
161
+ if (process.env[options.tokenEnv] === undefined)
162
+ throw new Error(`${options.tokenEnv} is not set. Export it, or leave out --api-token-env.`);
163
+ auth = { bearer: `\${${options.tokenEnv}}` };
164
+ }
165
+ err.write(`${drafted(catalog)}, served from ${base.origin}${base.pathname}.\n`);
166
+ return {
167
+ name: catalog.title || basename(spec.name),
168
+ url: base.toString(),
169
+ http: { description, ...(auth ? { auth } : {}), ...(base.protocol === 'http:' ? { insecure: true } : {}) },
170
+ };
171
+ }
@@ -0,0 +1,101 @@
1
+ import type { IncomingMessage, ServerResponse } from 'node:http';
2
+ import type { Writable } from 'node:stream';
3
+ import type { ConnectionPoolStats } from '../connections.js';
4
+ import { type RequestMetricsSnapshot } from './requestMetrics.js';
5
+ /** One open database pool's meters (poolMetrics.ts), by its connection's
6
+ * position in the configuration: never a name, URL or database. */
7
+ export interface CapacityPool {
8
+ readonly position: number;
9
+ readonly dialect: string;
10
+ readonly role: string;
11
+ /** Which of the connection's replicas, from 1, for a replica's readers. */
12
+ readonly replica?: number;
13
+ readonly pooler: string;
14
+ readonly size: number;
15
+ readonly open: number | null;
16
+ readonly inUse: number;
17
+ readonly waiting: number;
18
+ readonly saturated: boolean;
19
+ readonly checkouts: number;
20
+ readonly queued: number;
21
+ readonly timedOut: number;
22
+ readonly failed: number;
23
+ readonly waitBuckets: readonly number[];
24
+ readonly holdBuckets: readonly number[];
25
+ }
26
+ /** What separates "add pods" from "raise the pool" from "the database is
27
+ * slow": the event loop's cumulative busy and idle time, and every open pool. */
28
+ export interface CapacitySnapshot {
29
+ readonly eventLoop: Readonly<{
30
+ activeMs: number;
31
+ idleMs: number;
32
+ }>;
33
+ readonly durationBoundsMs: readonly number[];
34
+ readonly pools: readonly CapacityPool[];
35
+ }
36
+ /** The registry's pools and this process's event loop, now. Cumulative
37
+ * since start: compare two snapshots for an interval, as with the HTTP metrics. */
38
+ export declare function collectCapacity(source: {
39
+ poolStats(): readonly ConnectionPoolStats[];
40
+ }): CapacitySnapshot;
41
+ export interface RequestDiagnostic {
42
+ event: 'http.request';
43
+ timestamp: string;
44
+ requestId: string;
45
+ method: string;
46
+ route: string;
47
+ status: number | null;
48
+ durationMs: number;
49
+ outcome: 'completed' | 'aborted';
50
+ droppedTotal: number;
51
+ }
52
+ export interface RequestMetricsDiagnostic extends RequestMetricsSnapshot {
53
+ readonly event: 'http.metrics';
54
+ readonly version: 1;
55
+ /** The pools and event loop at the moment the summary was taken, once a host attaches them. */
56
+ readonly capacity?: CapacitySnapshot;
57
+ readonly health: Readonly<{
58
+ droppedTotal: number;
59
+ failed: boolean;
60
+ queuedRecords: number;
61
+ writingRecord: boolean;
62
+ writingSummary: boolean;
63
+ summaryPending: boolean;
64
+ summaryDroppedTotal: number;
65
+ }>;
66
+ }
67
+ /** Local, best-effort HTTP diagnostics, separate from the business journal.
68
+ * The caller owns the stream. No request waits for it, and only one bounded
69
+ * record is handed to it at a time. A failed stream disables further output. */
70
+ export declare class RequestDiagnostics {
71
+ private readonly output;
72
+ private readonly queue;
73
+ private scheduled;
74
+ private writing;
75
+ private failed;
76
+ private dropped;
77
+ private readonly metrics;
78
+ private summaryPending;
79
+ private summaryRevision;
80
+ private summaryDropped;
81
+ private flushPromise;
82
+ private flushDone;
83
+ private capacity;
84
+ constructor(output: Writable);
85
+ get droppedTotal(): number;
86
+ /** Carry the host's capacity (its pools and event loop) in every summary
87
+ * from now on. Read when the summary is taken, never per request. */
88
+ watchCapacity(read: () => CapacitySnapshot): void;
89
+ snapshot(): RequestMetricsDiagnostic;
90
+ private get revision();
91
+ observe(req: IncomingMessage, res: ServerResponse): void;
92
+ /** A bounded shutdown opportunity, not a delivery guarantee. Does not end
93
+ * stderr (or a caller's stream), and never participates in a business write. */
94
+ flush(timeoutMs?: number): Promise<boolean>;
95
+ private enqueue;
96
+ private schedule;
97
+ private readonly fail;
98
+ private notifyIdle;
99
+ }
100
+ /** Only the exact explicit opt-in enables diagnostics. MCP never calls this. */
101
+ export declare function diagnosticsFromEnvironment(value: string | undefined, output?: Writable): RequestDiagnostics | undefined;