@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,323 @@
1
+ /**
2
+ * Evidence: capturing what a caller handed in as frozen plain data, and
3
+ * failing closed when it cannot be trusted.
4
+ *
5
+ * It lived in `src/server/tenant/` because tenancy is where it was first
6
+ * needed, and 27 modules outside tenancy ended up importing tenancy for it —
7
+ * `auth/`, `app/`, `cli/`, `commands/` and every non-tenant `api/` file — which
8
+ * made a folder boundary unreadable: almost every arrow into tenant/ was this
9
+ * one file. Nothing in it is tenant-specific. It stays under `src/server/`
10
+ * rather than `src/shared/` because it reads `node:util/types` and the
11
+ * adapters' outcome error, neither of which the client may carry.
12
+ *
13
+ * The names are unchanged, tenant spelling and all: they are what the refusal
14
+ * path reads as, and renaming them would have made one mechanical move into a
15
+ * diff nobody could review.
16
+ */
17
+ import { isProxy, isUint8Array } from 'node:util/types';
18
+ import { TransactionOutcomeUnknown } from '../adapters/adapter.js';
19
+ import { PoolBusy } from '../adapters/poolMetrics.js';
20
+ import { Refusal, recordRefusalCause, refusalCause } from '../shared/refusal.js';
21
+ import { isCapturedScopeCatalog } from '../shared/scopeCatalog.js';
22
+ import { keepBreakdownsAgainst } from '../shared/breakdown.js';
23
+ import { isRowScopeSnapshot } from '../shared/rowScope.js';
24
+ import { carryServerRequest } from './serverRequests.js';
25
+ /** Private admission errors reveal neither membership existence nor provider data. */
26
+ export class TenantContextError extends Error {
27
+ code = 'tenant_context_unavailable';
28
+ constructor() {
29
+ super('The tenant context could not be verified.');
30
+ this.name = 'TenantContextError';
31
+ }
32
+ }
33
+ /* The recorded reason behind every opaque refusal lives with the refusal
34
+ class itself (shared/refusal.ts), so an adapter's scope check records one
35
+ the same way a tenant denial does. */
36
+ export { recordRefusalCause, refusalCause, refusalHeadline, refusalReasons, refusalReasonsBelow } from '../shared/refusal.js';
37
+ export const denyTenant = (cause) => {
38
+ throw recordRefusalCause(new TenantContextError(), cause);
39
+ };
40
+ /** The database could not answer, so authority was never decided: not a
41
+ * refusal. Still a TenantContextError — every consumer that denies on one
42
+ * still denies — and carries no `cause`, so no driver text travels with it
43
+ * (the driver's error is recorded for the operator, as any refusal's is).
44
+ * Only an owner that answers a caller tells the two apart (503, not 403). */
45
+ export class TenantUnavailableError extends TenantContextError {
46
+ code = 'tenant_temporarily_unavailable';
47
+ }
48
+ const NETWORK = new Set(['ECONNREFUSED', 'ECONNRESET', 'EPIPE', 'ETIMEDOUT', 'EHOSTUNREACH', 'ENETUNREACH', 'ENOTFOUND', 'EAI_AGAIN']);
49
+ /* Recognized positively. Every refusal in the tenant path is a
50
+ TenantContextError, and anything unrecognized denies, so a new failure
51
+ shape can only ever be answered as a refusal, never as a fault that hides
52
+ one. */
53
+ export function databaseFault(error) {
54
+ if (error instanceof TenantUnavailableError)
55
+ return true;
56
+ if (error instanceof TenantContextError || !(error instanceof Error))
57
+ return false;
58
+ if (error instanceof TransactionOutcomeUnknown)
59
+ return true;
60
+ /* A pool that would not lend a connection in time (poolMetrics.ts): nothing
61
+ was leased, so nothing was asked. Under load this is the commonest fault
62
+ there is, and answered as a denial it told a person their tenant context
63
+ was gone because the server was busy (a field report: 403s on reads at
64
+ twelve users on half a core). */
65
+ if (error instanceof PoolBusy)
66
+ return true;
67
+ // A check refused because the engine could not answer (the SQLite catalog
68
+ // scan): the cause, one level deep and itself a raw driver error, decides.
69
+ if (error instanceof Refusal)
70
+ return !(error.cause instanceof Refusal) && databaseFault(error.cause);
71
+ const { code, severity } = error;
72
+ // node:sqlite: busy, locked, I/O, a missing or unreadable file.
73
+ if (code === 'ERR_SQLITE_ERROR')
74
+ return true;
75
+ if (typeof code === 'string' && NETWORK.has(code))
76
+ return true;
77
+ /* An integrity rule the database enforced (class 23: a key already taken, a
78
+ reference to nothing, a required value, a check) is the database answering,
79
+ and refusing: permanent for that write, and never a reason to try again.
80
+ Counted as unanswered, a duplicate key was told "try again" with a
81
+ Retry-After (a live load test). Every write route answers it as the refusal
82
+ it is (constraints.ts writeRefusalStatus). A data exception (class 22) stays
83
+ below on purpose: on a tenant read it is a filter value its column cannot
84
+ hold, and a denial there would end the person's context; a write route
85
+ recognizes it before asking this (tenantWriteFault.ts). */
86
+ if (typeof severity === 'string' && typeof code === 'string' && code.startsWith('23'))
87
+ return false;
88
+ // pg's DatabaseError: a server-reported SQLSTATE (a terminated backend, a
89
+ // database refusing connections, a cancelled or timed-out statement).
90
+ if (typeof severity === 'string' && typeof code === 'string' && /^[0-9A-Z]{5}$/.test(code))
91
+ return true;
92
+ // pg's own connection errors, and this pool's, carry no code.
93
+ return /^(?:Connection terminated|Client has encountered a connection error|Client was closed|timeout exceeded when trying to connect|Observed PostgreSQL checkout is unavailable|Postgres connection manager is closed)/.test(error.message);
94
+ }
95
+ /** The request's own fault, said to the caller as that, not as the context's
96
+ * denial: no record this context reads has the key (`not_found`, the same for
97
+ * one that is missing and one that is another tenant's), or a read that cannot
98
+ * be answered as asked (`invalid_read`). The context read and decided
99
+ * nothing to its detriment, and revalidates before this is let out
100
+ * (tenantReadRuntime.ts), so the session that asked keeps going. It carries
101
+ * no data: its words are fixed here. */
102
+ export class TenantRequestFault extends Error {
103
+ status;
104
+ code;
105
+ constructor(status, code) {
106
+ super(code === 'not_found' ? 'No such record.' : 'This read cannot be answered.');
107
+ this.status = status;
108
+ this.code = code;
109
+ this.name = 'TenantRequestFault';
110
+ }
111
+ }
112
+ /**
113
+ * Whether the database not answering is what failed, under however many
114
+ * refusals and failures it was recorded: a tenant write's failure is
115
+ * value-free on purpose and keeps what failed beneath it, and a read that
116
+ * waited on that write (an inbox's mail) refuses with it as its cause. Read
117
+ * positively, as `databaseFault` is, and a denial anywhere on the way down
118
+ * stays a denial: it decided something, whatever lies beneath it.
119
+ */
120
+ export function databaseUnanswered(error) {
121
+ let at = error;
122
+ for (let depth = 0; at !== null && typeof at === 'object' && depth < 16; depth++) {
123
+ if (databaseFault(at))
124
+ return true;
125
+ if (at instanceof TenantContextError)
126
+ return false;
127
+ at = refusalCause(at) ?? (at instanceof Error ? at.cause : undefined);
128
+ }
129
+ return false;
130
+ }
131
+ /** Deny, unless the cause is the database failing to answer: then the tenant
132
+ * context is unavailable. Fails closed either way. */
133
+ export const denyTenantFor = (cause) => {
134
+ throw recordRefusalCause(databaseUnanswered(cause) ? new TenantUnavailableError() : new TenantContextError(), cause);
135
+ };
136
+ const capturedData = new WeakMap();
137
+ /* A scope catalog (shared/scopeCatalog.ts) is detached, validated and deeply
138
+ frozen plain data too; its cost is measured once, without copying it. So is
139
+ a row scope snapshotRowScope made (shared/rowScope.ts): a tenant read hands
140
+ its request's scope through several captures, and each copied it whole. */
141
+ const catalogCosts = new WeakMap();
142
+ function catalogCost(value) {
143
+ let cost = catalogCosts.get(value);
144
+ if (cost)
145
+ return cost;
146
+ cost = { nodes: 0, characters: 0, depth: 0 };
147
+ const walk = (node, depth) => {
148
+ cost.nodes++;
149
+ if (depth > cost.depth)
150
+ cost.depth = depth;
151
+ if (typeof node === 'string')
152
+ cost.characters += node.length;
153
+ else if (node && typeof node === 'object')
154
+ for (const key of Object.keys(node)) {
155
+ if (!Array.isArray(node))
156
+ cost.characters += key.length;
157
+ walk(node[key], depth + 1);
158
+ }
159
+ };
160
+ walk(value, 0);
161
+ catalogCosts.set(value, cost);
162
+ return cost;
163
+ }
164
+ /* A caller's value frozen all the way down — every object and array in it frozen as given, plain data with no
165
+ accessor (a copy refuses one) and no proxy — is one nothing can change either: freezing cannot be undone, and a
166
+ frozen object's values cannot be swapped. A policy's row scope is such a constant (`Object.freeze({ lead: true,
167
+ … })`), handed back on every request and copied afresh by each, so every request's scope was new data and nothing
168
+ keyed by it was ever found again (tenantReadScope.ts). Its capture is kept with it, and reused as a captured value
169
+ is: same object, same cost charged. */
170
+ const frozenCaptures = new WeakMap();
171
+ /** Test-only: how many objects and arrays captures have copied, as opposed to reused. */
172
+ export const captureCounters = { copied: 0 };
173
+ /** Whether a value is one captureTenantData froze all the way down, or a
174
+ * captured scope catalog: data that cannot change for as long as it lives, so
175
+ * an answer derived from it alone may be kept with it (a WeakMap keyed by it)
176
+ * and is gone when it is. A reload captures new values and starts afresh. */
177
+ export function isCapturedTenantData(value) {
178
+ return value !== null && typeof value === 'object' && (capturedData.has(value) || isCapturedScopeCatalog(value));
179
+ }
180
+ /* A breakdown compiled against such a catalog is kept with it (breakdown.ts compileBreakdown): a served tenant
181
+ catalog is one, and an enter compiles each of its breakdowns against it for the access check and the SQL pane. */
182
+ keepBreakdownsAgainst(isCapturedTenantData);
183
+ /** Server evidence is data, never getters, proxies, thenables or inherited grants. */
184
+ export function captureTenantData(input) {
185
+ /* A capture handed back whole is itself, within every bound by having been
186
+ made within them: answered before the walk's state is set up, since a
187
+ request hands the same evidence through dozens of these. */
188
+ if (input !== null && typeof input === 'object' && capturedData.has(input))
189
+ return carryServerRequest(input, input);
190
+ let nodes = 0, characters = 0, reach = 0, bytes = 0,
191
+ /* Objects copied that were not frozen as given: a subtree with none is the caller's constant. */
192
+ thawed = 0;
193
+ const reuse = (value, depth) => {
194
+ const cost = capturedData.get(value) ??
195
+ (isCapturedScopeCatalog(value) || isRowScopeSnapshot(value) ? catalogCost(value) : undefined);
196
+ if (!cost)
197
+ return undefined;
198
+ // Exactly the counts a fresh copy of this value would have added.
199
+ if ((nodes += cost.nodes) > 262_144 || depth + cost.depth > 24 || (characters += cost.characters) > 16_777_216)
200
+ return denyTenant();
201
+ if (depth + cost.depth > reach)
202
+ reach = depth + cost.depth;
203
+ return value;
204
+ };
205
+ const copy = (value, depth = 0) => {
206
+ if (value !== null && typeof value === 'object' && !isProxy(value)) {
207
+ const kept = reuse(frozenCaptures.get(value) ?? value, depth);
208
+ if (kept !== undefined)
209
+ return kept;
210
+ }
211
+ if (++nodes > 262_144 || depth > 24)
212
+ return denyTenant();
213
+ if (depth > reach)
214
+ reach = depth;
215
+ if (value === undefined || value === null || typeof value === 'boolean')
216
+ return value;
217
+ if (typeof value === 'number')
218
+ return Number.isFinite(value) ? value : denyTenant();
219
+ if (typeof value === 'string') {
220
+ if ((characters += value.length) > 16_777_216)
221
+ return denyTenant();
222
+ return value;
223
+ }
224
+ if (typeof value !== 'object' || isProxy(value))
225
+ return denyTenant();
226
+ /* A file's bytes (a file resource's content column, read or written): a
227
+ genuine byte array, copied, so nothing the caller still holds changes
228
+ what was captured. Counted against the same budget as text. */
229
+ if (isUint8Array(value)) {
230
+ const copied = Buffer.from(value);
231
+ bytes++;
232
+ if ((characters += copied.byteLength) > 16_777_216)
233
+ return denyTenant();
234
+ return copied;
235
+ }
236
+ const array = Array.isArray(value), prototype = Object.getPrototypeOf(value);
237
+ if (array ? prototype !== Array.prototype : prototype !== null && prototype !== Object.prototype)
238
+ return denyTenant();
239
+ const keys = Reflect.ownKeys(value);
240
+ if (keys.length > 65_537)
241
+ return denyTenant();
242
+ captureCounters.copied++;
243
+ const before = { nodes: nodes - 1, characters, reach, bytes, thawed };
244
+ // Counted after `before`: the value itself must have been frozen too, not only what it holds.
245
+ if (!Object.isFrozen(value))
246
+ thawed++;
247
+ reach = depth;
248
+ let result;
249
+ if (array) {
250
+ const length = Object.getOwnPropertyDescriptor(value, 'length')?.value;
251
+ if (!Number.isInteger(length) || length > 65_536 || keys.length !== length + 1)
252
+ return denyTenant();
253
+ result = Object.freeze(Array.from({ length }, (_, index) => {
254
+ const descriptor = Object.getOwnPropertyDescriptor(value, String(index));
255
+ if (!descriptor?.enumerable || !('value' in descriptor))
256
+ return denyTenant();
257
+ return copy(descriptor.value, depth + 1);
258
+ }));
259
+ }
260
+ else {
261
+ const record = Object.create(null);
262
+ for (const key of keys) {
263
+ if (typeof key !== 'string' || (characters += key.length) > 16_777_216)
264
+ return denyTenant();
265
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
266
+ if (!descriptor?.enumerable || !('value' in descriptor))
267
+ return denyTenant();
268
+ record[key] = copy(descriptor.value, depth + 1);
269
+ }
270
+ result = Object.freeze(record);
271
+ }
272
+ if (bytes === before.bytes) {
273
+ capturedData.set(result, {
274
+ nodes: nodes - before.nodes,
275
+ characters: characters - before.characters,
276
+ depth: reach - depth,
277
+ });
278
+ if (thawed === before.thawed)
279
+ frozenCaptures.set(value, result);
280
+ }
281
+ reach = Math.max(reach, before.reach);
282
+ return result;
283
+ };
284
+ try {
285
+ // A request the server built for a file's own columns stays the server's through the copy (serverRequests.ts).
286
+ return carryServerRequest(input, copy(input));
287
+ }
288
+ catch {
289
+ return denyTenant();
290
+ }
291
+ }
292
+ export function tenantRecord(value, fields) {
293
+ if (!value || typeof value !== 'object' || Array.isArray(value) || (fields && Object.keys(value).some((key) => !fields.includes(key))))
294
+ denyTenant();
295
+ }
296
+ export function tenantIdentifier(value, maximum = 256) {
297
+ if (typeof value !== 'string' || !value.length || value.length > maximum || value !== value.trim() || /\p{Cc}/u.test(value))
298
+ denyTenant();
299
+ }
300
+ /** Trusted callbacks are captured without invoking configuration accessors. */
301
+ export function tenantOptions(input, fields) {
302
+ if (!input || typeof input !== 'object' || isProxy(input) || Array.isArray(input))
303
+ return denyTenant();
304
+ const prototype = Object.getPrototypeOf(input);
305
+ if (prototype !== null && prototype !== Object.prototype)
306
+ return denyTenant();
307
+ const result = Object.create(null);
308
+ const keys = Reflect.ownKeys(input);
309
+ /* The refusal names the key it did not expect: a loader that grows a key
310
+ (an App's pageFiles did) otherwise stops every tenant start with only
311
+ "the tenant context could not be verified". Recorded for the operator's
312
+ reader alone, and cut short, since the key is the caller's text. */
313
+ const unknown = keys.find((key) => typeof key !== 'string' || !fields.includes(key));
314
+ if (unknown !== undefined)
315
+ return denyTenant(`"${String(unknown).slice(0, 64)}" is not a key this takes; it takes ${fields.join(', ')}.`);
316
+ for (const key of keys) {
317
+ const descriptor = Object.getOwnPropertyDescriptor(input, key);
318
+ if (!descriptor?.enumerable || !('value' in descriptor))
319
+ return denyTenant();
320
+ result[key] = descriptor.value;
321
+ }
322
+ return result;
323
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * A connection that never hands out some of its columns.
3
+ *
4
+ * `"hidden": { "account": ["password_hash"], "*": ["*_token"] }` in
5
+ * tablewalk.json keeps those columns from everything served over the
6
+ * connection: the Workbench, MCP, and every App on it. It is enforced where
7
+ * `"rows": false` is (shapeonly.ts), by wrapping the adapter before the
8
+ * registry stores it, so a feature added later inherits the boundary instead
9
+ * of having to remember it.
10
+ *
11
+ * The checks are the App grants' own (resourceChecks in columnGrants.ts):
12
+ * the catalog is served without the columns, so a query, a view, a filter or
13
+ * a sort that names one is refused as naming a column that is not there, and
14
+ * a read that names no columns gets the visible ones, never `SELECT *`.
15
+ * Raw SQL is refused outright: a statement cannot be column-redacted
16
+ * honestly. The strongest form of this boundary is still the database's own:
17
+ * a role without SELECT on those columns, which no tablewalk bug can undo.
18
+ */
19
+ import { type Adapter } from '../adapters/adapter.js';
20
+ import { type DatabaseSchema } from '../shared/schema.js';
21
+ /** Table (id, bare name or "*") → column names, `*` a wildcard within a name. As written in tablewalk.json. */
22
+ export type HiddenColumnRules = Readonly<Record<string, readonly string[]>>;
23
+ /** The rules as the config file must spell them, refused with the file's own words otherwise. */
24
+ export declare function parseHiddenColumns(raw: unknown, where: string): HiddenColumnRules;
25
+ /** The catalog as served: the columns gone, and every edge, index and list naming one. */
26
+ export declare function withoutHiddenColumns(schema: DatabaseSchema, rules: HiddenColumnRules, name: string): DatabaseSchema;
27
+ /**
28
+ * The same adapter with the rules' columns cut from every answer and refused
29
+ * in every question. Methods are copied, not proxied, so an optional one the
30
+ * adapter lacks stays absent (shapeonly.ts says why).
31
+ */
32
+ export declare function hideColumns(adapter: Adapter, name: string, rules: HiddenColumnRules, introspected: DatabaseSchema): Adapter;
@@ -0,0 +1,238 @@
1
+ /**
2
+ * A connection that never hands out some of its columns.
3
+ *
4
+ * `"hidden": { "account": ["password_hash"], "*": ["*_token"] }` in
5
+ * tablewalk.json keeps those columns from everything served over the
6
+ * connection: the Workbench, MCP, and every App on it. It is enforced where
7
+ * `"rows": false` is (shapeonly.ts), by wrapping the adapter before the
8
+ * registry stores it, so a feature added later inherits the boundary instead
9
+ * of having to remember it.
10
+ *
11
+ * The checks are the App grants' own (resourceChecks in columnGrants.ts):
12
+ * the catalog is served without the columns, so a query, a view, a filter or
13
+ * a sort that names one is refused as naming a column that is not there, and
14
+ * a read that names no columns gets the visible ones, never `SELECT *`.
15
+ * Raw SQL is refused outright: a statement cannot be column-redacted
16
+ * honestly. The strongest form of this boundary is still the database's own:
17
+ * a role without SELECT on those columns, which no tablewalk bug can undo.
18
+ */
19
+ import { Refusal } from '../adapters/adapter.js';
20
+ import { CONNECTION_HIDDEN } from '../shared/schema.js';
21
+ import { AppAccessDenied, accessibleSchema, authorizeColumnWrites, resourceChecks } from './columnGrants.js';
22
+ import { lendWriteView } from '../adapters/storeHost.js';
23
+ import { configFileName } from './product.js';
24
+ /** The rules as the config file must spell them, refused with the file's own words otherwise. */
25
+ export function parseHiddenColumns(raw, where) {
26
+ const shape = `"hidden" must be an object of table → column names, like { "account": ["password_hash"], "*": ["*_token"] }`;
27
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw) || !Object.keys(raw).length)
28
+ throw new Error(`${where}: ${shape}.`);
29
+ for (const [table, columns] of Object.entries(raw)) {
30
+ if (!table.trim() ||
31
+ !Array.isArray(columns) ||
32
+ !columns.length ||
33
+ columns.some((column) => typeof column !== 'string' || !column.trim() || /^\*+$/.test(column.trim()))) {
34
+ throw new Error(`${where}: "hidden" for "${table}" is not a list of column names (a "*" matches within a name, never a whole table). ${shape}.`);
35
+ }
36
+ }
37
+ return raw;
38
+ }
39
+ const matcher = (pattern) => new RegExp(`^${pattern
40
+ .trim()
41
+ .split('*')
42
+ .map((part) => part.replace(/[.+?^${}()|[\]\\]/g, '\\$&'))
43
+ .join('.*')}$`, 'i');
44
+ /** Each table's cut columns under the rules, by table id; a primary key is refused, since every link to a record carries it. */
45
+ function hiddenByTable(schema, rules, name) {
46
+ const patterns = Object.entries(rules).map(([table, columns]) => ({ table, columns: columns.map(matcher) }));
47
+ const cuts = new Map();
48
+ for (const table of schema.tables) {
49
+ const applying = patterns.filter((rule) => rule.table === '*' || rule.table === table.id || rule.table === table.name);
50
+ const cut = table.columns.filter((column) => applying.some((rule) => rule.columns.some((pattern) => pattern.test(column.name))));
51
+ const key = cut.find((column) => column.primaryKey);
52
+ if (key) {
53
+ throw new Error(`"${name}" has "hidden" covering ${table.id}.${key.name}, part of a primary key: every link to a record carries it. ` +
54
+ `Narrow the pattern in your ${configFileName()}.`);
55
+ }
56
+ if (cut.length)
57
+ cuts.set(table.id, new Set(cut.map((column) => column.name)));
58
+ }
59
+ return cuts;
60
+ }
61
+ /** Every table read and written as the connection allows, minus the cut columns, as one grant. */
62
+ function grantOf(schema, cuts) {
63
+ const all = new Set(schema.tables.map((table) => table.id));
64
+ return {
65
+ readable: all,
66
+ writable: all,
67
+ fields: new Map([...cuts].map(([id, cut]) => {
68
+ const visible = schema.tables
69
+ .find((table) => table.id === id)
70
+ .columns.map((column) => column.name)
71
+ .filter((column) => !cut.has(column));
72
+ return [id, { read: new Set(visible), write: new Set(visible) }];
73
+ })),
74
+ };
75
+ }
76
+ /** The catalog as served: the columns gone, and every edge, index and list naming one. */
77
+ export function withoutHiddenColumns(schema, rules, name) {
78
+ const cuts = hiddenByTable(schema, rules, name);
79
+ if (!cuts.size)
80
+ return schema;
81
+ const pruned = accessibleSchema(schema, grantOf(schema, cuts));
82
+ const keep = (id, columns) => columns?.filter((column) => !cuts.get(id)?.has(column));
83
+ return {
84
+ ...pruned,
85
+ tables: pruned.tables.map((table) => {
86
+ // accessibleSchema narrows `deletable` where a field map exists; a connection's deletes stay its own to judge.
87
+ const original = schema.tables.find((item) => item.id === table.id);
88
+ const { deletable: _deletable, ...rest } = table;
89
+ // Likewise each column's `writable`: the grant says nothing about writes here.
90
+ const columns = table.columns.map((column) => {
91
+ const { writable: _writable, ...said } = column;
92
+ const was = original.columns.find((item) => item.name === column.name);
93
+ return was.writable !== undefined ? { ...said, writable: was.writable } : said;
94
+ });
95
+ const cut = cuts.get(table.id);
96
+ return {
97
+ ...rest,
98
+ columns,
99
+ ...(cut ? { [CONNECTION_HIDDEN]: [...cut] } : {}),
100
+ ...(original.deletable !== undefined ? { deletable: original.deletable } : {}),
101
+ ...(table.filterable ? { filterable: keep(table.id, table.filterable) } : {}),
102
+ ...(table.sortable ? { sortable: keep(table.id, table.sortable) } : {}),
103
+ };
104
+ }),
105
+ };
106
+ }
107
+ /**
108
+ * The same adapter with the rules' columns cut from every answer and refused
109
+ * in every question. Methods are copied, not proxied, so an optional one the
110
+ * adapter lacks stays absent (shapeonly.ts says why).
111
+ */
112
+ export function hideColumns(adapter, name, rules, introspected) {
113
+ const refused = (what) => new Refusal(`"${name}" hides columns ("hidden" in your ${configFileName()}): ${what}. ` +
114
+ 'The hidden columns are not in its catalog, so nothing can ask for them.');
115
+ let full = introspected;
116
+ let cuts = hiddenByTable(full, rules, name);
117
+ let checks = resourceChecks(full, grantOf(full, cuts));
118
+ const refresh = (schema) => {
119
+ full = schema;
120
+ cuts = hiddenByTable(full, rules, name);
121
+ checks = resourceChecks(full, grantOf(full, cuts));
122
+ };
123
+ /* A grant's refusal is deliberately opaque to an App's reader; here the
124
+ person asking owns the config, so it says which boundary answered. */
125
+ const checked = (check) => {
126
+ try {
127
+ return check();
128
+ }
129
+ catch (error) {
130
+ if (error instanceof AppAccessDenied)
131
+ throw refused('this request names a hidden column, or would return one');
132
+ throw error;
133
+ }
134
+ };
135
+ const from = (key) => {
136
+ const method = adapter[key];
137
+ return typeof method === 'function' ? method.bind(adapter) : undefined;
138
+ };
139
+ const authorized = (tx) => {
140
+ const inner = authorizeColumnWrites(full, grantOf(full, cuts), tx);
141
+ const guard = (run) => (...args) => {
142
+ try {
143
+ return run(...args).catch((error) => {
144
+ throw error instanceof AppAccessDenied ? refused('this write names a hidden column, or would return or remove one') : error;
145
+ });
146
+ }
147
+ catch (error) {
148
+ return Promise.reject(error instanceof AppAccessDenied ? refused('this write names a hidden column, or would return or remove one') : error);
149
+ }
150
+ };
151
+ return {
152
+ ...(inner.lockRecord ? { lockRecord: guard(inner.lockRecord) } : {}),
153
+ query: guard(inner.query),
154
+ count: guard(inner.count),
155
+ insert: guard(inner.insert),
156
+ update: guard(inner.update),
157
+ remove: guard(inner.remove),
158
+ ...(inner.tell ? { tell: guard(inner.tell) } : {}),
159
+ };
160
+ };
161
+ const reads = (bound) => ({
162
+ query: (request) => bound.query(checked(() => checks.queryFor(request))),
163
+ count: (table, filter, limit) => bound.count(table, checked(() => checks.filterFor(table, filter)), limit),
164
+ runView: (view, offset) => bound.runView(checked(() => checks.viewFor(view)), offset),
165
+ countView: (view, limit) => bound.countView(checked(() => checks.viewFor(view)), limit),
166
+ runBreakdown: (def, offset) => bound.runBreakdown(checked(() => checks.breakdownFor(def)), offset),
167
+ countBreakdown: (def, limit) => bound.countBreakdown(checked(() => checks.breakdownFor(def)), limit),
168
+ });
169
+ const wrapped = Object.create(Object.getPrototypeOf(adapter));
170
+ Object.assign(wrapped, adapter);
171
+ wrapped.close = from('close');
172
+ wrapped.introspect = async () => {
173
+ refresh(await adapter.introspect());
174
+ return withoutHiddenColumns(full, rules, name);
175
+ };
176
+ if (adapter.poolStats)
177
+ wrapped.poolStats = from('poolStats');
178
+ if (adapter.privileges)
179
+ wrapped.privileges = from('privileges');
180
+ if (adapter.estimateCount)
181
+ wrapped.estimateCount = from('estimateCount');
182
+ wrapped.query = async (request) => adapter.query(checked(() => checks.queryFor(request)));
183
+ wrapped.count = async (table, filter, limit) => adapter.count(table, checked(() => checks.filterFor(table, filter)), limit);
184
+ if (adapter.countEach)
185
+ wrapped.countEach = async (items, limit) => adapter.countEach(checked(() => items.map((item) => ({ table: item.table, filter: checks.filterFor(item.table, item.filter) }))), limit);
186
+ if (adapter.runView)
187
+ wrapped.runView = async (view, offset) => adapter.runView(checked(() => checks.viewFor(view)), offset);
188
+ if (adapter.countView)
189
+ wrapped.countView = async (view, limit) => adapter.countView(checked(() => checks.viewFor(view)), limit);
190
+ if (adapter.runBreakdown)
191
+ wrapped.runBreakdown = async (def, offset) => adapter.runBreakdown(checked(() => checks.breakdownFor(def)), offset);
192
+ if (adapter.countBreakdown)
193
+ wrapped.countBreakdown = async (def, limit) => adapter.countBreakdown(checked(() => checks.breakdownFor(def)), limit);
194
+ if (adapter.scopeReads)
195
+ wrapped.scopeReads = async (scope) => reads(await adapter.scopeReads(scope));
196
+ /* Raw SQL can name any column, in any spelling, through any function: no
197
+ honest redaction exists for it. EXPLAIN is refused with it, since a plan
198
+ can be asked to run the statement. */
199
+ if (adapter.runSql)
200
+ wrapped.runSql = async () => {
201
+ throw refused('raw SQL is refused, because a statement can name any column. Remove "hidden" to run SQL here, or connect as a database role without SELECT on those columns');
202
+ };
203
+ if (adapter.explainSql)
204
+ wrapped.explainSql = async () => {
205
+ throw refused('explaining raw SQL is refused with running it');
206
+ };
207
+ // A table's DDL spells out every column, the hidden ones too.
208
+ if (adapter.ddl)
209
+ wrapped.ddl = async (table) => (cuts.has(table) ? undefined : adapter.ddl(table));
210
+ /* Profile keeps its numbers for the columns that are served. */
211
+ if (adapter.profile)
212
+ wrapped.profile = async (table, limits) => {
213
+ const result = await adapter.profile(table, limits);
214
+ const cut = cuts.get(table);
215
+ return cut ? { ...result, columns: result.columns.filter((column) => !cut.has(column.column)) } : result;
216
+ };
217
+ /* Writes are judged by the same grant: a hidden column is never written,
218
+ and an insert's stored row comes back without it. A delete removes every
219
+ column, the hidden ones too, and journals them for Undo, so it is
220
+ refused on a table with hidden columns. */
221
+ if (adapter.insert)
222
+ wrapped.insert = (request) => authorized(adapter).insert(request);
223
+ if (adapter.update)
224
+ wrapped.update = (request) => authorized(adapter).update(request);
225
+ if (adapter.remove)
226
+ wrapped.remove = (request) => authorized(adapter).remove(request);
227
+ if (adapter.transaction)
228
+ wrapped.transaction = (run) => adapter.transaction((tx) => run(authorized(tx)));
229
+ if (adapter.scopeTransaction)
230
+ wrapped.scopeTransaction = (scope, run) => adapter.scopeTransaction(scope, (tx, catalog) => run(authorized(tx), withoutHiddenColumns(catalog, rules, name)));
231
+ /* The command journal runs its work under the same grant and catalog. */
232
+ lendWriteView(wrapped, {
233
+ over: adapter,
234
+ records: (records) => authorized(records),
235
+ catalog: (catalog) => withoutHiddenColumns(catalog, rules, name),
236
+ });
237
+ return wrapped;
238
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * The headers every answer carries, set before anything is routed so a reply
3
+ * that names its own (a mail link's `no-referrer`) still wins: `writeHead`'s
4
+ * headers override what `setHeader` put first.
5
+ *
6
+ * - `Referrer-Policy: strict-origin-when-cross-origin`: an address under a
7
+ * record (`/compass/leads/127?search=…`) leaves this origin as the origin
8
+ * alone, and never over plain http.
9
+ * - `Permissions-Policy`: no page here uses a camera, a microphone, a
10
+ * location or a payment sheet, so none is granted — to a component, or to
11
+ * whatever frames or is framed.
12
+ * - `Strict-Transport-Security`, only on an answer that arrived over https
13
+ * (trust.ts `arrivedOverHttps`): the socket's own TLS, an https public
14
+ * address, or a proxy this server trusts saying it forwarded https. A
15
+ * plain-http server (a laptop, a loopback dev server) never pins its name
16
+ * to https.
17
+ */
18
+ import type { IncomingMessage, ServerResponse } from 'node:http';
19
+ import { type ProxyRange } from './trust.js';
20
+ export declare const REFERRER_POLICY = "strict-origin-when-cross-origin";
21
+ export declare const PERMISSIONS_POLICY: string;
22
+ /** A year, and the names under this one: the time browsers ask of a name kept on https. */
23
+ export declare const STRICT_TRANSPORT = "max-age=31536000; includeSubDomains";
24
+ export declare function setBaselineHeaders(req: Pick<IncomingMessage, 'headers' | 'socket'>, res: ServerResponse, trustedProxies?: readonly ProxyRange[]): void;
@@ -0,0 +1,12 @@
1
+ import { arrivedOverHttps } from './trust.js';
2
+ export const REFERRER_POLICY = 'strict-origin-when-cross-origin';
3
+ export const PERMISSIONS_POLICY = 'camera=(), microphone=(), geolocation=(), payment=(), usb=(), serial=(), bluetooth=(), hid=(), midi=(), ' +
4
+ 'magnetometer=(), gyroscope=(), accelerometer=(), display-capture=(), browsing-topics=()';
5
+ /** A year, and the names under this one: the time browsers ask of a name kept on https. */
6
+ export const STRICT_TRANSPORT = 'max-age=31536000; includeSubDomains';
7
+ export function setBaselineHeaders(req, res, trustedProxies = []) {
8
+ res.setHeader('referrer-policy', REFERRER_POLICY);
9
+ res.setHeader('permissions-policy', PERMISSIONS_POLICY);
10
+ if (arrivedOverHttps(req, trustedProxies))
11
+ res.setHeader('strict-transport-security', STRICT_TRANSPORT);
12
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * A reply held in memory: what a route sends when it answers a request made
3
+ * inside another (recordCompose.ts). The route is the same code an HTTP
4
+ * request reaches — the same grants, row scope and hidden columns — and
5
+ * writes through `send` as ever; only the bytes stop here instead of on a
6
+ * socket. Just enough of ServerResponse for the reply helpers (reply.ts) and
7
+ * the routes that set a header on the way.
8
+ */
9
+ import { EventEmitter } from 'node:events';
10
+ import type { OutgoingHttpHeaders, ServerResponse } from 'node:http';
11
+ export declare class CapturedReply extends EventEmitter {
12
+ statusCode: number;
13
+ headersSent: boolean;
14
+ writableEnded: boolean;
15
+ destroyed: boolean;
16
+ /** No request: nothing is compressed, and the whole reply is one JSON body. */
17
+ readonly req: undefined;
18
+ private readonly headers;
19
+ private chunks;
20
+ setHeader(name: string, value: number | string | readonly string[]): this;
21
+ getHeader(name: string): string | number | readonly string[] | undefined;
22
+ hasHeader(name: string): boolean;
23
+ removeHeader(name: string): void;
24
+ writeHead(status: number, headers?: OutgoingHttpHeaders): this;
25
+ write(chunk: Buffer | string): boolean;
26
+ end(chunk?: Buffer | string): this;
27
+ destroy(): this;
28
+ /** As the route answered: its status and its JSON, or undefined when it sent nothing. */
29
+ answer(): {
30
+ status: number;
31
+ body: unknown;
32
+ } | undefined;
33
+ /** Typed as the response the routes take. */
34
+ asResponse(): ServerResponse;
35
+ }