@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,730 @@
1
+ /**
2
+ * A grant over a catalog, and every check that holds a request to it: which
3
+ * tables and columns a reader reads and writes, the catalog pruned to them
4
+ * (its edges too, since a relationship can disclose a table), and each
5
+ * query, view, breakdown, filter and write refused where it reaches past
6
+ * them. The engine's, because two products hold requests to one: an App
7
+ * role's grant (app/appAccess.ts, which adds its rules over writes through
8
+ * `WriteRules`) and a connection's hidden columns (hiddenColumns.ts), which
9
+ * has no App in it to ask.
10
+ */
11
+ import { ANSI_STYLE, Refusal, } from '../adapters/adapter.js';
12
+ import { freezeDerivedCatalog, isCapturedScopeCatalog, isFixedScopeCatalog } from '../shared/scopeCatalog.js';
13
+ import { compileView, resolveAggregate, tryResolvePath } from '../shared/view.js';
14
+ import { rollupReads } from '../shared/rollups.js';
15
+ import { compileBreakdown, measureConditions } from '../shared/breakdown.js';
16
+ import { textToView } from '../shared/viewtext.js';
17
+ import { textToBreakdown } from '../shared/breakdowntext.js';
18
+ import { isJsonType } from '../shared/schema.js';
19
+ import { impliedEdges } from '../shared/declaredReferences.js';
20
+ import { unformedColumns } from '../shared/form.js';
21
+ import { isServerRequest } from './serverRequests.js';
22
+ /**
23
+ * A reader reaching past its grant. Its name is the App's, where most
24
+ * refusals are met; a connection's hidden columns (hiddenColumns.ts) say
25
+ * which boundary answered in a refusal of their own.
26
+ */
27
+ export class AppAccessDenied extends Refusal {
28
+ constructor(message = 'Access to this resource is denied.') {
29
+ super(message);
30
+ this.name = 'AppAccessDenied';
31
+ }
32
+ }
33
+ /** Preserve changes made before invocation, never changes during its awaits.
34
+ * These copied sets stay private; freezing a Set alone would not freeze grants. */
35
+ export function captureGrant(grant) {
36
+ return {
37
+ ...grant,
38
+ readable: new Set(grant.readable),
39
+ writable: new Set(grant.writable),
40
+ ...(grant.creatable ? { creatable: new Set(grant.creatable) } : {}),
41
+ ...(grant.fields
42
+ ? {
43
+ fields: new Map([...grant.fields].map(([table, fields]) => [table, { read: new Set(fields.read), write: new Set(fields.write) }])),
44
+ }
45
+ : {}),
46
+ };
47
+ }
48
+ const withoutCarriedReferences = (def) => {
49
+ if (!def || typeof def !== 'object' || !('references' in def))
50
+ return def;
51
+ const { references: _requested, ...rest } = def;
52
+ return rest;
53
+ };
54
+ /* Pruning a catalog to a grant allocated a fresh catalog on every request (9%
55
+ of a busy server's allocation), though the answer is the same for the same
56
+ catalog and the same grant. Only a grant its owner says is never changed
57
+ (markStableGrant: the HTTP source keeps one per App, catalog and role set)
58
+ is remembered, by the identity of its sets, so a grant built and edited by
59
+ a caller is judged afresh every time as before. */
60
+ const stableGrants = new WeakSet();
61
+ export function markStableGrant(grant) {
62
+ stableGrants.add(grant.readable);
63
+ return grant;
64
+ }
65
+ const prunedCatalogs = new WeakMap();
66
+ /* A tenant request resolves its grant afresh each time, so its sets are never
67
+ the same objects twice, and every read in it pruned the catalog again
68
+ (G118). A captured catalog is frozen, and pruning reads nothing of the grant
69
+ but the five things in this key, so the answer for a catalog and a key is
70
+ kept — bounded, oldest out first — and frozen, so no caller can change the
71
+ copy another one is handed. */
72
+ const prunedByContent = new WeakMap();
73
+ const PRUNED = 256;
74
+ const sorted = (names) => [...names].sort();
75
+ function grantKey(access) {
76
+ return JSON.stringify([
77
+ sorted(access.readable),
78
+ sorted(access.writable),
79
+ access.creatable ? sorted(access.creatable) : null,
80
+ access.fields
81
+ ? [...access.fields].map(([table, { read, write }]) => [table, sorted(read), sorted(write)]).sort((a, b) => (a[0] < b[0] ? -1 : 1))
82
+ : null,
83
+ access.rows !== undefined,
84
+ access.internal
85
+ ? [...access.internal].map(([table, columns]) => [table, sorted(columns)]).sort((a, b) => (a[0] < b[0] ? -1 : 1))
86
+ : null,
87
+ ]);
88
+ }
89
+ /** Test-only: how many times a catalog was pruned rather than reused. */
90
+ export const pruneCounters = { pruned: 0 };
91
+ /** Hide graph edges as well as tables: a relationship can disclose another resource. */
92
+ export function accessibleSchema(schema, access) {
93
+ if (!stableGrants.has(access.readable)) {
94
+ if (!isCapturedScopeCatalog(schema))
95
+ return pruneCatalog(schema, access);
96
+ let byKey = prunedByContent.get(schema);
97
+ if (!byKey)
98
+ prunedByContent.set(schema, (byKey = new Map()));
99
+ const key = grantKey(access);
100
+ const known = byKey.get(key);
101
+ if (known)
102
+ return known;
103
+ const pruned = freezeDerivedCatalog(pruneCatalog(schema, access));
104
+ if (byKey.size >= PRUNED)
105
+ byKey.delete(byKey.keys().next().value);
106
+ byKey.set(key, pruned);
107
+ return pruned;
108
+ }
109
+ let byGrant = prunedCatalogs.get(schema);
110
+ if (!byGrant)
111
+ prunedCatalogs.set(schema, (byGrant = new WeakMap()));
112
+ const kept = byGrant.get(access.readable);
113
+ const scoped = access.rows !== undefined;
114
+ if (kept &&
115
+ kept.writable === access.writable &&
116
+ kept.creatable === access.creatable &&
117
+ kept.fields === access.fields &&
118
+ kept.internal === access.internal &&
119
+ kept.scoped === scoped)
120
+ return kept.pruned;
121
+ // Frozen over a captured catalog, as the content path's is: what reads it later (resourceChecks) may then keep by its identity.
122
+ const made = pruneCatalog(schema, access);
123
+ const pruned = isCapturedScopeCatalog(schema) ? freezeDerivedCatalog(made) : made;
124
+ const { writable, creatable, fields, internal } = access;
125
+ byGrant.set(access.readable, { writable, creatable, fields, internal, scoped, pruned });
126
+ return pruned;
127
+ }
128
+ function pruneCatalog(schema, access) {
129
+ pruneCounters.pruned++;
130
+ const scoped = access.rows !== undefined;
131
+ const readable = (table, column) => access.readable.has(table) && (access.fields?.get(table)?.read.has(column) ?? true);
132
+ /* Read by the server, never listed: an internal column is left out of what the catalog names, but not out of what the grant allows. */
133
+ const listed = (table, column) => readable(table, column) && !access.internal?.get(table)?.has(column);
134
+ const reaches = (fk) => access.readable.has(fk.from.table) &&
135
+ access.readable.has(fk.to.table) &&
136
+ fk.from.columns.every((column) => readable(fk.from.table, column)) &&
137
+ fk.to.columns.every((column) => readable(fk.to.table, column));
138
+ const kept = schema.foreignKeys.filter(reaches);
139
+ const keptSet = new Set(kept);
140
+ /* A composite key this reader cannot follow whole — a tenant's
141
+ `(tenant_id, group_id)`, whose ownership column no tenant reads — is still
142
+ followed by a leg that names one row alone (declaredReferences.ts
143
+ impliedEdges), so `group_id` keeps its link and its label.
144
+ Only where the composite is dropped: a reader who reads it whole has it. */
145
+ const dropped = schema.foreignKeys.filter((fk) => !fk.declared && fk.from.columns.length > 1 && !keptSet.has(fk));
146
+ // The single-column keys kept, by table: a leg is added only where none already leaves its column.
147
+ const keptSingle = new Map();
148
+ for (const fk of kept)
149
+ if (fk.from.columns.length === 1) {
150
+ const columns = keptSingle.get(fk.from.table);
151
+ if (columns)
152
+ columns.add(fk.from.columns[0]);
153
+ else
154
+ keptSingle.set(fk.from.table, new Set(fk.from.columns));
155
+ }
156
+ const legs = dropped.length
157
+ ? impliedEdges({ ...schema, foreignKeys: dropped }).filter((edge) => reaches(edge) && !keptSingle.get(edge.from.table)?.has(edge.from.columns[0]))
158
+ : [];
159
+ const foreignKeys = legs.length ? [...kept, ...legs] : kept;
160
+ /* Each edge by the table it leaves, and the tables an inferred edge points
161
+ at: asked below for every column of every table, a scan of the whole
162
+ graph each time made one pruning of a few hundred tables cost
163
+ milliseconds, and startup prunes once per command and role. */
164
+ const served = new Set(foreignKeys);
165
+ const leaving = (edges) => {
166
+ const by = new Map();
167
+ for (const edge of edges) {
168
+ const list = by.get(edge.from.table);
169
+ if (list)
170
+ list.push(edge);
171
+ else
172
+ by.set(edge.from.table, [edge]);
173
+ }
174
+ return by;
175
+ };
176
+ const servedFrom = leaving(foreignKeys), allFrom = leaving(schema.foreignKeys);
177
+ const inferredTo = new Set(schema.foreignKeys.flatMap((fk) => (fk.declared ? [] : [fk.to.table])));
178
+ return {
179
+ ...schema,
180
+ tables: schema.tables
181
+ .filter((table) => access.readable.has(table.id))
182
+ .map((table) => {
183
+ const { approxRows: _approxRows, ...withoutEstimate } = table;
184
+ return {
185
+ ...(scoped ? withoutEstimate : table),
186
+ ...(access.fields?.has(table.id)
187
+ ? {
188
+ deletable: access.writable.has(table.id) &&
189
+ table.columns.every((column) => readable(table.id, column.name) && access.fields.get(table.id).write.has(column.name)),
190
+ }
191
+ : {}),
192
+ /* A write grant whose columns leave out one a new row needs (a key,
193
+ a NOT NULL without a default) can edit rows and never make one:
194
+ New is not offered rather than refused on every save. */
195
+ ...(access.fields?.has(table.id) &&
196
+ access.writable.has(table.id) &&
197
+ !table.isView &&
198
+ unformedColumns(table, (column) => access.fields.get(table.id).write.has(column)).length
199
+ ? { insertable: false }
200
+ : {}),
201
+ // A role that edits and never creates (`create`): the same answer, said by the author.
202
+ ...(access.creatable && access.writable.has(table.id) && !access.creatable.has(table.id) ? { insertable: false } : {}),
203
+ ...(scoped
204
+ ? {
205
+ deletable: access.writable.has(table.id) &&
206
+ !table.isView &&
207
+ table.columns.some((column) => column.primaryKey) &&
208
+ !inferredTo.has(table.id) &&
209
+ table.columns.every((column) => readable(table.id, column.name) && (access.fields?.get(table.id)?.write.has(column.name) ?? true)),
210
+ }
211
+ : {}),
212
+ ...(table.indexed ? { indexed: table.indexed.filter((column) => listed(table.id, column)) } : {}),
213
+ // Like `indexed`: a hidden column is not named, even as unique.
214
+ ...(table.unique ? { unique: table.unique.filter((column) => listed(table.id, column)) } : {}),
215
+ ...(table.uniquePairs
216
+ ? {
217
+ uniquePairs: table.uniquePairs.filter((pair) => pair.every((column) => listed(table.id, column))),
218
+ }
219
+ : {}),
220
+ ...(table.trigram
221
+ ? {
222
+ trigram: table.trigram.filter((column) => listed(table.id, column)),
223
+ }
224
+ : {}),
225
+ columns: table.columns
226
+ .filter((column) => listed(table.id, column.name))
227
+ .map((column) => {
228
+ const scope = access.fields?.get(table.id);
229
+ const metadata = {
230
+ ...column,
231
+ // A column the database computes stays unwritable whatever the grant says.
232
+ ...(scope ? { writable: column.writable !== false && access.writable.has(table.id) && scope.write.has(column.name) } : {}),
233
+ ...(scoped
234
+ ? {
235
+ writable: column.writable !== false &&
236
+ access.writable.has(table.id) &&
237
+ !table.isView &&
238
+ (scope?.write.has(column.name) ?? true),
239
+ }
240
+ : {}),
241
+ };
242
+ const reference = column.references;
243
+ // A surviving component of a hidden composite FK must not advertise
244
+ // a relationship whose other join columns cannot be read — unless the
245
+ // column is a key of its own this reader follows: its own single key, or
246
+ // the leg the composite implies. Beside a tenant's composite, a single key
247
+ // lost its link here and its cells drew the raw id.
248
+ const followed = (servedFrom.get(table.id) ?? []).some((edge) => edge.from.columns.length === 1 &&
249
+ edge.from.columns[0] === column.name &&
250
+ edge.to.table === reference?.table &&
251
+ edge.to.columns[0] === reference?.column);
252
+ const hiddenEdge = !followed && (allFrom.get(table.id) ?? []).some((fk) => fk.from.columns.includes(column.name) && !served.has(fk));
253
+ if (!reference || (readable(reference.table, reference.column) && !hiddenEdge))
254
+ return metadata;
255
+ const { references: _references, ...visible } = metadata;
256
+ return visible;
257
+ }),
258
+ };
259
+ }),
260
+ foreignKeys,
261
+ };
262
+ }
263
+ /** Capture data before checking it: queued adapters must execute what we authorized.
264
+ * Getters, inherited properties and coercible objects are not structured requests. */
265
+ export function requestData(value, ancestors = new Set()) {
266
+ if (value === null ||
267
+ value === undefined ||
268
+ typeof value === 'string' ||
269
+ typeof value === 'boolean' ||
270
+ (typeof value === 'number' && Number.isFinite(value)))
271
+ return value;
272
+ // Bytes are data too (a file upload's content), copied so no caller keeps a handle on what is written.
273
+ if (value instanceof Uint8Array && (Object.getPrototypeOf(value) === Uint8Array.prototype || Buffer.isBuffer(value)))
274
+ return Buffer.from(value);
275
+ if (typeof value !== 'object' || ancestors.has(value))
276
+ throw new AppAccessDenied();
277
+ const array = Array.isArray(value);
278
+ const proto = Object.getPrototypeOf(value);
279
+ if (array ? proto !== Array.prototype : proto !== Object.prototype && proto !== null)
280
+ throw new AppAccessDenied();
281
+ ancestors.add(value);
282
+ const entries = [];
283
+ for (const key of Reflect.ownKeys(value)) {
284
+ if (array && key === 'length')
285
+ continue;
286
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
287
+ if (typeof key !== 'string' || !descriptor.enumerable || !('value' in descriptor) || (array && !/^(0|[1-9][0-9]*)$/.test(key)))
288
+ throw new AppAccessDenied();
289
+ entries.push([key, requestData(descriptor.value, ancestors)]);
290
+ }
291
+ ancestors.delete(value);
292
+ if (array) {
293
+ if (entries.length !== value.length)
294
+ throw new AppAccessDenied();
295
+ return entries.map(([, item]) => item);
296
+ }
297
+ return Object.fromEntries(entries);
298
+ }
299
+ /* A pruned catalog's full-catalog comparison (resourceChecks), kept per pruned catalog nothing can change. */
300
+ const comparisons = new WeakMap();
301
+ /** Every read and write check against one grant, over the catalog it prunes: an App role's (app/appAccess.ts) and a connection's hidden columns (hiddenColumns.ts) alike. */
302
+ export function resourceChecks(full, access) {
303
+ const schema = accessibleSchema(full, access);
304
+ /* What the pruned compile is compared with: every table and edge of the
305
+ full catalog, so a hop that pruning disambiguated differently still
306
+ shows, but each table's columns as this reader reads them. A relation
307
+ written out whole (a rollup's filtered rows, a row scope) lists its
308
+ columns, and that list is meant to differ by the ones cut. */
309
+ /* With the legs pruning followed in place of a composite key the reader
310
+ cannot read whole (pruneCatalog): the full catalog joins on the composite
311
+ only under its own hop name, so `group_id` is the same join on both. */
312
+ /* Built when a view or breakdown is compiled, not for every request: the
313
+ scan of every edge against every edge was among a tenant read's largest
314
+ costs in a field report's profile, for a catalog most requests never
315
+ compare. Kept per pruned catalog where both catalogs are fixed: such a
316
+ pruning is the answer for one grant's content (accessibleSchema), and
317
+ the columns cut here are that grant's `fields`, so the same pruned
318
+ catalog always stands beside the same comparison. */
319
+ let compared;
320
+ const unprunedCatalog = () => {
321
+ if (compared)
322
+ return compared;
323
+ const fixed = isCapturedScopeCatalog(full) && isFixedScopeCatalog(schema);
324
+ const kept = fixed ? comparisons.get(schema) : undefined;
325
+ if (kept)
326
+ return (compared = kept);
327
+ const legs = schema.foreignKeys.filter((fk) => !full.foreignKeys.some((other) => other.name === fk.name && other.from.table === fk.from.table));
328
+ const followed = legs.length ? { ...full, foreignKeys: [...full.foreignKeys, ...legs] } : full;
329
+ const made = access.fields
330
+ ? {
331
+ ...followed,
332
+ tables: full.tables.map((table) => {
333
+ const read = access.fields.get(table.id)?.read;
334
+ return read ? { ...table, columns: table.columns.filter((column) => read.has(column.name)) } : table;
335
+ }),
336
+ }
337
+ : followed;
338
+ /* Frozen where it is kept: a catalog nothing can change, so what is compiled against it — every view and
339
+ breakdown of an enter is compiled here a second time — is kept with it too (breakdown.ts compileBreakdown). */
340
+ if (fixed)
341
+ comparisons.set(schema, freezeDerivedCatalog(made));
342
+ return (compared = made);
343
+ };
344
+ const assertRead = (table) => {
345
+ if (!access.readable.has(table))
346
+ throw new AppAccessDenied();
347
+ };
348
+ const assertWrite = (table) => {
349
+ assertRead(table);
350
+ if (!access.writable.has(table))
351
+ throw new AppAccessDenied();
352
+ };
353
+ /* An `internal` column is the server's: a request that names it — a
354
+ column, a filter, a sort, a value — is refused as one naming a column it
355
+ may not have, unless the server built the request itself. */
356
+ const assertFields = (table, columns, mode = 'read', server = false) => {
357
+ assertRead(table);
358
+ const declared = full.tables.find((item) => item.id === table);
359
+ const allowed = access.fields?.get(table);
360
+ const internal = server ? undefined : access.internal?.get(table);
361
+ for (const column of columns) {
362
+ if (!declared?.columns.some((item) => item.name === column) ||
363
+ internal?.has(column) ||
364
+ (allowed && (!allowed.read.has(column) || (mode === 'write' && !allowed.write.has(column))))) {
365
+ throw new AppAccessDenied();
366
+ }
367
+ }
368
+ };
369
+ /* Every column of a table: a delete's before-image, a cascade's dependents,
370
+ a profile. A removal takes the server's columns with the row, so `owned`
371
+ leaves them out of what the principal must hold; a read of them never does. */
372
+ const assertAllFields = (table, mode = 'read', owned = false) => assertFields(table, full.tables
373
+ .find((item) => item.id === table)
374
+ ?.columns.map((column) => column.name)
375
+ .filter((column) => !owned || !access.internal?.get(table)?.has(column)) ?? [], mode);
376
+ const recordFields = (table, record, mode, server = false) => {
377
+ if (!record || typeof record !== 'object' || Array.isArray(record))
378
+ throw new AppAccessDenied();
379
+ assertFields(table, Object.keys(record), mode, server);
380
+ // A written value may also be bytes (a file's content, already copied by requestData); a key or a read never is.
381
+ if (Object.values(record).some((value) => value !== null &&
382
+ typeof value !== 'string' &&
383
+ typeof value !== 'number' &&
384
+ typeof value !== 'boolean' &&
385
+ !(mode === 'write' && value instanceof Uint8Array)))
386
+ throw new AppAccessDenied();
387
+ };
388
+ const keyFields = (table, key) => {
389
+ recordFields(table, key, 'read');
390
+ const primary = full.tables.find((item) => item.id === table)?.columns.filter((column) => column.primaryKey) ?? [];
391
+ if (!primary.length ||
392
+ Object.keys(key).length !== primary.length ||
393
+ primary.some((column) => !Object.hasOwn(key, column.name)) ||
394
+ Object.values(key).some((value) => typeof value !== 'string' && typeof value !== 'number'))
395
+ throw new AppAccessDenied();
396
+ };
397
+ const filterFor = (table, input, server = false) => {
398
+ assertRead(table);
399
+ const filter = requestData(input);
400
+ if (filter)
401
+ for (const group of filter.groups)
402
+ for (const condition of group)
403
+ assertFields(table, [condition.column], 'read', server);
404
+ return filter;
405
+ };
406
+ const queryFor = (input) => {
407
+ const server = isServerRequest(input);
408
+ const request = requestData(input);
409
+ assertRead(request.table);
410
+ const columns = request.columns?.length
411
+ ? request.columns
412
+ : (schema.tables.find((table) => table.id === request.table)?.columns.map((column) => column.name) ?? []);
413
+ // Never pass an empty projection to an adapter: it means SELECT *.
414
+ if (!columns.length)
415
+ throw new AppAccessDenied();
416
+ assertFields(request.table, columns, 'read', server);
417
+ for (const order of request.orderBy ?? [])
418
+ assertFields(request.table, [order.column], 'read', server);
419
+ return { ...request, columns, filter: filterFor(request.table, request.filter, server) };
420
+ };
421
+ /* A rollup reads its child rows: the child, the reference, the column it
422
+ sums and the columns its filter narrows by must all be readable here —
423
+ an inner rollup's too — or the number would be built from values this
424
+ reader may not see. A view's and a breakdown's alike. */
425
+ const assertRollups = (computed) => {
426
+ for (const rollup of Object.values(computed ?? {})) {
427
+ for (const { table, fields } of rollupReads(rollup)) {
428
+ assertRead(table);
429
+ assertFields(table, fields);
430
+ }
431
+ }
432
+ };
433
+ /* A computed column reads its record's columns (computed.ts): each must be
434
+ one this reader is served, through readable references, or the value
435
+ would say what its inputs may not. A pinned expression is the catalog's,
436
+ never a request's, and is held to the reader here all the same. */
437
+ const assertExpressions = (base, expressions, rollups) => {
438
+ for (const expressed of Object.values(expressions ?? {})) {
439
+ for (const read of expressed.reads) {
440
+ const path = expressed.on ? `${expressed.on}.${read}` : read;
441
+ /* A rollup it reads is pinned beside it (viewLabels.ts withViewComputed),
442
+ not on this catalog, and assertRollups has held it to the reader. */
443
+ if (rollups && Object.hasOwn(rollups, path))
444
+ continue;
445
+ const { resolved } = tryResolvePath(schema, base, path);
446
+ if (!resolved)
447
+ throw new AppAccessDenied();
448
+ for (const hop of resolved.hops) {
449
+ assertRead(hop.from.table);
450
+ assertRead(hop.to.table);
451
+ }
452
+ assertRead(resolved.table.id);
453
+ if (!resolved.rollup && !resolved.computed)
454
+ assertFields(resolved.table.id, [resolved.column.name]);
455
+ }
456
+ }
457
+ };
458
+ /* A record's tags read their link rows and the tags themselves
459
+ (tagLists.ts): both tables, and the columns read there, must be this
460
+ reader's, or a chip would say what the reader may not read. Pinned from
461
+ the catalog, never a request, and held to the reader here all the same. */
462
+ const assertTags = (tagged) => {
463
+ for (const tags of Object.values(tagged ?? {})) {
464
+ assertFields(tags.through, [tags.from, tags.via]);
465
+ assertFields(tags.to, [tags.tagKey, tags.label, ...(tags.tone ? [tags.tone] : [])]);
466
+ }
467
+ };
468
+ /* `any opportunity where stage = won` reads the rows that point at the record (view.ts): their table, the
469
+ reference they point through, and every column their conditions name — through readable references, as a
470
+ path anywhere is — must be this reader's, or the list would answer a question about rows they cannot read.
471
+ Their scope is the statement's (rowScope.ts), so a row policy on them narrows the answer as it narrows them. */
472
+ const assertAnyRows = (filter) => {
473
+ for (const condition of filter?.groups.flat() ?? []) {
474
+ if (!condition.any)
475
+ continue;
476
+ if (typeof condition.any !== 'object' || typeof condition.any.via !== 'string')
477
+ throw new AppAccessDenied();
478
+ const { via } = condition.any;
479
+ const child = via.slice(0, via.lastIndexOf('.'));
480
+ assertRead(child);
481
+ assertFields(child, via.slice(child.length + 1).split('+'));
482
+ for (const inner of condition.any.filter?.groups.flat() ?? []) {
483
+ for (const path of [inner.column, ...(inner.other === undefined ? [] : [inner.other])]) {
484
+ const { resolved } = tryResolvePath(schema, child, path);
485
+ if (!resolved || resolved.rollup || resolved.computed || resolved.tags)
486
+ throw new AppAccessDenied();
487
+ for (const hop of resolved.hops) {
488
+ assertFields(hop.from.table, hop.from.columns);
489
+ assertFields(hop.to.table, hop.to.columns);
490
+ }
491
+ assertFields(resolved.table.id, [resolved.column.name]);
492
+ }
493
+ }
494
+ }
495
+ };
496
+ const viewFor = (input) => {
497
+ // The soft keys a compiler below may walk are the App's to attach, never a request's.
498
+ let view = withoutCarriedReferences(requestData(input));
499
+ if (view.text !== undefined) {
500
+ if (typeof view.text !== 'string')
501
+ throw new AppAccessDenied();
502
+ const parsed = textToView(schema, view.text, { id: view.id, name: view.name });
503
+ if (!parsed.view || parsed.errors.length)
504
+ throw new AppAccessDenied();
505
+ // Text is authoritative until materialized. Never forward it alongside
506
+ // checked columns for another layer to parse against its full catalog.
507
+ // Pagination is invocation-owned, not part of text authority over paths.
508
+ // Keep the caller's normalized cap when materializing against this graph.
509
+ view = { ...parsed.view, limit: view.limit ?? parsed.view.limit, source: view.source, connection: view.connection };
510
+ }
511
+ assertRead(view.base);
512
+ if (!view.columns?.length)
513
+ view.columns = schema.tables.find((table) => table.id === view.base).columns.map((column) => ({ path: column.name }));
514
+ if (!view.columns.length)
515
+ throw new AppAccessDenied();
516
+ for (const aggregate of view.aggregates ?? []) {
517
+ if (aggregate.column !== undefined)
518
+ assertFields(resolveAggregate(schema, view.base, aggregate).child.id, [aggregate.column]);
519
+ }
520
+ assertRollups(view.computed);
521
+ assertExpressions(view.base, view.expressions, view.computed);
522
+ assertTags(view.tagged);
523
+ assertAnyRows(view.filter);
524
+ // Validate against the pruned graph before the underlying full catalog can
525
+ // resolve a forbidden forward path, filter, sort or reverse aggregate.
526
+ const compiled = compileView(schema, view, ANSI_STYLE);
527
+ // Pruning can change hop disambiguation. Refuse if the full compiler would
528
+ // execute a different relationship from the one checked above.
529
+ if (compiled.text !== compileView(unprunedCatalog(), view, ANSI_STYLE).text)
530
+ throw new AppAccessDenied();
531
+ return view;
532
+ };
533
+ const breakdownFor = (input) => {
534
+ let breakdown = withoutCarriedReferences(requestData(input));
535
+ if (breakdown.text !== undefined) {
536
+ if (typeof breakdown.text !== 'string')
537
+ throw new AppAccessDenied();
538
+ const parsed = textToBreakdown(schema, breakdown.text);
539
+ if (!parsed.breakdown || parsed.errors.length)
540
+ throw new AppAccessDenied();
541
+ const { text: _text, ...materialized } = parsed.breakdown;
542
+ breakdown = { ...materialized, limit: breakdown.limit ?? materialized.limit };
543
+ }
544
+ assertRead(breakdown.base);
545
+ assertRollups(breakdown.computed);
546
+ assertExpressions(breakdown.base, breakdown.expressions, breakdown.computed);
547
+ assertTags(breakdown.tagged);
548
+ assertAnyRows(breakdown.filter);
549
+ for (const where of measureConditions(breakdown.measures))
550
+ assertAnyRows(where);
551
+ const compiled = compileBreakdown(schema, breakdown, ANSI_STYLE);
552
+ if (compiled.text !== compileBreakdown(unprunedCatalog(), breakdown, ANSI_STYLE).text)
553
+ throw new AppAccessDenied();
554
+ return breakdown;
555
+ };
556
+ const assertRelatedWrites = (table, fields) => {
557
+ const visited = new Set();
558
+ const visit = (target) => {
559
+ if (visited.has(target))
560
+ return;
561
+ visited.add(target);
562
+ // The database's keys only: a declared reference is never authority for a write (declaredReferences.ts).
563
+ for (const fk of full.foreignKeys.filter((fk) => fk.to.table === target && !fk.declared)) {
564
+ if (fields && target === table && !fk.to.columns.some((column) => fields.includes(column)))
565
+ continue;
566
+ // Unknown actions and hidden dependents must not be treated as harmless.
567
+ assertRead(fk.from.table);
568
+ assertFields(fk.from.table, fk.from.columns);
569
+ assertFields(fk.to.table, fk.to.columns);
570
+ if (!fields && (fk.onDelete === 'restrict' || fk.onDelete === 'no action'))
571
+ continue;
572
+ assertWrite(fk.from.table);
573
+ // Cascaded deletion removes every field. ON UPDATE is not introspected,
574
+ // so only a fully writable dependent is safe for key changes/unknowns.
575
+ if (fields || fk.onDelete === 'cascade' || !fk.onDelete)
576
+ assertAllFields(fk.from.table, 'write', true);
577
+ else
578
+ assertFields(fk.from.table, fk.from.columns, 'write');
579
+ visit(fk.from.table);
580
+ }
581
+ };
582
+ visit(table);
583
+ };
584
+ /* A write may point a row only at a parent the principal reads: an
585
+ insert at every parent it names (its values and its key), an update at
586
+ those whose columns it sets. A reference the write does not touch is not
587
+ its to vouch for; checking it refused a borrower's phone edit over the
588
+ applicant row their profile points at, which the App never declares. */
589
+ const assertParentReads = (table, values, insert) => {
590
+ const meta = full.tables.find((item) => item.id === table);
591
+ const set = new Set([
592
+ ...Object.keys(values ?? {}),
593
+ ...(insert ? (meta?.columns.filter((column) => column.primaryKey).map((column) => column.name) ?? []) : []),
594
+ ]);
595
+ for (const fk of full.foreignKeys.filter((fk) => fk.from.table === table && !fk.declared && fk.from.columns.some((column) => set.has(column)))) {
596
+ assertFields(fk.to.table, fk.to.columns);
597
+ }
598
+ };
599
+ return {
600
+ schema,
601
+ assertRead,
602
+ assertWrite,
603
+ assertAllFields,
604
+ assertParentReads,
605
+ recordFields,
606
+ keyFields,
607
+ queryFor,
608
+ filterFor,
609
+ viewFor,
610
+ breakdownFor,
611
+ assertRelatedWrites,
612
+ };
613
+ }
614
+ /** Pure catalog validation through the same graph boundary as runtime reads. */
615
+ export function validateResourceView(schema, access, view) {
616
+ return resourceChecks(schema, access).viewFor(view);
617
+ }
618
+ /* A JSON column's object or array is written as its JSON text: every door
619
+ (a form, a command, the API, an import) passes here, so the checks below
620
+ and the adapters, the tenant's managed transaction among them, stay scalar. */
621
+ function jsonWritten(full, request) {
622
+ const values = request.values;
623
+ if (!values || typeof values !== 'object' || Array.isArray(values))
624
+ return request;
625
+ const json = jsonColumns(full, request.table);
626
+ const objects = Object.keys(values).filter((column) => json.has(column) && values[column] !== null && typeof values[column] === 'object');
627
+ if (!objects.length)
628
+ return request;
629
+ return { ...request, values: { ...values, ...Object.fromEntries(objects.map((column) => [column, JSON.stringify(values[column])])) } };
630
+ }
631
+ function jsonColumns(full, table) {
632
+ return new Set(full.tables
633
+ .find((item) => item.id === table)
634
+ ?.columns.filter((column) => isJsonType(column.type))
635
+ .map((column) => column.name) ?? []);
636
+ }
637
+ /* An update's `expected` names each written column but a JSON one, which no
638
+ engine compares (updateGuard.ts) and which a stale write cannot hide in:
639
+ it is written whole. */
640
+ export function expectedCovers(full, request) {
641
+ const json = jsonColumns(full, request.table);
642
+ const expected = request.expected;
643
+ const columns = Object.keys(request.values).filter((column) => !json.has(column) || Object.hasOwn(expected, column));
644
+ return Object.keys(expected).length === columns.length && columns.every((column) => Object.hasOwn(expected, column));
645
+ }
646
+ /** Apply the same graph-aware checks to an already-owned transaction handle. */
647
+ export function authorizeColumnWrites(full, grant, writer, rules) {
648
+ // An arbitrary transaction handle has no proof of row enforcement. Only
649
+ // authorizeResources may bind the explicit capability before composing this.
650
+ if (grant.rows !== undefined)
651
+ throw new AppAccessDenied();
652
+ const checks = resourceChecks(full, grant);
653
+ const { assertRead, assertWrite, assertAllFields, recordFields, keyFields, queryFor, filterFor, assertRelatedWrites } = checks;
654
+ const product = rules?.(checks);
655
+ // Keep each call's rules stable across its awaits; the next call reads current grants.
656
+ const capture = (current) => (product ? product.capture(current) : captureGrant(current));
657
+ return {
658
+ ...(writer.lockRecord
659
+ ? {
660
+ lockRecord: async (input) => {
661
+ const request = requestData(input);
662
+ if (grant.writable.has(request.table) || !product?.locksUnwritable?.(request.table, grant))
663
+ assertWrite(request.table);
664
+ else
665
+ assertRead(request.table);
666
+ keyFields(request.table, request.key);
667
+ await writer.lockRecord(request);
668
+ },
669
+ }
670
+ : {}),
671
+ // A flow's notify step tells of a record the principal reads; it writes nothing.
672
+ ...(writer.tell
673
+ ? {
674
+ tell: async (input) => {
675
+ const request = requestData(input);
676
+ assertRead(request.table);
677
+ keyFields(request.table, request.key);
678
+ await writer.tell(request);
679
+ },
680
+ }
681
+ : {}),
682
+ query: (request) => writer.query(queryFor(request)),
683
+ count: (table, filter) => writer.count(table, filterFor(table, filter)),
684
+ insert: (input) => {
685
+ const server = isServerRequest(input);
686
+ const request = jsonWritten(full, requestData(input));
687
+ const operation = capture(grant);
688
+ assertWrite(request.table);
689
+ if (operation.creatable && !operation.creatable.has(request.table))
690
+ throw new AppAccessDenied();
691
+ recordFields(request.table, request.values, 'write', server);
692
+ const written = product?.insert ? product.insert(request, operation, server) : (async () => writer.insert(request))();
693
+ return written.then((result) => {
694
+ const readable = operation.fields?.get(request.table)?.read;
695
+ if (!readable || !result.row)
696
+ return result;
697
+ return { ...result, row: Object.fromEntries(Object.entries(result.row).filter(([column]) => readable.has(column))) };
698
+ });
699
+ },
700
+ update: (input) => {
701
+ const request = jsonWritten(full, requestData(input));
702
+ const operation = capture(grant);
703
+ if (!operation.writable.has(request.table)) {
704
+ const answered = product?.unwritable?.(request, operation);
705
+ if (answered)
706
+ return answered;
707
+ }
708
+ assertWrite(request.table);
709
+ recordFields(request.table, request.values, 'write', isServerRequest(input));
710
+ keyFields(request.table, request.key);
711
+ if (request.expected !== undefined) {
712
+ recordFields(request.table, request.expected, 'read');
713
+ if (!expectedCovers(full, request))
714
+ throw new AppAccessDenied();
715
+ }
716
+ assertRelatedWrites(request.table, Object.keys(request.values));
717
+ return product?.update ? product.update(request, operation) : (async () => writer.update(request))();
718
+ },
719
+ remove: (input) => {
720
+ const request = requestData(input);
721
+ assertWrite(request.table);
722
+ keyFields(request.table, request.key);
723
+ // Delete/Undo requires a complete readable before-image and permission
724
+ // to remove all fields, including those protected from ordinary updates.
725
+ assertAllFields(request.table, 'write', true);
726
+ assertRelatedWrites(request.table);
727
+ return product?.remove ? product.remove(request, grant) : writer.remove(request);
728
+ },
729
+ };
730
+ }