@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,606 @@
1
+ import { ANSI_STYLE, POSTGRES_STYLE } from '../adapters/adapter.js';
2
+ import { findTable } from '../shared/schema.js';
3
+ import { parseQuery, explain } from '../shared/query.js';
4
+ import { PathError, explainView, parseViewQuery } from '../shared/view.js';
5
+ import { textToView, viewToTextWithSchema } from '../shared/viewtext.js';
6
+ import { breakdownToText, sectionFromText, textToBreakdown } from '../shared/breakdowntext.js';
7
+ import { explainBreakdown } from '../shared/breakdown.js';
8
+ import { readRecords, readCount, readCounts, readView, readViewCount, readBreakdown, ResourceReadError, DEFAULT_COUNT_LIMIT, } from './resourceReadOperations.js';
9
+ import { clampLimit, clampOffset, COUNT_EACH_MAX } from '../shared/reads.js';
10
+ import { readPageStep } from '../shared/keysetPage.js';
11
+ import { recordsPaging, settlePage, viewPaging } from './keysetReadHttp.js';
12
+ /**
13
+ * A view's count as a plain count, when it is one: every condition names a
14
+ * column of the base itself — no path through a reference, no rollup, no
15
+ * label — so the view's joins and projection cannot change how many rows
16
+ * there are. Null otherwise, and for a condition compared with another column
17
+ * (`on_hand <= reorder_at`): only the view's compiler resolves the right-hand
18
+ * column against the reader's catalog, so a structured count refuses one, and
19
+ * the tab is counted as its list reads it, through the view.
20
+ */
21
+ function plainCount(schema, view) {
22
+ const base = findTable(schema, view.base);
23
+ if (!base)
24
+ return null;
25
+ const own = (path) => path === undefined || (!path.includes('.') && !view.computed?.[path] && base.columns.some((column) => column.name === path));
26
+ const groups = view.filter?.groups ?? [];
27
+ if (!groups.every((group) => group.every((condition) => own(condition.path) && condition.other === undefined)))
28
+ return null;
29
+ return groups.length
30
+ ? {
31
+ filter: {
32
+ groups: groups.map((group) => group.map((condition) => ({
33
+ column: condition.path,
34
+ op: condition.op,
35
+ ...(condition.value === undefined ? {} : { value: condition.value }),
36
+ ...(condition.collation === undefined ? {} : { collation: condition.collation }),
37
+ }))),
38
+ },
39
+ }
40
+ : {};
41
+ }
42
+ /* What a batched list's page may say: what `/api/run` reads of a first page. */
43
+ const RUN_FIELDS = ['q', 'limit', 'offset', 'count', 'exactCount', 'countLimit'];
44
+ /** A dashboard is at most a few dozen sections; a batch past this is not one. */
45
+ export const BREAKDOWN_BATCH = 48;
46
+ /* How many of a batch's breakdowns read at once: the PostgreSQL read pool's
47
+ default size (--read-pool), so a batch never queues behind itself. */
48
+ const BREAKDOWN_CONCURRENCY = 4;
49
+ /** The furthest a list is paged by offset over HTTP: past it the rows skipped cost more than the page. */
50
+ export const MAX_PAGE_OFFSET = 10_000;
51
+ /** The routes a list, a view or a breakdown is paged through. */
52
+ const PAGED = new Set(['/api/query', '/api/run', '/api/view/run', '/api/breakdown']);
53
+ /**
54
+ * Parse and shape the five resource-read routes using an already-authorized
55
+ * adapter. This owns no source acquisition, response stream or HTTP error class:
56
+ * escaping service validation errors retain their identity for the host to map.
57
+ */
58
+ export async function dispatchResourceReadHttp(path, body, adapter, schema, options) {
59
+ /* A union's reads are its branches', each through this same reader (unionReads.ts). */
60
+ const app = options.app;
61
+ if (app)
62
+ adapter = app.reader(adapter, schema);
63
+ const sendData = (_route, value) => reply(200, app ? app.reply({ ...value }) : { ...value });
64
+ /* The person is looked up once, and only for text that compares with them. */
65
+ /* An App's weeks start where its locale says, never where a request does. */
66
+ const weekOf = (def) => (options.weekStart === undefined ? def : { ...def, weekStart: options.weekStart });
67
+ /* With the memberships the text reads (`me.group_member.group_id`), through this request's own reader. */
68
+ const personFor = async (...texts) => options.me && app ? app.person(options.me, texts, schema, adapter) : {};
69
+ /* A page is found by skipping every row before it, so the database walks
70
+ them all: page 80,000 of a sorted list was fifteen seconds on SQLite,
71
+ with the server's one handle held the whole time, and two seconds on
72
+ PostgreSQL. Nobody reads that far by paging; they narrow the list. An
73
+ export reads its own way (exportRoute.ts), and the App API by cursor. */
74
+ /* The query bar's list pages by key (keysetReadHttp.ts): a step after a
75
+ row, before one or from the end costs what the first page does, and the
76
+ offset it carries only names the page. A step the order cannot take —
77
+ no key, a sort through a reference — is an offset again, and meets the
78
+ ceiling below. */
79
+ const step = path === '/api/run' ? readPageStep(body) : undefined;
80
+ if (step === 'invalid')
81
+ return refusal(400, ['A page starts "after" a row, "before" one, or at the "end": one of the three.']);
82
+ const tooDeep = () => clampOffset(body.offset) > MAX_PAGE_OFFSET
83
+ ? reply(200, {
84
+ errors: [
85
+ {
86
+ message: `That page starts past the first ${MAX_PAGE_OFFSET.toLocaleString('en-US')} rows, ` +
87
+ 'which is further than a list is paged. Narrow the filter, or sort the other way to reach the end.',
88
+ },
89
+ ],
90
+ })
91
+ : undefined;
92
+ if (PAGED.has(path) && !step) {
93
+ const refused = tooDeep();
94
+ if (refused)
95
+ return refused;
96
+ }
97
+ if (path === '/api/query') {
98
+ const { result, order } = await readRecords(adapter, schema, {
99
+ table: String(body.table ?? ''),
100
+ filter: body.filter,
101
+ columns: Array.isArray(body.columns) ? body.columns : undefined,
102
+ orderBy: body.orderBy,
103
+ limit: body.limit,
104
+ offset: body.offset,
105
+ });
106
+ return sendData(path, { ...result, order });
107
+ }
108
+ /**
109
+ * Parse-and-run, for the query bar.
110
+ *
111
+ * The language lives on the server and only on the server. The client could
112
+ * parse it too, but then there would be two implementations to keep in step
113
+ * and a build step to ship the shared one to the browser. Sending the text
114
+ * and getting back rows, the compiled SQL and any errors costs one round
115
+ * trip and keeps the client a static file.
116
+ */
117
+ if (path === '/api/run') {
118
+ /* `count: 'none'` is for a caller that never shows a total — a dashboard
119
+ tile, a palette search, a lookup, the cards and the calendar — and so
120
+ never pays for one. Anything else unreadable is refused rather than
121
+ read as the default, as /api/view/run refuses it. */
122
+ if (body.count !== undefined && body.count !== 'none' && body.count !== 'exact' && body.count !== 'estimate') {
123
+ return refusal(400, ['count must be "none", "exact" or "estimate".']);
124
+ }
125
+ const text = String(body.q ?? '');
126
+ const person = await personFor(text);
127
+ const parsed = parseQuery(text, { schema, now: options.now(), ...person });
128
+ /* A view is a superset of a query, so the bar can take one.
129
+ `invoice customer_id.name contains Harbour` is not a legal single-table
130
+ query — `customer_id.name` is not a column on invoice — but it is a
131
+ perfectly good view, and refusing it because of which endpoint the text
132
+ arrived at would be an implementation detail leaking into the language.
133
+
134
+ The fall-through is deliberately one-way and last. Anything that parses
135
+ cleanly as a query still runs as a query, so no text that works today
136
+ can change meaning; only text that would otherwise have been an error
137
+ gets a second reading. */
138
+ if ((!parsed.query || parsed.errors.length) && adapter.runView) {
139
+ const asView = textToView(schema, text, { id: 'bar', name: '', now: options.now(), ...person });
140
+ if (asView.view && !asView.errors.length) {
141
+ const base = findTable(schema, asView.view.base);
142
+ /* A union pages by offset: its rows have no one key order across branches (unionReads.ts). */
143
+ const paging = base && !base.union ? viewPaging(schema, base, asView.view, step) : undefined;
144
+ if (step && !paging?.continuation) {
145
+ const refused = tooDeep();
146
+ if (refused)
147
+ return refused;
148
+ }
149
+ const most = options.rowsMost?.(asView.view.base);
150
+ const bounded = most === undefined ? body : { ...body, limit: Math.min(clampLimit(body.limit ?? asView.view.limit), most) };
151
+ return runViewForBar(adapter, schema, asView.view, bounded, app, body.count === 'none' ? 'none' : 'exact', paging);
152
+ }
153
+ }
154
+ if (!parsed.query)
155
+ return reply(200, { errors: parsed.errors });
156
+ // Errors that would change which rows come back must not be papered over
157
+ // with a partial result — a filter clause that failed to compile would
158
+ // otherwise silently return more rows than asked for.
159
+ if (parsed.errors.length) {
160
+ return sendData(path, { errors: parsed.errors, explain: explain(parsed.query) });
161
+ }
162
+ let q = parsed.query;
163
+ /* An explicit `columns` overrides the query's own `show` clause, matching
164
+ /api/query. Without it the two endpoints disagreed: one honoured the
165
+ field and the other ignored it silently, which is the worst of the
166
+ three options — a caller asking for three columns got all of them and
167
+ no indication why. */
168
+ if (Array.isArray(body.columns) && body.columns.length) {
169
+ const known = new Set(findTable(schema, q.table)?.columns.map((c) => c.name) ?? []);
170
+ const requested = body.columns.filter((c) => known.has(c));
171
+ const unknown = body.columns.filter((c) => !known.has(c));
172
+ if (unknown.length) {
173
+ return refusal(400, [`No column called "${unknown[0]}" on ${q.table}.`]);
174
+ }
175
+ // A copy: a parse is kept and shared (shared/query.ts), never changed.
176
+ q = { ...q, columns: requested };
177
+ }
178
+ /* An API reports no totals (adapters/http), and counting one would walk
179
+ every page of someone else's rate budget: its lists page by whether a
180
+ full page came back, as a view without a count does. */
181
+ const exact = body.exactCount === true || body.count === 'exact';
182
+ const countMode = schema.dialect === 'http' || body.count === 'none' ? 'none' : exact ? 'exact' : 'estimate';
183
+ /* A filtered total is counted to DEFAULT_COUNT_LIMIT unless the request
184
+ asks for the exact number or names its own bound: past it the list says
185
+ "10,000+" and offers to count exactly. Unfiltered, the catalog's
186
+ estimate or a plain count answers as before. */
187
+ const countLimit = body.countLimit ?? (!exact && q.filter?.groups?.length ? DEFAULT_COUNT_LIMIT : undefined);
188
+ const own = findTable(schema, q.table);
189
+ const most = options.rowsMost?.(own?.id ?? q.table);
190
+ const bounded = (limit) => (most === undefined ? limit : Math.min(clampLimit(limit), most));
191
+ const paging = own && !own.union ? recordsPaging(own, schema.dialect, q.orderBy, q.columns, q.filter, step) : undefined;
192
+ if (step && !paging?.continuation) {
193
+ const refused = tooDeep();
194
+ if (refused)
195
+ return refused;
196
+ }
197
+ const { result, total, order, request: { limit, offset }, } = await readRecords(adapter, schema, { ...q, ...(paging?.columns ? { columns: paging.columns } : {}), limit: bounded(body.limit ?? q.limit), offset: body.offset }, countMode, countLimit, paging?.continuation);
198
+ const settled = paging ? settlePage(paging.order, paging.extra, result) : undefined;
199
+ return sendData(path, {
200
+ table: q.table,
201
+ ...result,
202
+ ...(settled ? { rows: settled.rows, columns: settled.columns, ...(settled.bounds ? { bounds: settled.bounds } : {}) } : {}),
203
+ ...(paging?.continuation ? { keyset: true } : {}),
204
+ ...(total ? { total: total.count, exactTotal: total.exact } : {}),
205
+ // Only when a bounded count stopped: `total` is then the bound, and more match.
206
+ ...(total?.capped ? { cappedTotal: true } : {}),
207
+ limit,
208
+ offset,
209
+ order,
210
+ explain: explain(q),
211
+ errors: [],
212
+ });
213
+ }
214
+ /**
215
+ * Several counts in one request: a list's tab badges.
216
+ *
217
+ * Each item is a question in the language, as a tab writes it. Every one
218
+ * that reads a table with a plain filter is counted in one statement where
219
+ * the reader can (readCounts: one conditional aggregate per tab over a
220
+ * small table, one bounded count per tab over a large one), through this
221
+ * request's own reader — the same grants, the same row scope. A tab that
222
+ * needs a view (a path through a reference) is counted as a view. Each is
223
+ * bounded as a list's total is, and a question that does not parse fails
224
+ * alone, in its item.
225
+ */
226
+ if (path === '/api/counts') {
227
+ const items = body.items;
228
+ if (!Array.isArray(items) || !items.length || items.length > COUNT_EACH_MAX || items.some((item) => typeof item !== 'string')) {
229
+ return refusal(400, [`A count batch is a list of 1 to ${COUNT_EACH_MAX} questions.`]);
230
+ }
231
+ const person = await personFor(...items);
232
+ const results = Array.from({ length: items.length });
233
+ const plain = [];
234
+ const views = [];
235
+ for (const [at, text] of items.entries()) {
236
+ const parsed = parseQuery(text, { schema, now: options.now(), ...person });
237
+ if (parsed.query && !parsed.errors.length) {
238
+ plain.push({ at, table: parsed.query.table, filter: parsed.query.filter });
239
+ continue;
240
+ }
241
+ const asView = adapter.runView ? textToView(schema, text, { id: 'bar', name: '', now: options.now(), ...person }) : undefined;
242
+ /* A list's tab asks its count in the list's own words, `show` paths
243
+ and all, which only a view reads; but a count reads only the
244
+ conditions. Conditions on the base's own columns are a plain count,
245
+ which is counted with the other tabs in one statement (countEach),
246
+ where a view is a statement of its own. */
247
+ const counted = asView?.view && !asView.errors.length ? plainCount(schema, asView.view) : null;
248
+ if (counted) {
249
+ plain.push({ at, table: asView.view.base, ...(counted.filter ? { filter: counted.filter } : {}) });
250
+ continue;
251
+ }
252
+ if (asView?.view && !asView.errors.length) {
253
+ /* A view's own statement, begun now and settled beside the plain
254
+ batch below: their waits overlap instead of adding. */
255
+ const view = asView.view;
256
+ views.push(readViewCount(adapter, schema, view, body.countLimit).then((counted) => {
257
+ results[at] = { total: counted.count, exactTotal: true, ...(counted.capped ? { cappedTotal: true } : {}) };
258
+ }));
259
+ continue;
260
+ }
261
+ results[at] = { errors: parsed.errors.length ? parsed.errors : [{ message: 'That question does not read as a count.' }] };
262
+ }
263
+ const batch = plain.length
264
+ ? readCounts(adapter, schema, plain, body.countLimit).then((counts) => {
265
+ plain.forEach(({ at }, i) => {
266
+ results[at] = {
267
+ total: counts[i].count,
268
+ exactTotal: counts[i].exact,
269
+ ...(counts[i].capped ? { cappedTotal: true } : {}),
270
+ };
271
+ });
272
+ })
273
+ : undefined;
274
+ /* Settled whole, so a failure leaves no read running behind the reply. */
275
+ const settled = await Promise.allSettled(batch ? [...views, batch] : views);
276
+ const failed = settled.find((result) => result.status === 'rejected');
277
+ if (failed)
278
+ throw failed.reason;
279
+ return reply(200, { results });
280
+ }
281
+ /**
282
+ * Several breakdowns in one request: a dashboard's cards, and its lists.
283
+ *
284
+ * A metric asks for its number, its compare window's number and its spark,
285
+ * and every chart and table asks once more, so an eight-card home was about
286
+ * thirty requests queued on one active connection and six browser sockets.
287
+ * Each item is answered by the single-breakdown route below, through this
288
+ * request's own adapter, so it reads exactly what that route would have —
289
+ * the same grant, the same row scope, the same errors — and a failing item
290
+ * fails alone. They run a few at a time: a PostgreSQL connection
291
+ * reads through a pool of several, so a filter rail's facets and a
292
+ * dashboard's cards cost the slowest of them rather than their sum; SQLite
293
+ * reads in process, where running them together costs nothing more. The
294
+ * answers keep the request's order.
295
+ */
296
+ if (path === '/api/breakdowns') {
297
+ const items = body.items;
298
+ if (!Array.isArray(items) ||
299
+ !items.length ||
300
+ items.length > BREAKDOWN_BATCH ||
301
+ items.some((item) => !item || typeof item !== 'object' || Array.isArray(item))) {
302
+ return refusal(400, [`A breakdown batch is a list of 1 to ${BREAKDOWN_BATCH} breakdowns.`]);
303
+ }
304
+ /* A dashboard's lists ride with its numbers: an item that is `run` is a
305
+ list's first page, answered as `/api/run` answers it. Only the page's
306
+ own fields are passed on, so a batch cannot ask anything the single
307
+ route would not. */
308
+ const run = (item) => item.run && typeof item.run === 'object' && !Array.isArray(item.run) ? item.run : undefined;
309
+ if (items.some((item) => 'run' in item && !run(item))) {
310
+ return refusal(400, ['A batched list is `run: { q, limit, offset, count, exactCount, countLimit }`.']);
311
+ }
312
+ const results = Array.from({ length: items.length });
313
+ const queue = items.map((item, at) => ({ item, at }));
314
+ const one = async () => {
315
+ for (let next = queue.shift(); next; next = queue.shift()) {
316
+ const page = run(next.item);
317
+ const { def, text, limit, offset } = next.item;
318
+ try {
319
+ results[next.at] = (await (page
320
+ ? dispatchResourceReadHttp('/api/run', Object.fromEntries(RUN_FIELDS.filter((field) => page[field] !== undefined).map((field) => [field, page[field]])), adapter, schema, options)
321
+ : dispatchResourceReadHttp('/api/breakdown', { def, text, limit, offset }, adapter, schema, options)));
322
+ }
323
+ catch (error) {
324
+ /* A request's own refusal (a ResourceReadError: the provider's are
325
+ stripped of the class before they get here) is said in its item.
326
+ Anything else is the host's to map and, in an App, to keep private,
327
+ so it fails the whole request; the client then asks each alone.
328
+ The rest of the batch is not started: its answer is not sent. */
329
+ if (!(error instanceof ResourceReadError)) {
330
+ queue.length = 0;
331
+ throw error;
332
+ }
333
+ results[next.at] = reply(error.status, { error: error.message });
334
+ }
335
+ }
336
+ };
337
+ await Promise.all(Array.from({ length: Math.min(BREAKDOWN_CONCURRENCY, queue.length) }, one));
338
+ return reply(200, { results });
339
+ }
340
+ /**
341
+ * Run a breakdown: counts and sums, grouped by something.
342
+ *
343
+ * Text in, groups out. The language lives on the server and only on the
344
+ * server — the same rule the query bar and the view composer follow — so
345
+ * the client sends the line somebody typed and gets back the rows, what the
346
+ * columns are, and how many groups there are in total.
347
+ *
348
+ * Errors are a 200 with `errors`, not a 4xx: a half-typed breakdown is the
349
+ * normal state of an input box, and an HTTP error code for it would have
350
+ * the client rendering "request failed" over a message that says which
351
+ * column was misspelled.
352
+ */
353
+ if (path === '/api/breakdown') {
354
+ if (!adapter.runBreakdown) {
355
+ return reply(501, { error: `${schema.dialect} connections cannot group in this build.` });
356
+ }
357
+ /* The structured entry, for page sections: their root filters walk
358
+ dotted paths the text grammar cannot write, so they arrive as the
359
+ BreakdownDef the planner built rather than as text. One that does
360
+ not compile is answered in the language's own error vocabulary —
361
+ the def may also be hand-made, and a hand is a thing that slips. */
362
+ if (body.def && typeof body.def === 'object') {
363
+ const given = weekOf(body.def);
364
+ try {
365
+ const { breakdown: def, result, names, total, offset, } = await readBreakdown(adapter, schema, given, { limit: body.limit, offset: body.offset });
366
+ return sendData(path, {
367
+ breakdown: def,
368
+ columns: result.columns,
369
+ resolved: result.resolved,
370
+ rows: result.rows,
371
+ ...(names ? { names } : {}),
372
+ total,
373
+ offset,
374
+ ms: result.ms,
375
+ sql: result.sql,
376
+ });
377
+ }
378
+ catch (err) {
379
+ // ResourceReadError and the host's former HttpError conversion both
380
+ // receive appError's generic read projection here. Do not promote this
381
+ // structured-entry catch into a new public validation exemption.
382
+ return reply(200, { errors: [app ? app.error(err) : { message: err.message }] });
383
+ }
384
+ }
385
+ const text = String(body.text ?? '');
386
+ const parsed = textToBreakdown(schema, text, { now: options.now(), ...(await personFor(text)) });
387
+ if (!parsed.breakdown)
388
+ return reply(200, { errors: parsed.errors });
389
+ /* Handed on as the structure it parsed to, without its text. An App's
390
+ access layer re-reads any text it is given (text is authoritative
391
+ until materialized), and it has no request clock: it read "next 7
392
+ days" on the wall clock in the server's zone, so the filter rail's
393
+ counts asked about another week than its list did. Without the text,
394
+ the def is checked as a structured one, the way `body.def` is above. */
395
+ const { text: _text, ...materialized } = weekOf(parsed.breakdown);
396
+ const { breakdown: def, result, names, total, offset, } = await readBreakdown(adapter, schema, materialized, { limit: body.limit, offset: body.offset });
397
+ return sendData(path, {
398
+ breakdown: def,
399
+ text: breakdownToText(schema, def),
400
+ /* The workbench-to-config bridge: the same line, already shaped as
401
+ a dashboard section for the copy button in the breakdown head. */
402
+ section: sectionFromText(schema, text),
403
+ columns: result.columns,
404
+ resolved: result.resolved,
405
+ rows: result.rows,
406
+ /* Each reference key's groups by the name of the record they are, as a grid names it. */
407
+ ...(names ? { names } : {}),
408
+ total,
409
+ offset,
410
+ ms: result.ms,
411
+ sql: result.sql,
412
+ /* The same statement with its values written in, for the SQL pane.
413
+ `sql` above keeps the parameterised form, which is what actually ran
414
+ and what anything machine-readable should be reading. */
415
+ explain: explainBreakdown(schema, def, styleFor(schema), offset),
416
+ });
417
+ }
418
+ /**
419
+ * Run a multi-table view: the composer's whole back end.
420
+ * The optional query box overrides the supplied definition, but parse errors
421
+ * must never be papered over with a partial result and a broader filter.
422
+ */
423
+ if (path === '/api/view/run') {
424
+ /* Views historically count exactly. Opting out is deliberately explicit:
425
+ * malformed input must refuse rather than quietly skip a caller's count. */
426
+ const countMode = body.count === undefined ? 'exact' : body.count;
427
+ if (countMode !== 'none' && countMode !== 'exact') {
428
+ return refusal(400, ['count must be "none" or "exact".']);
429
+ }
430
+ if (!adapter.runView) {
431
+ return reply(501, { error: `${schema.dialect} connections cannot run views in this build.` });
432
+ }
433
+ let view = normaliseView(body.view);
434
+ let merged = view;
435
+ const person = await personFor(body.text, body.query);
436
+ const errors = [];
437
+ if (!view.base && typeof body.text !== 'string') {
438
+ return refusal(400, ['A view needs a base table.']);
439
+ }
440
+ /* A view may arrive as text instead of a structure — `work_order show
441
+ reference, customer_id.name as customer count …`. It is the same
442
+ language and the same parser; only the shape of what the client sent
443
+ differs, so it is normalised here and everything below is unchanged. */
444
+ if (typeof body.text === 'string' && body.text.trim()) {
445
+ const parsed = textToView(schema, body.text, { id: view.id, name: view.name, now: options.now(), ...person });
446
+ if (parsed.errors.length || !parsed.view)
447
+ return reply(200, { errors: parsed.errors });
448
+ view = parsed.view;
449
+ merged = parsed.view;
450
+ }
451
+ if (typeof body.query === 'string' && body.query.trim()) {
452
+ const parsed = parseViewQuery(schema, view.base, body.query, options.now(), person);
453
+ errors.push(...parsed.errors);
454
+ merged = {
455
+ ...view,
456
+ filter: parsed.filter.groups.length ? parsed.filter : view.filter,
457
+ /* A `show` clause in the box overrides the checklist, matching how
458
+ `/api/run` lets an explicit column list win. Silently honouring one
459
+ and ignoring the other is the worst of the three options. */
460
+ columns: parsed.columns.length ? parsed.columns.map((p) => ({ path: p })) : view.columns,
461
+ orderBy: parsed.orderBy.length ? parsed.orderBy : view.orderBy,
462
+ limit: parsed.limit ?? view.limit,
463
+ };
464
+ }
465
+ if (errors.length)
466
+ return reply(200, { errors });
467
+ try {
468
+ const { view: validated, result, total, more, limit, offset, } = await readView(adapter, schema, merged, { limit: body.limit, offset: body.offset }, countMode);
469
+ return sendData(path, {
470
+ view: validated,
471
+ text: viewToTextWithSchema(schema, merged),
472
+ total,
473
+ columns: result.columns,
474
+ resolved: result.resolved,
475
+ joins: result.joins,
476
+ rows: result.rows,
477
+ ms: result.ms,
478
+ sql: result.sql,
479
+ explain: explainView(schema, { ...merged, limit }, styleFor(schema)),
480
+ more,
481
+ limit,
482
+ offset,
483
+ errors: [],
484
+ });
485
+ }
486
+ catch (err) {
487
+ if (err instanceof PathError) {
488
+ return refusal(400, [err.message]);
489
+ }
490
+ throw err;
491
+ }
492
+ }
493
+ /* `countLimit`, here and on /api/run, bounds the count (countLimitOf): at
494
+ most that many rows are counted, and past it the answer is the bound with
495
+ `capped`. Absent, the count is the one these routes always gave. */
496
+ if (path === '/api/count') {
497
+ const result = await readCount(adapter, schema, {
498
+ table: String(body.table ?? ''),
499
+ filter: body.filter,
500
+ exact: body.exactCount === true,
501
+ countLimit: body.countLimit,
502
+ });
503
+ return reply(200, {
504
+ count: result.count,
505
+ exact: result.exact,
506
+ ...(result.capped ? { capped: true } : {}),
507
+ });
508
+ }
509
+ return undefined;
510
+ }
511
+ function reply(status, body) {
512
+ return { status, body };
513
+ }
514
+ function refusal(status, messages) {
515
+ return reply(status, { error: messages[0], errors: messages.map((message) => ({ message })) });
516
+ }
517
+ /**
518
+ * Run a view for the query bar, answering in the shape the grid expects.
519
+ *
520
+ * Same keys as `/api/run`'s ordinary answer — `table`, `columns`, `rows`,
521
+ * `total`, `explain` — so the renderer needs no branch. What it gains is
522
+ * `resolved`, which says what each output column actually is; a client that
523
+ * ignores it renders path-named columns as plain text, which is a degradation
524
+ * rather than a break.
525
+ */
526
+ async function runViewForBar(adapter, schema, view, body, app, countMode = 'exact', paging) {
527
+ try {
528
+ const { view: validated, result, total, limit, offset, } = await readView(adapter, schema, paging?.view ?? view, { limit: body.limit, offset: body.offset }, countMode, undefined, paging?.continuation);
529
+ /* A row's value for an order path is under the column that path compiled to. */
530
+ const named = (path) => result.resolved?.find((column) => column.path === path)?.name ?? path;
531
+ const settled = paging ? settlePage(paging.order, paging.extra, result, named) : undefined;
532
+ const dropped = new Set(paging?.extra ?? []);
533
+ const value = {
534
+ table: view.base,
535
+ view: validated,
536
+ text: viewToTextWithSchema(schema, view),
537
+ columns: settled?.columns ?? result.columns,
538
+ resolved: dropped.size ? result.resolved?.filter((column) => !dropped.has(column.path)) : result.resolved,
539
+ joins: result.joins,
540
+ rows: settled?.rows ?? result.rows,
541
+ ...(settled?.bounds ? { bounds: settled.bounds } : {}),
542
+ ...(paging?.continuation ? { keyset: true } : {}),
543
+ ms: result.ms,
544
+ total,
545
+ limit,
546
+ offset,
547
+ explain: explainView(schema, { ...view, limit }, styleFor(schema)),
548
+ errors: [],
549
+ };
550
+ return reply(200, app ? app.reply(value) : value);
551
+ }
552
+ catch (err) {
553
+ if (err instanceof PathError)
554
+ return refusal(400, [err.message]);
555
+ throw err;
556
+ }
557
+ }
558
+ /**
559
+ * Which dialect writes the SQL shown in the explain panel.
560
+ *
561
+ * The adapter picks its own style when it runs the statement; this is the
562
+ * copy the user reads, and it has to agree with what actually ran or the
563
+ * panel is teaching the wrong thing.
564
+ */
565
+ export function styleFor(schema) {
566
+ if (schema.dialect === 'postgres')
567
+ return POSTGRES_STYLE;
568
+ return ANSI_STYLE;
569
+ }
570
+ /**
571
+ * Coerce a JSON body into a `ViewDef`.
572
+ *
573
+ * Shape only. Whether the paths mean anything is `compileView`'s job, and it
574
+ * refuses what it cannot resolve — so this does not need to know the schema,
575
+ * and there is no second, weaker validator to disagree with the first.
576
+ */
577
+ export function normaliseView(raw) {
578
+ const v = (raw ?? {});
579
+ const columns = Array.isArray(v.columns) ? v.columns : [];
580
+ const orderBy = Array.isArray(v.orderBy) ? v.orderBy : [];
581
+ return {
582
+ id: String(v.id ?? ''),
583
+ name: String(v.name ?? ''),
584
+ base: String(v.base ?? '').trim(),
585
+ columns: columns
586
+ .map((c) => typeof c === 'string'
587
+ ? { path: c }
588
+ : { path: String(c?.path ?? ''), alias: c?.alias })
589
+ .filter((c) => c.path),
590
+ aggregates: Array.isArray(v.aggregates) ? v.aggregates : undefined,
591
+ filter: (v.filter ?? undefined),
592
+ orderBy: orderBy
593
+ .map((o) => {
594
+ const entry = o;
595
+ return {
596
+ path: String(entry?.path ?? ''),
597
+ direction: entry?.direction === 'desc' ? 'desc' : 'asc',
598
+ /* A similar list's closest-first order. Only a number passes here,
599
+ and the compiler refuses one that is not finite and safe. */
600
+ ...(typeof entry?.near === 'number' ? { near: entry.near } : {}),
601
+ };
602
+ })
603
+ .filter((o) => o.path),
604
+ limit: typeof v.limit === 'number' ? v.limit : undefined,
605
+ };
606
+ }