@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,472 @@
1
+ import { isIP } from 'node:net';
2
+ import { untrustedDatabaseRefusal } from '../../adapters/net/untrustedDatabase.js';
3
+ import { serverSettings } from '../../adapters/serverSettings.js';
4
+ import { envName, product } from '../product.js';
5
+ /** Split an `…_ALLOWED_HOSTS` value (`TABLEWALK_` or `MISTRI_`, product.ts). Commas or spaces, either way. */
6
+ export function parseHostList(value) {
7
+ return (value ?? '')
8
+ .split(/[,\s]+/)
9
+ .map((s) => s.trim())
10
+ .filter(Boolean);
11
+ }
12
+ /**
13
+ * Refuse a request that another site made on the user's behalf.
14
+ *
15
+ * Binding to loopback keeps tablewalk off the network. It does **not** keep it
16
+ * away from the browser: any page the user has open can `fetch` a localhost
17
+ * port, and while the same-origin policy stops it reading the reply, the
18
+ * request still runs. That was enough to matter here — a page could POST to
19
+ * /api/update and the write would land, on a connection the user never put
20
+ * into write mode, because write mode is a decision the client makes and the
21
+ * server was taking on trust.
22
+ *
23
+ * Three checks, each cheap and each closing a different door:
24
+ *
25
+ * - **Origin.** A cross-origin POST always carries one. Ours never differs
26
+ * from the host we are serving on. A request with no Origin at all is a
27
+ * tool like curl, which is not a confused-deputy risk and is allowed.
28
+ * - **Content-Type.** Requiring JSON makes a cross-origin request
29
+ * non-"simple", so the browser must preflight it — and we answer no CORS
30
+ * headers at all, so the preflight fails before the real request is sent.
31
+ * This is the check that holds even if a browser stops sending Origin.
32
+ * - **Host.** Only loopback names, or the interface actually bound. This is
33
+ * the DNS-rebinding case: an attacker's domain resolving to 127.0.0.1
34
+ * makes their page same-origin with us, and the Origin check would pass.
35
+ * It is the one of the three that runs on reads as well — see
36
+ * `hostRefusal` — because same-origin is exactly what makes a *read*
37
+ * worth doing, and the schema, the DDL and the saved SQL are all reads.
38
+ *
39
+ * No token, no session, no cookie. The browser already tells us everything we
40
+ * need, and inventing a ceremony on top would be more code guarding the same
41
+ * door.
42
+ *
43
+ * The Host check has one deliberate escape hatch, `allowedHosts`. In a
44
+ * container the server binds 0.0.0.0 while the browser sends whatever name the
45
+ * user typed — `tablewalk.internal`, or a reverse proxy's public name — and
46
+ * neither is loopback nor the bound interface, so nothing would be answered at
47
+ * all — a message about a host nobody set, on the page itself. Naming those
48
+ * hosts explicitly is the fix. It is opt-in and empty by default because
49
+ * each entry is a name whose DNS you are now trusting: if an attacker can make
50
+ * a name on this list resolve to your loopback, the rebinding defence is gone
51
+ * for that name. That is a fair trade for a name you chose and a bad one for a
52
+ * wildcard, which is why there is no wildcard.
53
+ */
54
+ const LOOPBACK = /^(localhost|127\.0\.0\.1|\[::1\]|::1)(:\d+)?$/i;
55
+ /** A socket peer on this machine: the operator's terminal, a health check, or a proxy beside the server. */
56
+ function loopbackPeer(address) {
57
+ return /^(127\.0\.0\.1|::1|::ffff:127\.0\.0\.1)$/.test(address ?? '');
58
+ }
59
+ const MAX_FORWARDED_HOPS = 32;
60
+ /**
61
+ * An address as eight 16-bit groups, or undefined. A zone (`%eth0`) is
62
+ * dropped; a trailing dotted quad is the last two groups. Shared with the
63
+ * limiter, which keys an IPv6 client by its first four.
64
+ */
65
+ export function ipv6Groups(address) {
66
+ let text = address.toLowerCase();
67
+ const zone = text.indexOf('%');
68
+ if (zone >= 0)
69
+ text = text.slice(0, zone);
70
+ if (isIP(text) !== 6)
71
+ return undefined;
72
+ const dotted = /(\d+)\.(\d+)\.(\d+)\.(\d+)$/.exec(text);
73
+ if (dotted) {
74
+ const [a, b, c, d] = dotted.slice(1).map(Number);
75
+ text = `${text.slice(0, dotted.index)}${((a << 8) | b).toString(16)}:${((c << 8) | d).toString(16)}`;
76
+ }
77
+ const [head, tail] = text.includes('::') ? text.split('::') : [text, undefined];
78
+ const before = head ? head.split(':') : [];
79
+ const after = tail ? tail.split(':') : [];
80
+ const fill = tail === undefined ? 0 : 8 - before.length - after.length;
81
+ const groups = [...before, ...Array.from({ length: fill }, () => '0'), ...after].map((group) => parseInt(group, 16));
82
+ return groups.length === 8 && groups.every((group) => Number.isInteger(group) && group >= 0 && group <= 0xffff) ? groups : undefined;
83
+ }
84
+ /* IPv4 is held IPv4-mapped (`::ffff:a.b.c.d`), so a dual-stack socket's
85
+ mapped peer and the bare address are one address, and a v4 range is the
86
+ same comparison 96 bits further in. */
87
+ function addressGroups(address) {
88
+ if (isIP(address) === 4) {
89
+ const [a, b, c, d] = address.split('.').map(Number);
90
+ return [0, 0, 0, 0, 0, 0xffff, (a << 8) | b, (c << 8) | d];
91
+ }
92
+ return ipv6Groups(address);
93
+ }
94
+ /**
95
+ * Read `--trust-proxy` and `--auth-proxy-from` values: each an IPv4 or IPv6 address or CIDR range,
96
+ * several to a value when separated by commas or spaces. What is not one is
97
+ * returned by name, for startup to refuse — a list that silently dropped an
98
+ * entry would collapse that proxy's clients into one budget with no word.
99
+ * A zero-length prefix is refused too: it trusts every address, which makes
100
+ * the header anyone's to write.
101
+ */
102
+ export function parseTrustedProxies(values) {
103
+ const ranges = [];
104
+ const invalid = [];
105
+ for (const value of values) {
106
+ const entries = value.split(/[,\s]+/).filter(Boolean);
107
+ if (!entries.length) {
108
+ invalid.push(value);
109
+ continue;
110
+ }
111
+ for (const entry of entries) {
112
+ const [address, bits, extra] = entry.split('/');
113
+ const family = address.includes('%') || extra !== undefined ? 0 : isIP(address);
114
+ const groups = family ? addressGroups(address) : undefined;
115
+ const width = family === 4 ? 32 : 128;
116
+ const prefix = bits === undefined ? width : /^\d{1,3}$/.test(bits) ? Number(bits) : NaN;
117
+ if (!groups || !(prefix >= 1 && prefix <= width)) {
118
+ invalid.push(entry);
119
+ continue;
120
+ }
121
+ ranges.push(Object.freeze({ text: entry, groups: Object.freeze(groups), prefix: family === 4 ? 96 + prefix : prefix }));
122
+ }
123
+ }
124
+ return { ranges, invalid };
125
+ }
126
+ function inRange(groups, range) {
127
+ for (let i = 0, bits = range.prefix; i < 8 && bits > 0; i++, bits -= 16) {
128
+ const mask = (0xffff << (16 - Math.min(16, bits))) & 0xffff;
129
+ if ((groups[i] & mask) !== (range.groups[i] & mask))
130
+ return false;
131
+ }
132
+ return true;
133
+ }
134
+ /**
135
+ * A peer on this machine (`loopbackPeer`, always), or inside a range in the list given. With the `--trust-proxy` list
136
+ * it is a peer whose `X-Forwarded-For` the limiter may read; with the `--auth-proxy-from` list (`Bound.identityProxies`)
137
+ * it is a peer whose `--auth-proxy-header` value `identityFor` believes. The two lists are never swapped: one
138
+ * grants a client address, the other a person.
139
+ */
140
+ export function trustedProxyPeer(address, trusted = []) {
141
+ if (loopbackPeer(address))
142
+ return true;
143
+ if (!trusted.length || !address)
144
+ return false;
145
+ const groups = addressGroups(address);
146
+ return !!groups && trusted.some((range) => inRange(groups, range));
147
+ }
148
+ /** Whether a public address (MISTRI_PUBLIC_URL) is an https one: what `ServerSettings.httpsFront` is set from. */
149
+ export function httpsAddress(url) {
150
+ try {
151
+ return url !== undefined && new URL(url.trim()).protocol === 'https:';
152
+ }
153
+ catch {
154
+ return false;
155
+ }
156
+ }
157
+ /**
158
+ * Whether a request reached this server over https: its socket is TLS; the
159
+ * server is published at an https address (`ServerSettings.httpsFront`), so
160
+ * a TLS front end stood before it; or a proxy it trusts (`trustedProxyPeer`)
161
+ * says in `X-Forwarded-Proto` that it forwarded https. The one rule for a
162
+ * Secure cookie, `Strict-Transport-Security` and the origin a page writes
163
+ * into a sitemap or a link preview (requestOrigin.ts, baselineHeaders.ts,
164
+ * forms/savedForms.ts `secureRequest`).
165
+ */
166
+ export function arrivedOverHttps(req, trusted = []) {
167
+ if (req.socket.encrypted)
168
+ return true;
169
+ if (serverSettings().httpsFront)
170
+ return true;
171
+ const forwarded = String(req.headers['x-forwarded-proto'] ?? '')
172
+ .split(',')[0]
173
+ .trim()
174
+ .toLowerCase();
175
+ return forwarded === 'https' && trustedProxyPeer(req.socket.remoteAddress, trusted);
176
+ }
177
+ /*
178
+ * How to name the client behind a managed front end, whose own address cannot
179
+ * be written into `--trust-proxy` (Cloud Run's, Cloudflare's: a changing pool
180
+ * of Google or Cloudflare addresses). Both are the operator's statement about
181
+ * the deployment, off by default, and settled at startup. The limiters that
182
+ * ask `forwardedClient` are spread across every transport and tenant, so the
183
+ * policy is the server's setting (adapters/serverSettings.ts), read from the
184
+ * scope the request runs in: two handlers in one process each key by their
185
+ * own front end.
186
+ */
187
+ /**
188
+ * Read `--trust-proxy-hops` and `--trust-proxy-cloudflare`. A hop count that
189
+ * is not a whole number from 1 to 32 comes back as an error for startup to
190
+ * print: a mistyped count would collapse every visitor into one budget, or
191
+ * believe a header the client wrote, with no word.
192
+ */
193
+ export function parseClientAddressPolicy(input) {
194
+ let hops;
195
+ if (input.hops !== undefined) {
196
+ if (!/^\d{1,2}$/.test(input.hops.trim()) || Number(input.hops) < 1 || Number(input.hops) > MAX_FORWARDED_HOPS) {
197
+ return {
198
+ error: `--trust-proxy-hops takes a whole number from 1 to ${MAX_FORWARDED_HOPS} (the proxies in front of the server), not "${input.hops}". It comes from the flag or ${envName('TRUST_PROXY_HOPS')}.`,
199
+ };
200
+ }
201
+ hops = Number(input.hops);
202
+ }
203
+ /* Two answers to one question: Cloudflare's header would win where it was sent and a hop count decide where it was
204
+ not, so a request that bypassed Cloudflare would be keyed by a rule the operator never chose for it. */
205
+ if (hops && input.cloudflare) {
206
+ return {
207
+ error: `--trust-proxy-hops and --trust-proxy-cloudflare are two ways to find the client: name one. Cloudflare in front alone, --trust-proxy-cloudflare; another front end, --trust-proxy-hops. They come from the flags or ${envName('TRUST_PROXY_HOPS')} and ${envName('TRUST_PROXY_CLOUDFLARE')}.`,
208
+ };
209
+ }
210
+ return { policy: { ...(hops ? { hops } : {}), ...(input.cloudflare ? { cloudflare: true } : {}) } };
211
+ }
212
+ /**
213
+ * Which client a request is from, for keying a limit — never for authority.
214
+ *
215
+ * With `--trust-proxy-cloudflare`, the `CF-Connecting-IP` header, when it is
216
+ * one address: Cloudflare sets it and replaces any the client sent. Without
217
+ * the flag it is never read, because anyone can write it.
218
+ *
219
+ * With `--trust-proxy-hops N`, the address N places from the right of
220
+ * [socket peer, ...X-Forwarded-For read right to left]: the peer is the first
221
+ * proxy, and each appends the address it saw, so what is left of the Nth is
222
+ * the client's own claim and is dropped. Fewer entries than hops, the
223
+ * furthest. This does not look at who the peer is — that is the point, on a
224
+ * front end with no stable address — so it is for a server reachable only
225
+ * through those hops.
226
+ *
227
+ * Otherwise the socket peer, unless that peer is a trusted proxy (`trustedProxyPeer`:
228
+ * loopback, or an address `--trust-proxy` named): then the client is the
229
+ * nearest `X-Forwarded-For` hop that is not a trusted proxy too. Read from
230
+ * the right, because a proxy appends the address it saw and everything to
231
+ * its left is whatever the client chose to send; each trusted hop passed
232
+ * vouches for the one before it. When every hop is trusted, the furthest is
233
+ * the client. From any other peer the header is not read at all — anyone can
234
+ * write one — and a malformed header is ignored whole rather than
235
+ * half-believed. A proxy on another host that nobody listed is its own
236
+ * address, so its clients share one budget.
237
+ */
238
+ export function forwardedClient(req, trusted = []) {
239
+ const peer = req.socket?.remoteAddress || 'unknown';
240
+ const clientPolicy = serverSettings().clientAddress;
241
+ if (clientPolicy.cloudflare) {
242
+ const cf = req.headers?.['cf-connecting-ip'];
243
+ const address = (Array.isArray(cf) ? cf[0] : cf)?.trim();
244
+ if (address && isIP(address) !== 0)
245
+ return address.toLowerCase();
246
+ }
247
+ if (clientPolicy.hops) {
248
+ const hops = forwardedHops(req.headers?.['x-forwarded-for']);
249
+ if (!hops)
250
+ return peer;
251
+ const chain = [peer, ...hops.reverse()];
252
+ return chain[Math.min(clientPolicy.hops, chain.length - 1)].toLowerCase();
253
+ }
254
+ if (!trustedProxyPeer(peer, trusted))
255
+ return peer;
256
+ const hops = forwardedHops(req.headers?.['x-forwarded-for']);
257
+ if (!hops)
258
+ return peer;
259
+ for (let i = hops.length - 1; i >= 0; i--)
260
+ if (!trustedProxyPeer(hops[i], trusted))
261
+ return hops[i].toLowerCase();
262
+ return hops[0].toLowerCase();
263
+ }
264
+ /** The addresses in an X-Forwarded-For value, or undefined when absent or any entry is not one. */
265
+ function forwardedHops(raw) {
266
+ const header = Array.isArray(raw) ? raw.join(',') : raw;
267
+ if (!header)
268
+ return undefined;
269
+ const hops = header.split(',').map((hop) => hop.trim());
270
+ return hops.length > MAX_FORWARDED_HOPS || hops.some((hop) => isIP(hop) === 0) ? undefined : hops;
271
+ }
272
+ /**
273
+ * Who is asking, when the operator has said which header carries it.
274
+ *
275
+ * `--auth-proxy-header X-Forwarded-User` means a proxy in front signs
276
+ * people in and writes the result into that header on the way through.
277
+ * A request without it did not come through the proxy — or came through
278
+ * one that is misconfigured — and is refused with the header named. So is
279
+ * a request that carries it from a peer that is not the proxy: the header
280
+ * is only a name anyone can type, so a value from an address neither on
281
+ * loopback nor in `--auth-proxy-from` is a forgery, not a sign-in. Loopback is
282
+ * exempt: the container's own health check, a curl on the box, the
283
+ * operator's terminal. Nothing here is authentication; it is the proxy's
284
+ * decision, carried to the journal.
285
+ */
286
+ export function identityFor(req, bound) {
287
+ if (!bound.identityHeader)
288
+ return {};
289
+ const raw = req.headers[bound.identityHeader.toLowerCase()];
290
+ const who = (Array.isArray(raw) ? raw[0] : raw)?.trim();
291
+ const peer = req.socket?.remoteAddress;
292
+ if (who && trustedProxyPeer(peer, bound.identityProxies))
293
+ return { who };
294
+ if (loopbackPeer(peer))
295
+ return { who: 'local' };
296
+ return {
297
+ refusal: who
298
+ ? `This server expects ${bound.identityHeader} only from its proxy, and this request did not come from the trusted proxy. ` +
299
+ "Reach it through the proxy that signs you in; the proxy's address belongs in --auth-proxy-from."
300
+ : `This server expects ${bound.identityHeader} from its proxy, and this request carried none. ` +
301
+ 'Reach it through the proxy that signs you in.',
302
+ };
303
+ }
304
+ /**
305
+ * Whether the browser on this listener is the operator.
306
+ *
307
+ * On loopback with no extra hosts, whoever reaches the port started the
308
+ * process, and the connection form may do what the config file may: reference
309
+ * `${PROD_PASSWORD}`, look a password up in the keychain by name, open a
310
+ * SQLite file by path, choose where the config is saved. Bound wider — or
311
+ * answering to a proxy's name — the browser is anyone on the network, and each
312
+ * of those is a way out: an env reference sends this process's secrets to a
313
+ * host the caller names, a keychain lookup attaches a stored password to the
314
+ * caller's URL, a file path reads any database the server user can, and a
315
+ * save path writes JSON wherever it points. The routes that take a target
316
+ * from the client ask this first and refuse those forms when it says no.
317
+ *
318
+ * Nothing here is authentication. It is the line between "your own machine"
319
+ * and "the network" that the README already draws, applied to the one API
320
+ * that takes a database *address* rather than a query.
321
+ */
322
+ export function clientTrusted(bound) {
323
+ return LOOPBACK.test(bound.host) && !bound.allowedHosts?.length;
324
+ }
325
+ /**
326
+ * Why a connection target from an untrusted client is refused, or null when
327
+ * it is a plain network URL that resolves nothing on this machine. A URL that
328
+ * passes is still dialled sealed, to public addresses only
329
+ * (adapters/net/untrustedDatabase.ts).
330
+ */
331
+ export function untrustedTargetRefusal(target) {
332
+ if (/\$\{?[A-Za-z_]/.test(target)) {
333
+ return ('This server is reachable beyond this machine, so a connection added from the browser cannot ' +
334
+ 'reference environment variables. Put it in the config file on the server, or type the password.');
335
+ }
336
+ if (!/^[a-z][\w+.-]*:\/\//i.test(target) || /^sqlite:/i.test(target)) {
337
+ return ('This server is reachable beyond this machine, so the browser cannot open a SQLite file by ' +
338
+ 'path. Name the file in the config file or on the command line.');
339
+ }
340
+ return untrustedDatabaseRefusal(target);
341
+ }
342
+ /**
343
+ * True when a `Host` header matches one of the extra names we were told to
344
+ * trust.
345
+ *
346
+ * An entry without a port matches the name on any port, because a request
347
+ * through a proxy on 80 or 443 arrives with no port at all and the person
348
+ * writing `--allowed-host tablewalk.internal` means the machine, not one
349
+ * listener on it. An entry *with* a port is taken literally.
350
+ */
351
+ function hostAllowed(host, allowed) {
352
+ const lower = host.toLowerCase();
353
+ const withoutPort = lower.replace(/:\d+$/, '');
354
+ return allowed.some((entry) => {
355
+ const want = entry.trim().toLowerCase();
356
+ if (!want)
357
+ return false;
358
+ return /:\d+$/.test(want) ? lower === want : withoutPort === want;
359
+ });
360
+ }
361
+ /**
362
+ * The `Host` half, on its own, because it has to run on reads too.
363
+ *
364
+ * This was inside `crossOriginRefusal`, which only ever ran for methods that
365
+ * change something. The reasoning was that a read is harmless — and it is
366
+ * wrong, because the attack this check exists to stop is DNS rebinding, and
367
+ * rebinding's whole trick is to make the request *same-origin* so the
368
+ * response can be read. A page on a name the attacker controls, pointed at
369
+ * 127.0.0.1, could `fetch('/api/schema')` and read the answer: every table,
370
+ * every column, every foreign key. `/api/ddl` handed over `CREATE TABLE`.
371
+ * `/api/connections` named the hosts, users and databases. `/api/queries`
372
+ * gave up the saved SQL. All of it, from any page, on any machine where
373
+ * tablewalk happened to be running.
374
+ *
375
+ * Row data was never reachable — reads that take arguments are POSTs, and
376
+ * those were checked. The schema is not nothing.
377
+ *
378
+ * It runs on the static files too, so a rebinding attempt fails at the page
379
+ * rather than one request later. Reaching tablewalk by any name other than
380
+ * loopback has always needed `--allowed-host` for writes to work; this makes
381
+ * that one rule instead of two.
382
+ *
383
+ * It is the first part of `doorRefusal`, which is what a surface calls.
384
+ */
385
+ export function hostRefusal(req, bound) {
386
+ const host = req.headers.host ?? '';
387
+ /* An IPv6 address arrives bracketed in a Host header — `[fe80::1]:4111` —
388
+ and is configured bare; compared as configured, a non-loopback IPv6
389
+ bind could never pass its own check. */
390
+ const expected = `${bound.host.includes(':') && !bound.host.startsWith('[') ? `[${bound.host}]` : bound.host}:${bound.port}`;
391
+ const allowed = bound.allowedHosts ?? [];
392
+ if (!LOOPBACK.test(host) && host !== expected && !hostAllowed(host, allowed)) {
393
+ return (`Refused: this request arrived for host "${host}". ${product()} only answers on ${expected}.` +
394
+ ` Add --allowed-host, or set ${envName('ALLOWED_HOSTS')}, to trust another name.`);
395
+ }
396
+ return null;
397
+ }
398
+ /** Validate a serialized browser Origin, independently of JSON body policy.
399
+ * Missing Origin remains available to non-browser clients. This compares hosts,
400
+ * not the serving socket's scheme: TLS proxies may terminate HTTPS upstream.
401
+ * Full scheme equality needs explicitly trusted external-origin metadata.
402
+ * A part of `doorRefusal`, which is what a surface calls; `ownOrigin` asks it as a question. */
403
+ export function originRefusal(req) {
404
+ const origin = req.headers.origin;
405
+ if (origin !== undefined) {
406
+ let parsed;
407
+ try {
408
+ parsed = new URL(origin);
409
+ }
410
+ catch {
411
+ return `Refused: "${origin}" is not a valid origin.`;
412
+ }
413
+ if (!['http:', 'https:'].includes(parsed.protocol) || parsed.origin !== origin) {
414
+ return `Refused: "${origin}" is not a valid origin.`;
415
+ }
416
+ if (parsed.host !== req.headers.host) {
417
+ return `Refused: a page at ${origin} tried to make this request. ${product()} only accepts requests from its own page.`;
418
+ }
419
+ }
420
+ return null;
421
+ }
422
+ /* Requests a host's page on another origin made with the bearer it was given
423
+ (embed/crossOrigin.ts): that door has checked the Origin against the one
424
+ the bearer was issued to, and replaced the cookies with the bearer's
425
+ session. The Host and the JSON body are still required below. */
426
+ const vouched = new WeakSet();
427
+ /** Mark a request whose Origin the embed door admitted on its bearer. */
428
+ export function vouchForOrigin(req) {
429
+ vouched.add(req);
430
+ }
431
+ /** A write's door, as one sentence or null: `doorRefusal` with `{ writing: true }`. Kept for its unit tests; surfaces call `doorRefusal`. */
432
+ export function crossOriginRefusal(req, bound) {
433
+ return doorRefusal(req, bound, { writing: true })?.error ?? null;
434
+ }
435
+ /** Whether a request can change something: anything but a GET or a HEAD. */
436
+ export function writes(req) {
437
+ return req.method !== 'GET' && req.method !== 'HEAD';
438
+ }
439
+ /** Whether the request's Origin, if it sent one, is this page's (`originRefusal`): a question, not a door. */
440
+ export function ownOrigin(req) {
441
+ return originRefusal(req) === null;
442
+ }
443
+ /**
444
+ * The one door every HTTP surface holds a request to, before it reads
445
+ * anything else of it: the Host (`hostRefusal`, on reads too), then, where
446
+ * `rule` says, the browser's fetch site and the Origin, then a write's JSON
447
+ * body. The gate (gate.ts) asks it twice, either side of the proxy identity
448
+ * and the embed door, because that door decides whether an Origin is vouched
449
+ * for; every other surface asks once.
450
+ */
451
+ export function doorRefusal(req, bound, rule) {
452
+ const wrongHost = hostRefusal(req, bound);
453
+ if (wrongHost)
454
+ return { check: 'host', error: wrongHost };
455
+ const origin = rule.origin ?? 'writes';
456
+ if (origin === 'always' || (origin === 'writes' && rule.writing)) {
457
+ if (rule.sameSite && req.headers['sec-fetch-site'] === 'cross-site')
458
+ return {
459
+ check: 'site',
460
+ error: 'Refused: another site made this request. ' + product() + ' only accepts requests from its own page.',
461
+ };
462
+ const wrongOrigin = origin === 'writes' && vouched.has(req) ? null : originRefusal(req);
463
+ if (wrongOrigin)
464
+ return { check: 'origin', error: wrongOrigin };
465
+ }
466
+ if (rule.writing && (rule.json ?? true) && !jsonBody(req))
467
+ return { check: 'json', error: 'Refused: this endpoint takes application/json.' };
468
+ return null;
469
+ }
470
+ function jsonBody(req) {
471
+ return (req.headers['content-type'] ?? '').split(';')[0].trim().toLowerCase() === 'application/json';
472
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Why a write is refused, apart from the routes that write: data writes
3
+ * (dataWriteRoutes.ts), a record's lines saved with it (formLinesWrite.ts) and
4
+ * an import (importRoutes.ts) all ask it, and the routes import the lines
5
+ * writer, so the question lives in a module of its own rather than closing a
6
+ * loop between them (test/repo/runtime-cycles).
7
+ */
8
+ import type { Registry } from '../connections.js';
9
+ import type { ColumnGrant } from '../columnGrants.js';
10
+ /**
11
+ * How a product says a refused write in its own words: an App answers for
12
+ * the connections it serves (app/apps.ts `appWriteWording`), and says
13
+ * nothing of the config file to the person using it. Absent, or undefined
14
+ * for a connection, the database browser's words are said.
15
+ */
16
+ export type WriteWording = (connection: string, name: string | undefined) => {
17
+ readonly readOnly: string;
18
+ denied(tableId: string | undefined, readable: boolean): string;
19
+ } | undefined;
20
+ /**
21
+ * Why a write to `connection` (and `tableId`, when the write names one) is
22
+ * refused, or null. Two gates in one sentence: the connection's `writable`
23
+ * flag, then the grant's write scope — narrower than the connection's, never
24
+ * wider. The message names the file and the field, because the person who
25
+ * hits this is usually the person who can change it.
26
+ */
27
+ export declare function writeRefusal(registry: Registry, wording: WriteWording | undefined, connection: string, tableId: string | undefined, resources?: {
28
+ connectionFor(table: string): string;
29
+ }, access?: ColumnGrant & {
30
+ readonly actions?: ReadonlyMap<string, unknown>;
31
+ },
32
+ /** An update (or its Undo) may reach a table where a role runs fixed actions without write; the facade judges which. */
33
+ update?: boolean): string | null;
@@ -0,0 +1,24 @@
1
+ import { configFileName } from '../product.js';
2
+ /**
3
+ * Why a write to `connection` (and `tableId`, when the write names one) is
4
+ * refused, or null. Two gates in one sentence: the connection's `writable`
5
+ * flag, then the grant's write scope — narrower than the connection's, never
6
+ * wider. The message names the file and the field, because the person who
7
+ * hits this is usually the person who can change it.
8
+ */
9
+ export function writeRefusal(registry, wording, connection, tableId, resources, access,
10
+ /** An update (or its Undo) may reach a table where a role runs fixed actions without write; the facade judges which. */
11
+ update = false) {
12
+ const owner = tableId && resources ? resources.connectionFor(tableId) : connection;
13
+ const config = registry.configOf(owner);
14
+ const said = wording?.(connection, registry.configOf(connection)?.name);
15
+ if (!config?.writable) {
16
+ if (said)
17
+ return said.readOnly;
18
+ return (`"${config?.name ?? connection}" is read-only. ` + `Add "writable": true to its entry in your ${configFileName()} to allow edits.`);
19
+ }
20
+ if (access && !access.writable.has(tableId ?? '') && !(update && access.actions?.has(tableId ?? ''))) {
21
+ return said ? said.denied(tableId, tableId !== undefined && access.readable.has(tableId)) : 'Access to this resource is denied.';
22
+ }
23
+ return null;
24
+ }
@@ -0,0 +1,49 @@
1
+ import { HttpAdapter } from '../adapters/http/httpAdapter.js';
2
+ import { type HttpDescription } from '../adapters/http/httpDescription.js';
3
+ import type { CacheStore } from '../adapters/cache/cacheStore.js';
4
+ import type { SecretSource } from '../shared/connection.js';
5
+ /** As written in the config file: either a bearer token or one named header, `${VAR}` references intact. */
6
+ export type HttpAuthConfig = {
7
+ bearer: string;
8
+ } | {
9
+ header: string;
10
+ value: string;
11
+ };
12
+ export interface HttpConnectionConfig {
13
+ /** The description file as written, relative to the config file, or the description itself; written back as it is on save. */
14
+ description: string | HttpDescription;
15
+ /** A description file, resolved against the config file's directory. */
16
+ descriptionPath?: string;
17
+ auth?: HttpAuthConfig;
18
+ /** Plain `http:` to the API. */
19
+ insecure?: boolean;
20
+ /** Link-local addresses, where cloud metadata answers. */
21
+ allowLinkLocal?: boolean;
22
+ /** Reads answered from the cache for `ttl` seconds after the API answered them. */
23
+ cache?: {
24
+ ttl: number;
25
+ };
26
+ }
27
+ /**
28
+ * An entry's HTTP fields, checked: the resolved block for an `http`
29
+ * connection, undefined for a database. Throws naming the field, because a
30
+ * config someone wrote is refused rather than half-read. Service kinds
31
+ * (`cache`, `webhook`, …) are read by serviceConnections.ts before this is asked.
32
+ */
33
+ export declare function httpConnectionOf(entry: Record<string, unknown>, path: string): HttpConnectionConfig | undefined;
34
+ /**
35
+ * Open an HTTP connection: read its description, resolve its credential and
36
+ * hand both to the adapter. `secrets: false` — a URL a browser supplied —
37
+ * opens without the credential rather than sending it to that URL, and
38
+ * without the cache: an answer fetched for one URL is not kept under a name
39
+ * another URL could be given.
40
+ */
41
+ export declare function openHttp(name: string, url: string, http: HttpConnectionConfig, options: {
42
+ secrets: boolean;
43
+ cache?: CacheStore;
44
+ environment?: NodeJS.ProcessEnv;
45
+ }): Promise<{
46
+ adapter: HttpAdapter;
47
+ secret: SecretSource;
48
+ warning?: string;
49
+ }>;