@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,627 @@
1
+ /**
2
+ * The schema model every adapter produces, and the whole reason this tool
3
+ * can exist for more than one database.
4
+ *
5
+ * Most database clients treat a schema as a list of tables. The interesting
6
+ * structure is the edges: which column points at which table, and — the part
7
+ * almost nothing surfaces well — which columns elsewhere point back at the row
8
+ * you are looking at. Answering that second question is what turns a database
9
+ * from a list into something you can walk.
10
+ *
11
+ * Relational databases hand you both directions for free. `information_schema`
12
+ * knows every foreign key, so the reverse map is a filter over a list you
13
+ * already have. Adapters do the dialect-specific reading; everything above
14
+ * this file works on the model below and never learns which database it is.
15
+ */
16
+ import { isLabelTemplate, LABEL_SEGMENT, parseLabelTemplate } from './recordLabel.js';
17
+ /**
18
+ * The one link a reader follows from a column that sits in several keys.
19
+ *
20
+ * Several references on one column is ordinary schema, not a mistake: a tenant
21
+ * table's ownership column carries its own single-column reference to the
22
+ * tenancy profile (the framework requires exactly that) and its part in each
23
+ * composite tenant key. So the question is never whether to accept them, only
24
+ * which one `references` says. A single-column key is the column's own target,
25
+ * so it wins. Two single-column keys disagreeing is the real contradiction:
26
+ * the column claims to be two different things, and a catalog that attests a
27
+ * write boundary refuses it. Components of composite keys that disagree name
28
+ * no single link, so the column shows none — every edge is still in
29
+ * `foreignKeys`, where the walk reads both directions anyway.
30
+ *
31
+ * Both callers read the same verdict, and they answer `conflict` differently on
32
+ * purpose. The scoped catalogs attest a write boundary, so a contradiction
33
+ * there refuses the whole catalog: a lease may not write through metadata it
34
+ * cannot vouch for. The adapters' own `describe`, which reads databases this
35
+ * tool did not design, shows the column no link and carries on — refusing
36
+ * there would blank an entire existing database in the browser over one odd
37
+ * pair of keys. Do not "fix" the second into the first.
38
+ */
39
+ export function chooseColumnReference(candidates) {
40
+ const spelling = (reference) => JSON.stringify([reference.table, reference.column]);
41
+ const own = new Map();
42
+ const parts = new Map();
43
+ for (const candidate of candidates) {
44
+ (candidate.composite ? parts : own).set(spelling(candidate.reference), candidate.reference);
45
+ }
46
+ if (own.size > 1)
47
+ return { kind: 'conflict' };
48
+ for (const reference of own.values())
49
+ return { kind: 'one', reference };
50
+ if (parts.size === 1)
51
+ for (const reference of parts.values())
52
+ return { kind: 'one', reference };
53
+ return { kind: 'none' };
54
+ }
55
+ /**
56
+ * The columns a connection's `"hidden"` keeps from everything served over it
57
+ * (server hiddenColumns.ts), on the table it cut them from. A symbol, so the
58
+ * names ride along with the served catalog on the server and are never
59
+ * written into a JSON answer: they are what lets an App's own `hidden` name a
60
+ * column the connection already hides, rather than be told it is no column.
61
+ */
62
+ export const CONNECTION_HIDDEN = Symbol('mistri.connectionHidden');
63
+ /**
64
+ * A dialect's spelling of an `ON DELETE` action, normalised.
65
+ *
66
+ * Each engine words these differently — SQLite in prose, Postgres as
67
+ * a single character — and the difference is not interesting upstream. Shared
68
+ * so the adapters cannot drift on a value the delete dialog reads
69
+ * literally.
70
+ *
71
+ * Unrecognised returns undefined rather than a default: "the adapter did not
72
+ * report it" and "the constraint says NO ACTION" lead to different advice, and
73
+ * conflating them presents an unknown as harmless.
74
+ */
75
+ export function deleteRuleOf(raw) {
76
+ switch (String(raw ?? '')
77
+ .trim()
78
+ .toUpperCase()) {
79
+ // Postgres stores confdeltype as one character.
80
+ case 'C':
81
+ case 'CASCADE':
82
+ return 'cascade';
83
+ case 'N':
84
+ case 'SET NULL':
85
+ return 'set null';
86
+ case 'D':
87
+ case 'SET DEFAULT':
88
+ return 'set default';
89
+ case 'R':
90
+ case 'RESTRICT':
91
+ return 'restrict';
92
+ case 'A':
93
+ case 'NO ACTION':
94
+ return 'no action';
95
+ default:
96
+ return undefined;
97
+ }
98
+ }
99
+ /* ---------- derived views over the model ---------- */
100
+ /**
101
+ * Columns elsewhere that point at this table — the "what refers to me"
102
+ * question. Deliberately derived rather than stored, so it cannot drift from
103
+ * the foreign key list it is computed from.
104
+ */
105
+ /** A column of the table, or a rollup or a computed column its catalog serves (rollups.ts, computed.ts): what a measure may read. */
106
+ export function columnOrRollup(table, name) {
107
+ return (table.columns.some((column) => column.name === name) ||
108
+ Boolean(table.rollups && Object.hasOwn(table.rollups, name)) ||
109
+ Boolean(table.computed && Object.hasOwn(table.computed, name)));
110
+ }
111
+ export function referencesTo(schema, tableId) {
112
+ return schema.foreignKeys.filter((fk) => fk.to.table === tableId);
113
+ }
114
+ /** Columns on this table that point elsewhere. */
115
+ export function referencesFrom(schema, tableId) {
116
+ return schema.foreignKeys.filter((fk) => fk.from.table === tableId);
117
+ }
118
+ /* A frozen catalog's tables by id, made the first time one is looked up: a
119
+ captured catalog, and those derived from it, cannot change, and startup
120
+ looks the same few hundred tables up in one for every command, role and
121
+ resource — by a scan, that was a large part of a large App's startup. A
122
+ catalog that can still change (one being built) is scanned as before, and
123
+ is never indexed, even once frozen later. The first of an id, as the scan finds it. */
124
+ const tableIndexes = new WeakMap();
125
+ const fixed = (table) => Object.isFrozen(table) && 'value' in (Object.getOwnPropertyDescriptor(table, 'id') ?? {});
126
+ export function findTable(schema, tableId) {
127
+ const tables = schema.tables;
128
+ let index = tableIndexes.get(tables);
129
+ if (index === undefined) {
130
+ if (Object.isFrozen(tables) && tables.every(fixed)) {
131
+ const byId = new Map();
132
+ for (const table of tables)
133
+ if (!byId.has(table.id))
134
+ byId.set(table.id, table);
135
+ index = byId;
136
+ }
137
+ else
138
+ index = null;
139
+ tableIndexes.set(tables, index);
140
+ }
141
+ return index ? index.get(tableId) : tables.find((t) => t.id === tableId);
142
+ }
143
+ /**
144
+ * A table by its id, or by a bare name when only one table has it.
145
+ *
146
+ * A table's id is qualified where the engine qualifies things — `public.customer`
147
+ * on Postgres — and nobody types that when there is
148
+ * only one `customer`. Ambiguity is left unresolved rather than guessed: two
149
+ * schemas with a `customer` each is exactly when picking one silently writes
150
+ * to the wrong database.
151
+ */
152
+ export function tableNamed(schema, asked) {
153
+ const exact = findTable(schema, asked);
154
+ if (exact)
155
+ return exact;
156
+ const matches = schema.tables.filter((t) => t.name === asked);
157
+ return matches.length === 1 ? matches[0] : undefined;
158
+ }
159
+ /**
160
+ * Whether a column should be treated as a date for *presentation* — offering
161
+ * relative-date filters, rendering without a midnight time.
162
+ *
163
+ * Kept separate from `columnKind`, which feeds value coercion and must stay
164
+ * strictly declaration-based: guessing wrong there would change what gets
165
+ * written to the database. Guessing wrong here only offers a filter that does
166
+ * not match, which the user sees immediately.
167
+ *
168
+ * The fallback exists because plenty of real schemas store dates in TEXT —
169
+ * SQLite has no date type at all, so `opened_on TEXT` is idiomatic rather
170
+ * than sloppy, and refusing to offer `last 30 days` on it would make the best
171
+ * part of the language unavailable exactly where it is most needed.
172
+ */
173
+ const DATE_NAME = /(^|_)(date|time|datetime|timestamp)(_|$)|_(at|on)$|^(created|updated|modified|deleted)(_|$)/i;
174
+ export function looksLikeDate(column) {
175
+ if (columnKind(column.type) === 'date')
176
+ return true;
177
+ // Only text columns get the name-based benefit of the doubt; a number named
178
+ // `updated_at` is an epoch and comparing it to a timestamp string is wrong.
179
+ return columnKind(column.type) === 'text' && DATE_NAME.test(column.name);
180
+ }
181
+ /**
182
+ * The column a row is best identified by in a list or a breadcrumb.
183
+ *
184
+ * A primary key is correct and unreadable — nobody recognises a row by its
185
+ * UUID. Prefer a human-meaningful column when the table has one, and say so
186
+ * by returning the primary key only as a fallback.
187
+ */
188
+ /* Order matters and is not arbitrary. Name-family columns come first because
189
+ `title` on a table that also has `first_name` is a job title, not a label —
190
+ ranking it higher labels every row in a staff list "Account Executive". */
191
+ const LABEL_CANDIDATES = [
192
+ 'name',
193
+ 'full_name',
194
+ 'display_name',
195
+ 'first_name',
196
+ 'username',
197
+ 'title',
198
+ 'label',
199
+ 'subject',
200
+ 'number',
201
+ 'email',
202
+ 'slug',
203
+ 'code',
204
+ ];
205
+ /** The column that names each row by what it is called (`name`, `title`, `invoice_number`), never one picked only
206
+ because it is text: the label of a table that has one, for a caller that must not take a guess for a name. */
207
+ export function rowName(table) {
208
+ const byName = LABEL_CANDIDATES.find((c) => table.columns.some((col) => col.name === c));
209
+ if (byName)
210
+ return byName;
211
+ /* `number` above with its noun attached: `tracking_number`, `invoice_number`.
212
+ It is how a person quotes the row, so it names the row before the first
213
+ text column does, which on a shipment would be the carrier's id. */
214
+ return table.columns.find((c) => /_number$/i.test(c.name))?.name;
215
+ }
216
+ export function labelColumn(table) {
217
+ const named = rowName(table);
218
+ if (named)
219
+ return named;
220
+ /* A date is never a good label. Two rows created the same day are
221
+ indistinguishable, and "2025-03-14" tells you nothing about *which*
222
+ invoice you are looking at — the key at least identifies it. Before the
223
+ demo declared proper date types this quietly labelled every invoice by
224
+ its date, which looked plausible and was useless. */
225
+ /* Nor is a column with a vocabulary. `status` is a text column and reads
226
+ like one, but a name has to identify a row: labelling six hundred
227
+ invoices "issued" is worse than labelling them by their key, because it
228
+ looks like a name and distinguishes nothing. */
229
+ /* Nor who stamped it: `received_by` reads like a name and is one, of the
230
+ person who did something to the row — empty until they do, and the same
231
+ on hundreds of rows after. And a column the row must have beats one it
232
+ may leave blank: the first text column of a purchase order was a
233
+ nullable `received_by`, and every order was named by nothing. */
234
+ /* Nor a pointer: a text column that references another table holds that record's key, not this row's name. The
235
+ one that mattered is a tenant table's ownership column (`tenant_id`, required and the same on every row), which
236
+ named a list's search box and every row of a table with no name of its own. */
237
+ const texts = table.columns.filter((c) => !c.primaryKey &&
238
+ !c.references &&
239
+ /char|text|varchar|string/i.test(c.type) &&
240
+ !looksLikeDate(c) &&
241
+ !c.allowed?.length &&
242
+ !/_by$/i.test(c.name));
243
+ const firstText = texts.find((c) => !c.nullable) ?? texts[0];
244
+ return firstText?.name ?? table.columns.find((c) => c.primaryKey)?.name;
245
+ }
246
+ /** Primary key columns, in declaration order. */
247
+ export function primaryKey(table) {
248
+ return table.columns.filter((c) => c.primaryKey).map((c) => c.name);
249
+ }
250
+ /* Tables that hold identities rather than things: the party-model pattern,
251
+ where a person's name lives on `party` or `person` and everything else —
252
+ employee, contact, supplier — points at it. Named the way labelColumn's
253
+ candidates are, because the schema does not record "this link is 1:1" and
254
+ the name is the signal actually present. */
255
+ const IDENTITY_TABLE = /(^|_)(party|parties|person|persons|people|user|users|profile|profiles|identity|identities)$/i;
256
+ /**
257
+ * Where a row's name lives, as a view path.
258
+ *
259
+ * `labelColumn` answers "which of this table's own columns reads best", and
260
+ * for a well-normalised table the honest answer is none of them: employee
261
+ * carries `party_id`, and the name is `party.display_name`, one table away.
262
+ * So when a table's best label is its own key, the question is asked one
263
+ * forward hop further before giving up — a tool whose whole idea is walking
264
+ * references should not call a person "30" when the walk it teaches would
265
+ * have found the name.
266
+ *
267
+ * The hop is taken only across a link that is plausibly one-to-one: a
268
+ * reference that *is* the whole primary key (the subtype pattern —
269
+ * `person.party_id PRIMARY KEY REFERENCES party` — one-to-one by
270
+ * construction), or a reference into an identity table. Not any reference
271
+ * with a name on the other end: `invoice.customer_id` reaches a perfectly
272
+ * good name that is not the invoice's — forty invoices share it, and a trail
273
+ * of rows all called "Dry Creek Vineyards" identifies nothing.
274
+ *
275
+ * A table with a real label of its own keeps it, so nothing changes where
276
+ * things already read well. Self-references are skipped: the manager's name
277
+ * is not this row's name.
278
+ */
279
+ export function labelPath(schema, table, preferred) {
280
+ /* A name the catalog computes — a template, or a column whose display rule
281
+ masks it (appRecordLabels.ts) — is read where it is computed, even where
282
+ the App named the column: the column itself would carry the value. */
283
+ if (table.labelTemplate && preferred !== undefined && preferred !== false && !isLabelTemplate(preferred))
284
+ return LABEL_SEGMENT;
285
+ // A projected false suppresses inference without revealing the unavailable path.
286
+ if (preferred !== undefined && preferred !== false && isLabelTemplate(preferred)) {
287
+ /* A template is computed in the statement as `$label`, where this catalog
288
+ serves it; one that does not (a restricted projection) names the row by
289
+ the template's first column rather than by nothing. */
290
+ if (table.labelTemplate)
291
+ return LABEL_SEGMENT;
292
+ const parsed = parseLabelTemplate(preferred);
293
+ return 'paths' in parsed ? parsed.paths[0] : undefined;
294
+ }
295
+ if (preferred !== undefined)
296
+ return preferred === false ? undefined : preferred;
297
+ // A table an App names by a template of its own (its noun and key) reads that.
298
+ if (table.labelTemplate)
299
+ return LABEL_SEGMENT;
300
+ const own = labelColumn(table);
301
+ const key = primaryKey(table);
302
+ if (own && !key.includes(own))
303
+ return own;
304
+ for (const column of table.columns) {
305
+ const ref = column.references;
306
+ if (!ref || ref.table === table.id)
307
+ continue;
308
+ const oneToOne = key.length === 1 && key[0] === column.name;
309
+ const target = findTable(schema, ref.table);
310
+ if (!target)
311
+ continue;
312
+ if (!oneToOne && !IDENTITY_TABLE.test(target.name))
313
+ continue;
314
+ const theirs = labelColumn(target);
315
+ if (!theirs || primaryKey(target).includes(theirs))
316
+ continue;
317
+ return `${column.name}.${theirs}`;
318
+ }
319
+ return own;
320
+ }
321
+ /* ---------- ordering ---------- */
322
+ /* Text by its type name; an enum or a set is the engine's own type, which it already sorts as declared. */
323
+ const TEXT_TYPE = /char|text|string|clob|citext|^name$/i;
324
+ /**
325
+ * The order a column's values sort in when it is not their text: the
326
+ * vocabulary the database declares over a text column (`CHECK (stage IN
327
+ * ('new', 'qualified', 'won', 'lost'))`), in the order it was written. A
328
+ * pipeline sorted A → Z put "Closed lost" before "Qualification"; sorted as
329
+ * declared it reads as the pipeline does. A native enum (Postgres) is
330
+ * left alone, since the engine already orders it so, and free text has none.
331
+ * Every value the column can hold is in the list or NULL, which is what lets
332
+ * a page continue past one by naming the values after it (keysetPage.ts).
333
+ */
334
+ export function declaredOrder(column) {
335
+ const allowed = column?.allowed;
336
+ if (!allowed || allowed.length < 2 || !TEXT_TYPE.test(column.type) || /^\s*(enum|set)\b/i.test(column.type))
337
+ return undefined;
338
+ return allowed;
339
+ }
340
+ /* Columns that record when a row was last touched, then when it came into
341
+ existence. Ordered by how well each answers "what has been happening here",
342
+ which is the question a table you have just opened is usually being asked. */
343
+ const TOUCHED_NAME = /^(sys_)?(updated|modified|changed|last_updated)(_at|_on|_date)?$/i;
344
+ const CREATED_NAME = /^(sys_)?(created|inserted|added|opened|raised|issued|ordered|received|signed_up|joined)(_at|_on|_date)?$/i;
345
+ /**
346
+ * The order a table's rows are shown in when the query does not say.
347
+ *
348
+ * There has to be one, and not for taste: `LIMIT`/`OFFSET` without `ORDER BY`
349
+ * has no defined order in either SQLite or Postgres, so paging through an
350
+ * unordered table can repeat a row on page two and never show another. The
351
+ * database is free to hand back rows in whatever order it finds them, and
352
+ * Postgres in particular will change its mind after an UPDATE moves a row.
353
+ * A default order is what makes "Next" mean what it appears to mean.
354
+ *
355
+ * Given that it must exist, it may as well be useful. In order of preference:
356
+ *
357
+ * 1. When the row was last touched, newest first — *if the column is
358
+ * indexed*. On a table with an indexed `updated_at`, "what changed
359
+ * recently" is what people open it to see, and the database can answer it
360
+ * by walking the index backwards.
361
+ * 2. When it was created, newest first, under the same condition.
362
+ * 3. A single numeric primary key, descending. On an autoincrement key that
363
+ * is the same "newest first" by proxy.
364
+ * 4. Any other primary key, ascending. A text key sorts alphabetically —
365
+ * `country` starting at ZW rather than AU would be perverse — and a
366
+ * composite key ascending groups its children under their parent, which
367
+ * is how `invoice_line` wants to be read.
368
+ * 5. The label column, then the first column: neither is meaningful, but
369
+ * both are deterministic, which is the part that matters.
370
+ *
371
+ * The index condition is the one rule here that is not about taste. A default
372
+ * that nobody asked for must not be a default that costs anything: `ORDER BY
373
+ * updated_at DESC LIMIT 20` on an unindexed column is a full scan and a sort
374
+ * of the whole table to return twenty rows, and it would happen on every table
375
+ * you clicked. The primary key is always indexed, which is why it is the
376
+ * fallback rather than merely one option among several.
377
+ *
378
+ * A table whose adapter does not report indexes at all gets the key, not a
379
+ * guess — `indexed` is undefined rather than empty in that case precisely so
380
+ * the two can be told apart.
381
+ */
382
+ export function defaultOrder(table) {
383
+ const indexed = new Set(table.indexed ?? []);
384
+ const named = (test) => table.columns.find((c) => test.test(c.name) && (looksLikeDate(c) || columnKind(c.type) === 'number') && indexed.has(c.name));
385
+ const touched = named(TOUCHED_NAME) ?? named(CREATED_NAME);
386
+ if (touched)
387
+ return withKey(table, [{ column: touched.name, direction: 'desc' }]);
388
+ const key = primaryKey(table);
389
+ if (key.length === 1) {
390
+ const column = table.columns.find((c) => c.name === key[0]);
391
+ return [{ column: key[0], direction: columnKind(column.type) === 'number' ? 'desc' : 'asc' }];
392
+ }
393
+ if (key.length > 1)
394
+ return key.map((column) => ({ column, direction: 'asc' }));
395
+ const label = labelColumn(table);
396
+ const fallback = label ?? table.columns[0]?.name;
397
+ return fallback ? [{ column: fallback, direction: 'asc' }] : [];
398
+ }
399
+ /**
400
+ * Make an order total by appending the primary key.
401
+ *
402
+ * Sorting by `status` leaves every row with the same status in an undefined
403
+ * order relative to its neighbours — which is the paging bug again, one level
404
+ * down: page one and page two disagree about which of two equal rows comes
405
+ * first, so one is shown twice and one not at all. Appending the key breaks
406
+ * every remaining tie the same way each time.
407
+ *
408
+ * A table with no primary key cannot be made stable this way, and is left
409
+ * alone rather than given a guess.
410
+ */
411
+ export function withKey(table, order) {
412
+ const chosen = new Set(order.map((o) => o.column));
413
+ const key = primaryKey(table).filter((c) => !chosen.has(c));
414
+ return [...order, ...key.map((column) => ({ column, direction: 'asc' }))];
415
+ }
416
+ /**
417
+ * The order to actually run with, and whether the caller asked for it.
418
+ *
419
+ * `implicit` is reported rather than hidden: the grid shows which column it
420
+ * sorted by, so a default order is something the reader can see and disagree
421
+ * with rather than a silent rearrangement of their data.
422
+ */
423
+ export function resolveOrder(table, requested) {
424
+ if (requested?.length)
425
+ return { order: withKey(table, requested), implicit: false };
426
+ return { order: defaultOrder(table), implicit: true };
427
+ }
428
+ /**
429
+ * Reconstruct a table's DDL from the catalog.
430
+ *
431
+ * This is a *reconstruction*, and callers must say so. It is built from what
432
+ * introspection captured — columns, types, nullability, defaults, keys — and
433
+ * therefore omits anything the model does not carry: indexes, check
434
+ * constraints, triggers, partitioning, storage parameters. Presenting it as
435
+ * the definitive `CREATE TABLE` would be a lie that bites the first time
436
+ * someone copies it into a migration.
437
+ *
438
+ * An adapter that can produce the database's own stored DDL should do so
439
+ * instead; `SqliteAdapter` does, because `sqlite_master` keeps the original
440
+ * statement text verbatim.
441
+ */
442
+ export function renderDDL(schema, tableId) {
443
+ const table = findTable(schema, tableId);
444
+ if (!table)
445
+ return `-- No table called "${tableId}".`;
446
+ const quote = (id) => `"${id.replace(/"/g, '""')}"`;
447
+ /* A qualified name is two identifiers, not one containing a dot. Quoting
448
+ `app.invoice_line` whole produces a table literally named "app.invoice_line",
449
+ which is valid SQL for something that does not exist — the worst kind of
450
+ wrong output, because it looks right until you run it. */
451
+ const qualified = (id) => {
452
+ const table = findTable(schema, id);
453
+ return table?.schema ? `${quote(table.schema)}.${quote(table.name)}` : quote(id);
454
+ };
455
+ const width = Math.max(...table.columns.map((c) => c.name.length), 0);
456
+ const lines = table.columns.map((col) => {
457
+ const parts = [quote(col.name).padEnd(width + 2), col.type.toUpperCase()];
458
+ if (!col.nullable)
459
+ parts.push('NOT NULL');
460
+ if (col.default !== undefined)
461
+ parts.push(`DEFAULT ${col.default}`);
462
+ return ` ${parts.join(' ')}`;
463
+ });
464
+ const pk = primaryKey(table);
465
+ if (pk.length)
466
+ lines.push(` PRIMARY KEY (${pk.map(quote).join(', ')})`);
467
+ for (const fk of referencesFrom(schema, tableId)) {
468
+ lines.push(` CONSTRAINT ${quote(fk.name)} FOREIGN KEY (${fk.from.columns.map(quote).join(', ')}) ` +
469
+ `REFERENCES ${qualified(fk.to.table)} (${fk.to.columns.map(quote).join(', ')})`);
470
+ }
471
+ const header = table.isView
472
+ ? `-- ${tableId} is a view. Its defining query was not captured;\n-- the columns below are what it returns.\nCREATE VIEW ${qualified(tableId)} (`
473
+ : `CREATE TABLE ${qualified(tableId)} (`;
474
+ const body = `${header}\n${lines.join(',\n')}\n);`;
475
+ return table.comment ? `-- ${table.comment}\n${body}` : body;
476
+ }
477
+ export function columnKind(type) {
478
+ const t = (type ?? '').toLowerCase();
479
+ if (/bool/.test(t))
480
+ return 'boolean';
481
+ /* Not interval or point, which hold "int" and are not numbers: read as one, a
482
+ filter compared an interval with an integer and a form refused "1 day". */
483
+ if (/int|serial|numeric|decimal|real|double|float|money/.test(t) && !/interval|point/.test(t))
484
+ return 'number';
485
+ if (/date|time/.test(t))
486
+ return 'date';
487
+ if (/char|text|uuid|json|enum|clob/.test(t))
488
+ return 'text';
489
+ return 'other';
490
+ }
491
+ /**
492
+ * What an aggregate other than a count reads from a value of this type.
493
+ * PostgreSQL has no sum, average, minimum, maximum or percentile of a boolean
494
+ * ("function avg(boolean) does not exist"), where SQLite holds one as
495
+ * 0 and 1 and add it up; read as an integer there, a won rate is the same
496
+ * number on every engine, a computed yes-or-no or a stored one.
497
+ */
498
+ export function aggregateInput(read, type, dialect) {
499
+ return dialect === 'postgres' && columnKind(type ?? '') === 'boolean' ? `CAST(${read} AS INTEGER)` : read;
500
+ }
501
+ /** A column that holds yes or no: declared BOOLEAN, or an integer a CHECK pins to 0 and 1. */
502
+ export function isFlagColumn(column) {
503
+ return Boolean(column) && (columnKind(column.type) === 'boolean' || column.flag === true);
504
+ }
505
+ /**
506
+ * How a column holds the moment something happened, the one rule every `now`
507
+ * the server writes follows (appStamps.ts): a DATE the App's day, a
508
+ * TIMESTAMP or DATETIME an instant (zoned or the App's wall clock), and a text
509
+ * column named for a moment — SQLite keeps dates as text — `_on` a day and
510
+ * `_at` an instant, in the digits the typed column would hold. Undefined for
511
+ * any other column, a TIME of day among them.
512
+ */
513
+ export function momentColumn(column) {
514
+ const type = (column.type ?? '').trim();
515
+ /* A SQLite text column the App declares a day (`types: { completed_on: 'date' }`, declaredDates.ts) reads `TEXT as date`. */
516
+ if (/^date$|\sas date$/i.test(type))
517
+ return 'date';
518
+ if (/timestamp|datetime/i.test(type))
519
+ return /timestamptz|with time zone/i.test(type) ? 'instant-zoned' : 'instant';
520
+ if (!/char|text|clob/i.test(type) || /uuid|json|enum/i.test(type) || columnKind(type) !== 'text')
521
+ return undefined;
522
+ return column.name.endsWith('_on') ? 'date' : column.name.endsWith('_at') ? 'instant' : undefined;
523
+ }
524
+ /**
525
+ * The column a state stamps as the record enters it, by its name: `ready_at`
526
+ * (or `ready_on`) beside a `ready` state is written the moment the record
527
+ * moves there, whatever moves it — a verb, a Save, a command — unless the
528
+ * write says it itself. Never the machine's own column or its `since`, never a
529
+ * key, a number or a flag.
530
+ */
531
+ export function stateStampColumn(state, columns, machine) {
532
+ for (const suffix of ['_at', '_on']) {
533
+ const column = columns.find((candidate) => candidate.name === `${state}${suffix}`);
534
+ if (column &&
535
+ !column.primaryKey &&
536
+ column.name !== machine.column &&
537
+ column.name !== machine.since &&
538
+ !isFlagColumn(column) &&
539
+ momentColumn(column) !== undefined)
540
+ return column;
541
+ }
542
+ return undefined;
543
+ }
544
+ /**
545
+ * Turn a value on its way *into* the database into the right JavaScript type
546
+ * for its column.
547
+ *
548
+ * Everything typed into a text input arrives as a string, including "17901"
549
+ * for a REAL column. SQLite's type affinity usually rescues that, but not
550
+ * always — a column with BLOB affinity stores the characters — and Postgres
551
+ * rejects it outright. Either way the stored value should be a number because
552
+ * the column says so, not because the driver was forgiving.
553
+ *
554
+ * Unparseable input is passed through unchanged rather than coerced to NaN or
555
+ * 0. Letting the database reject "abc" for an integer column gives the user a
556
+ * real error; silently storing 0 gives them a wrong number.
557
+ *
558
+ * Only a number a double holds exactly becomes one. An id past 2^53 or a
559
+ * numeric wider than fifteen digits stays the text it was typed as, and the
560
+ * database parses it exactly: through Number(), "9007199254740993" was
561
+ * written as …992, a different row. And only plain decimal text is read as
562
+ * a number at all — Number() also reads "0x1A" as 26 and "1e3" as 1000,
563
+ * which is not what was typed; those go to the database as given too.
564
+ */
565
+ export function coerceForColumn(declaredType, value) {
566
+ if (value === null || typeof value !== 'string')
567
+ return value;
568
+ const kind = columnKind(declaredType);
569
+ if (kind === 'number') {
570
+ const typed = value.trim();
571
+ if (typed === '')
572
+ return null;
573
+ const plain = /^-?(\d+)(?:\.(\d+))?$/.exec(typed);
574
+ if (!plain)
575
+ return value;
576
+ const n = Number(typed);
577
+ if (plain[2] === undefined)
578
+ return Number.isSafeInteger(n) && String(n) === typed ? n : value;
579
+ // Fifteen significant digits is what every double carries back exactly.
580
+ const significant = `${plain[1]}${plain[2]}`.replace(/^0+/, '').replace(/0+$/, '').length;
581
+ return significant <= 15 ? n : value;
582
+ }
583
+ if (kind === 'boolean') {
584
+ if (/^(true|yes|1|t)$/i.test(value))
585
+ return true;
586
+ if (/^(false|no|0|f)$/i.test(value))
587
+ return false;
588
+ return value;
589
+ }
590
+ return value;
591
+ }
592
+ /** A column that holds bytes: BLOB (SQLite), bytea (Postgres), (VAR)BINARY. */
593
+ export function isBinaryType(type) {
594
+ return /^(blob|tinyblob|mediumblob|longblob|bytea|binary|varbinary)\b/i.test((type ?? '').trim());
595
+ }
596
+ /** A column that holds a JSON document: json and jsonb (Postgres), JSON (SQLite by declaration). */
597
+ export function isJsonType(type) {
598
+ return /^jsonb?\b/i.test((type ?? '').trim());
599
+ }
600
+ /** A column whose stored value an update can be compared on (scoped/updateGuard.ts): not a document, bytes, an array or a geometry. */
601
+ export function comparableType(type) {
602
+ return !/json|blob|binary|bytea|\[\]|geometry|geography|xml|interval|money|range/i.test(type ?? '');
603
+ }
604
+ /**
605
+ * What an update of `values` expects the record to hold still: each column
606
+ * it writes, as the list or record showed it (`row`). Sent as the update's
607
+ * `expected`, it makes the write a compare-and-set, so a save made on a row
608
+ * someone else has since changed is refused rather than written over theirs
609
+ * — the lost update a writer pool would otherwise let through (server
610
+ * writeLanes.ts). Undefined when the row does not hold every written column
611
+ * as a plain value of a comparable type: the write is then as blind as ever.
612
+ */
613
+ export function expectedValues(table, values, row) {
614
+ if (!row)
615
+ return undefined;
616
+ const expected = {};
617
+ for (const column of Object.keys(values)) {
618
+ const value = row[column];
619
+ const meta = table.columns.find((item) => item.name === column);
620
+ if (!meta || !Object.hasOwn(row, column) || !comparableType(meta.type))
621
+ return undefined;
622
+ if (value !== null && typeof value !== 'string' && typeof value !== 'boolean' && !(typeof value === 'number' && Number.isFinite(value)))
623
+ return undefined;
624
+ expected[column] = value;
625
+ }
626
+ return Object.keys(expected).length ? expected : undefined;
627
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * The schema as text — Mermaid, Markdown, JSON — with no DOM and no state.
3
+ *
4
+ * Split from schemaexport.js so the server can speak these formats too:
5
+ * `tablewalk --export md` prints the same brief the browser downloads, and a
6
+ * committed CLAUDE.md schema section costs one command. Pure on purpose, the
7
+ * way shape.js is pure — a schema in, text out, importable from anywhere.
8
+ */
9
+ /** The tables to export, and the keys wholly between them. */
10
+ export declare function selection(schema: any, only: any): {
11
+ tables: any;
12
+ keys: any;
13
+ };
14
+ /**
15
+ * Mermaid `erDiagram`.
16
+ *
17
+ * Cardinality is stated as far as the catalog knows it, which is not very far:
18
+ * a foreign key says the child *may* point at one parent, and says nothing
19
+ * about whether a parent must have children. So every relationship is written
20
+ * `}o--||` — many-optional to exactly-one — which is what a nullable foreign
21
+ * key actually guarantees. Claiming more precision would be inventing it.
22
+ *
23
+ * Mermaid identifiers cannot contain a dot, so `app.invoice` becomes
24
+ * `app_invoice`. Said in a comment at the top of the output rather than
25
+ * silently, because someone comparing the diagram to their database will
26
+ * notice.
27
+ */
28
+ export declare function toMermaid(schema: any, only: any): string;
29
+ /** A readable reference document, of the kind that belongs in a repository. */
30
+ export declare function toMarkdown(schema: any, only: any): string;
31
+ /**
32
+ * The structured form.
33
+ *
34
+ * Deliberately the shape tablewalk itself uses rather than a format invented
35
+ * for export — anything that reads it is reading the same model the tool
36
+ * reasons about, and there is no second definition to keep in step.
37
+ */
38
+ export declare function toSchemaJson(schema: any, only: any): string;