@segmentstream/ontology 0.0.0-stage → 0.92.0

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 (483) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +2 -0
  3. package/README.md +1655 -2
  4. package/dist/action.d.ts +193 -0
  5. package/dist/action.js +41 -0
  6. package/dist/agent-chat.d.ts +44 -0
  7. package/dist/agent-chat.js +91 -0
  8. package/dist/agent-task-contract.d.ts +64 -0
  9. package/dist/agent-task-contract.js +15 -0
  10. package/dist/agent-task.d.ts +39 -0
  11. package/dist/agent-task.js +112 -0
  12. package/dist/analyze.d.ts +215 -0
  13. package/dist/analyze.js +2438 -0
  14. package/dist/app-feedback.d.ts +167 -0
  15. package/dist/app-feedback.js +176 -0
  16. package/dist/authoring-input.d.ts +3 -0
  17. package/dist/authoring-input.js +107 -0
  18. package/dist/authoring-names.d.ts +4 -0
  19. package/dist/authoring-names.js +13 -0
  20. package/dist/authoring-records.d.ts +35 -0
  21. package/dist/authoring-records.js +264 -0
  22. package/dist/authoring.d.ts +15 -0
  23. package/dist/authoring.js +331 -0
  24. package/dist/bin/check.d.ts +30 -0
  25. package/dist/bin/check.js +99 -0
  26. package/dist/bin/load.d.ts +48 -0
  27. package/dist/bin/load.js +139 -0
  28. package/dist/bin/main.d.ts +31 -0
  29. package/dist/bin/main.js +121 -0
  30. package/dist/bin/migrate.d.ts +57 -0
  31. package/dist/bin/migrate.js +170 -0
  32. package/dist/bin/output.d.ts +31 -0
  33. package/dist/bin/output.js +84 -0
  34. package/dist/bin.d.ts +2 -0
  35. package/dist/bin.js +31 -0
  36. package/dist/blob.d.ts +52 -0
  37. package/dist/blob.js +87 -0
  38. package/dist/channel-session.d.ts +16 -0
  39. package/dist/channel-session.js +16 -0
  40. package/dist/chat.d.ts +43 -0
  41. package/dist/chat.js +34 -0
  42. package/dist/confirmation.d.ts +46 -0
  43. package/dist/confirmation.js +41 -0
  44. package/dist/connection.d.ts +213 -0
  45. package/dist/connection.js +289 -0
  46. package/dist/deployment.d.ts +35 -0
  47. package/dist/deployment.js +76 -0
  48. package/dist/diagnostics.d.ts +27 -0
  49. package/dist/diagnostics.js +106 -0
  50. package/dist/emails.d.ts +70 -0
  51. package/dist/emails.js +221 -0
  52. package/dist/entity.d.ts +331 -0
  53. package/dist/entity.js +153 -0
  54. package/dist/errors.d.ts +154 -0
  55. package/dist/errors.js +109 -0
  56. package/dist/feedback-config.d.ts +24 -0
  57. package/dist/feedback-config.js +126 -0
  58. package/dist/files.d.ts +39 -0
  59. package/dist/files.js +4 -0
  60. package/dist/groups.d.ts +95 -0
  61. package/dist/groups.js +280 -0
  62. package/dist/index.d.ts +109 -0
  63. package/dist/index.js +70 -0
  64. package/dist/internal/diagnostics.js +594 -0
  65. package/dist/legacy.d.ts +160 -0
  66. package/dist/legacy.js +270 -0
  67. package/dist/manifest-compatibility.d.ts +8 -0
  68. package/dist/manifest-compatibility.js +87 -0
  69. package/dist/manifest.d.ts +3329 -0
  70. package/dist/manifest.js +757 -0
  71. package/dist/me.d.ts +46 -0
  72. package/dist/me.js +109 -0
  73. package/dist/metric-filters.d.ts +48 -0
  74. package/dist/metric-filters.js +252 -0
  75. package/dist/metric-routes.d.ts +132 -0
  76. package/dist/metric-routes.js +498 -0
  77. package/dist/metric.d.ts +172 -0
  78. package/dist/metric.js +132 -0
  79. package/dist/migrate/apply.d.ts +94 -0
  80. package/dist/migrate/apply.js +526 -0
  81. package/dist/migrate/errors.d.ts +46 -0
  82. package/dist/migrate/errors.js +38 -0
  83. package/dist/migrate/index.d.ts +10 -0
  84. package/dist/migrate/index.js +7 -0
  85. package/dist/migrate/model.d.ts +2311 -0
  86. package/dist/migrate/model.js +148 -0
  87. package/dist/migrate/plan.d.ts +51 -0
  88. package/dist/migrate/plan.js +1856 -0
  89. package/dist/migrate/preview.d.ts +13 -0
  90. package/dist/migrate/preview.js +65 -0
  91. package/dist/migrate/storage.d.ts +226 -0
  92. package/dist/migrate/storage.js +774 -0
  93. package/dist/model-metrics.d.ts +22 -0
  94. package/dist/model-metrics.js +545 -0
  95. package/dist/names.d.ts +49 -0
  96. package/dist/names.js +110 -0
  97. package/dist/navigation-artifact.d.ts +13 -0
  98. package/dist/navigation-artifact.js +11 -0
  99. package/dist/navigation-catalog.d.ts +55 -0
  100. package/dist/navigation-catalog.js +297 -0
  101. package/dist/nitro-navigation.d.ts +3 -0
  102. package/dist/nitro-navigation.js +64 -0
  103. package/dist/nitro-workflows.d.ts +108 -0
  104. package/dist/nitro-workflows.js +286 -0
  105. package/dist/nitro.d.ts +40 -0
  106. package/dist/nitro.js +50 -0
  107. package/dist/ontology.d.ts +41 -0
  108. package/dist/ontology.js +46 -0
  109. package/dist/permissions.d.ts +198 -0
  110. package/dist/permissions.js +272 -0
  111. package/dist/property.d.ts +188 -0
  112. package/dist/property.js +301 -0
  113. package/dist/query.d.ts +245 -0
  114. package/dist/query.js +615 -0
  115. package/dist/relationship.d.ts +99 -0
  116. package/dist/relationship.js +33 -0
  117. package/dist/render.d.ts +81 -0
  118. package/dist/render.js +512 -0
  119. package/dist/replication/baseline.d.ts +51 -0
  120. package/dist/replication/baseline.js +215 -0
  121. package/dist/replication/bigquery.d.ts +37 -0
  122. package/dist/replication/bigquery.js +211 -0
  123. package/dist/replication/coverage.d.ts +14 -0
  124. package/dist/replication/coverage.js +53 -0
  125. package/dist/replication/evolution.d.ts +25 -0
  126. package/dist/replication/evolution.js +184 -0
  127. package/dist/replication/identities.d.ts +6 -0
  128. package/dist/replication/identities.js +47 -0
  129. package/dist/replication/legacy-baseline.d.ts +27 -0
  130. package/dist/replication/legacy-baseline.js +109 -0
  131. package/dist/replication/legacy-store.d.ts +19 -0
  132. package/dist/replication/legacy-store.js +63 -0
  133. package/dist/replication/lineage.d.ts +36 -0
  134. package/dist/replication/lineage.js +72 -0
  135. package/dist/replication/migrate.d.ts +21 -0
  136. package/dist/replication/migrate.js +84 -0
  137. package/dist/replication/model.d.ts +52 -0
  138. package/dist/replication/model.js +99 -0
  139. package/dist/replication/scans.d.ts +34 -0
  140. package/dist/replication/scans.js +158 -0
  141. package/dist/replication/schema.d.ts +11 -0
  142. package/dist/replication/schema.js +226 -0
  143. package/dist/replication/shadow-schema.d.ts +4 -0
  144. package/dist/replication/shadow-schema.js +61 -0
  145. package/dist/replication/shadow.d.ts +127 -0
  146. package/dist/replication/shadow.js +614 -0
  147. package/dist/replication/source-replacement.d.ts +33 -0
  148. package/dist/replication/source-replacement.js +76 -0
  149. package/dist/replication/store.d.ts +36 -0
  150. package/dist/replication/store.js +382 -0
  151. package/dist/replication/transaction.d.ts +23 -0
  152. package/dist/replication/transaction.js +88 -0
  153. package/dist/role.d.ts +61 -0
  154. package/dist/role.js +76 -0
  155. package/dist/runtime/action-deadlocks.d.ts +21 -0
  156. package/dist/runtime/action-deadlocks.js +130 -0
  157. package/dist/runtime/action-transactions.d.ts +35 -0
  158. package/dist/runtime/action-transactions.js +54 -0
  159. package/dist/runtime/agent-counters.d.ts +26 -0
  160. package/dist/runtime/agent-counters.js +98 -0
  161. package/dist/runtime/agent-tasks.d.ts +63 -0
  162. package/dist/runtime/agent-tasks.js +120 -0
  163. package/dist/runtime/agents.d.ts +15 -0
  164. package/dist/runtime/agents.js +457 -0
  165. package/dist/runtime/batch-diagnostics.d.ts +22 -0
  166. package/dist/runtime/batch-diagnostics.js +89 -0
  167. package/dist/runtime/batch.d.ts +52 -0
  168. package/dist/runtime/batch.js +534 -0
  169. package/dist/runtime/channel-session-revocation.d.ts +3 -0
  170. package/dist/runtime/channel-session-revocation.js +5 -0
  171. package/dist/runtime/channel-sessions.d.ts +4 -0
  172. package/dist/runtime/channel-sessions.js +61 -0
  173. package/dist/runtime/confirmations.d.ts +29 -0
  174. package/dist/runtime/confirmations.js +57 -0
  175. package/dist/runtime/cursor.d.ts +23 -0
  176. package/dist/runtime/cursor.js +100 -0
  177. package/dist/runtime/deployment.d.ts +7 -0
  178. package/dist/runtime/deployment.js +4 -0
  179. package/dist/runtime/errors.d.ts +118 -0
  180. package/dist/runtime/errors.js +109 -0
  181. package/dist/runtime/federation-tables.d.ts +2 -0
  182. package/dist/runtime/federation-tables.js +20 -0
  183. package/dist/runtime/federation.d.ts +42 -0
  184. package/dist/runtime/federation.js +222 -0
  185. package/dist/runtime/files.d.ts +39 -0
  186. package/dist/runtime/files.js +44 -0
  187. package/dist/runtime/generated-actions.d.ts +37 -0
  188. package/dist/runtime/generated-actions.js +307 -0
  189. package/dist/runtime/history.d.ts +91 -0
  190. package/dist/runtime/history.js +77 -0
  191. package/dist/runtime/ids.d.ts +6 -0
  192. package/dist/runtime/ids.js +39 -0
  193. package/dist/runtime/member-tables.d.ts +8 -0
  194. package/dist/runtime/member-tables.js +33 -0
  195. package/dist/runtime/member-writes.d.ts +78 -0
  196. package/dist/runtime/member-writes.js +202 -0
  197. package/dist/runtime/metric-query.d.ts +19 -0
  198. package/dist/runtime/metric-query.js +411 -0
  199. package/dist/runtime/model.d.ts +67 -0
  200. package/dist/runtime/model.js +150 -0
  201. package/dist/runtime/new-user-hook.d.ts +6 -0
  202. package/dist/runtime/new-user-hook.js +37 -0
  203. package/dist/runtime/oauth.d.ts +9 -0
  204. package/dist/runtime/oauth.js +299 -0
  205. package/dist/runtime/pipeline.d.ts +155 -0
  206. package/dist/runtime/pipeline.js +597 -0
  207. package/dist/runtime/postgres-tls.d.ts +10 -0
  208. package/dist/runtime/postgres-tls.js +14 -0
  209. package/dist/runtime/principals.d.ts +302 -0
  210. package/dist/runtime/principals.js +1307 -0
  211. package/dist/runtime/reads.d.ts +55 -0
  212. package/dist/runtime/reads.js +313 -0
  213. package/dist/runtime/records.d.ts +42 -0
  214. package/dist/runtime/records.js +245 -0
  215. package/dist/runtime/resolve-agent-identity.d.ts +6 -0
  216. package/dist/runtime/resolve-agent-identity.js +181 -0
  217. package/dist/runtime/service-binding.d.ts +18 -0
  218. package/dist/runtime/service-binding.js +266 -0
  219. package/dist/runtime/sign-in-links.d.ts +68 -0
  220. package/dist/runtime/sign-in-links.js +147 -0
  221. package/dist/runtime/sql-runtime.d.ts +131 -0
  222. package/dist/runtime/sql-runtime.js +362 -0
  223. package/dist/runtime/statement.d.ts +18 -0
  224. package/dist/runtime/statement.js +31 -0
  225. package/dist/runtime/user-identities.d.ts +66 -0
  226. package/dist/runtime/user-identities.js +106 -0
  227. package/dist/runtime/user-identity-sql.d.ts +86 -0
  228. package/dist/runtime/user-identity-sql.js +297 -0
  229. package/dist/runtime/user-roles.d.ts +16 -0
  230. package/dist/runtime/user-roles.js +32 -0
  231. package/dist/runtime/validation.d.ts +16 -0
  232. package/dist/runtime/validation.js +26 -0
  233. package/dist/runtime/where.d.ts +57 -0
  234. package/dist/runtime/where.js +404 -0
  235. package/dist/runtime/workflow-admission.d.ts +49 -0
  236. package/dist/runtime/workflow-admission.js +92 -0
  237. package/dist/runtime/workflow-argument-codec.d.ts +10 -0
  238. package/dist/runtime/workflow-argument-codec.js +120 -0
  239. package/dist/runtime/workflow-arguments.d.ts +17 -0
  240. package/dist/runtime/workflow-arguments.js +99 -0
  241. package/dist/runtime/workflow-starts.d.ts +203 -0
  242. package/dist/runtime/workflow-starts.js +493 -0
  243. package/dist/runtime/workflow-users.d.ts +9 -0
  244. package/dist/runtime/workflow-users.js +17 -0
  245. package/dist/runtime/workload.d.ts +25 -0
  246. package/dist/runtime/workload.js +24 -0
  247. package/dist/runtime/writes.d.ts +108 -0
  248. package/dist/runtime/writes.js +491 -0
  249. package/dist/runtime-source.d.ts +22 -0
  250. package/dist/runtime-source.js +28 -0
  251. package/dist/runtime.d.ts +310 -0
  252. package/dist/runtime.js +31 -0
  253. package/dist/server.d.ts +23 -0
  254. package/dist/server.js +107 -0
  255. package/dist/service/agent/attachments.d.ts +33 -0
  256. package/dist/service/agent/attachments.js +228 -0
  257. package/dist/service/agent/authentication.d.ts +22 -0
  258. package/dist/service/agent/authentication.js +58 -0
  259. package/dist/service/agent/confirmations.d.ts +5 -0
  260. package/dist/service/agent/confirmations.js +73 -0
  261. package/dist/service/agent/conversation-routes.d.ts +14 -0
  262. package/dist/service/agent/conversation-routes.js +45 -0
  263. package/dist/service/agent/conversations.d.ts +40 -0
  264. package/dist/service/agent/conversations.js +69 -0
  265. package/dist/service/agent/files.d.ts +12 -0
  266. package/dist/service/agent/files.js +69 -0
  267. package/dist/service/agent/protocol.d.ts +90 -0
  268. package/dist/service/agent/protocol.js +114 -0
  269. package/dist/service/agent/server.d.ts +28 -0
  270. package/dist/service/agent/server.js +374 -0
  271. package/dist/service/agent/task-caller.d.ts +21 -0
  272. package/dist/service/agent/task-caller.js +35 -0
  273. package/dist/service/agent/task-start.d.ts +53 -0
  274. package/dist/service/agent/task-start.js +161 -0
  275. package/dist/service/agent/tasks.d.ts +40 -0
  276. package/dist/service/agent/tasks.js +155 -0
  277. package/dist/service/api.d.ts +50 -0
  278. package/dist/service/api.js +288 -0
  279. package/dist/service/authentication.d.ts +227 -0
  280. package/dist/service/authentication.js +767 -0
  281. package/dist/service/caller-context.d.ts +24 -0
  282. package/dist/service/caller-context.js +6 -0
  283. package/dist/service/catalog.d.ts +42 -0
  284. package/dist/service/catalog.js +66 -0
  285. package/dist/service/channel/provider.d.ts +10 -0
  286. package/dist/service/channel/provider.js +1 -0
  287. package/dist/service/channel/providers/telegram.d.ts +18 -0
  288. package/dist/service/channel/providers/telegram.js +108 -0
  289. package/dist/service/channel/sessions.d.ts +5 -0
  290. package/dist/service/channel/sessions.js +53 -0
  291. package/dist/service/channel/sign-in.d.ts +7 -0
  292. package/dist/service/channel/sign-in.js +78 -0
  293. package/dist/service/chat/archive.d.ts +64 -0
  294. package/dist/service/chat/archive.js +62 -0
  295. package/dist/service/chat/attribution.d.ts +26 -0
  296. package/dist/service/chat/attribution.js +28 -0
  297. package/dist/service/chat/delivery.d.ts +18 -0
  298. package/dist/service/chat/delivery.js +251 -0
  299. package/dist/service/chat/diagnostics.d.ts +2 -0
  300. package/dist/service/chat/diagnostics.js +35 -0
  301. package/dist/service/chat/envelope.d.ts +96 -0
  302. package/dist/service/chat/envelope.js +39 -0
  303. package/dist/service/chat/idempotency.d.ts +19 -0
  304. package/dist/service/chat/idempotency.js +37 -0
  305. package/dist/service/chat/providers/telegram.d.ts +36 -0
  306. package/dist/service/chat/providers/telegram.js +133 -0
  307. package/dist/service/chat/reads.d.ts +25 -0
  308. package/dist/service/chat/reads.js +75 -0
  309. package/dist/service/chat/resolve.d.ts +34 -0
  310. package/dist/service/chat/resolve.js +150 -0
  311. package/dist/service/chat/routes.d.ts +23 -0
  312. package/dist/service/chat/routes.js +75 -0
  313. package/dist/service/chat/schemas.d.ts +43 -0
  314. package/dist/service/chat/schemas.js +31 -0
  315. package/dist/service/config.d.ts +218 -0
  316. package/dist/service/config.js +265 -0
  317. package/dist/service/connection-stream.d.ts +10 -0
  318. package/dist/service/connection-stream.js +191 -0
  319. package/dist/service/connections.d.ts +60 -0
  320. package/dist/service/connections.js +271 -0
  321. package/dist/service/decisions.d.ts +35 -0
  322. package/dist/service/decisions.js +63 -0
  323. package/dist/service/descriptions.d.ts +8 -0
  324. package/dist/service/descriptions.js +20 -0
  325. package/dist/service/discovery-schemas.d.ts +92 -0
  326. package/dist/service/discovery-schemas.js +59 -0
  327. package/dist/service/discovery-search.d.ts +30 -0
  328. package/dist/service/discovery-search.js +95 -0
  329. package/dist/service/discovery.d.ts +37 -0
  330. package/dist/service/discovery.js +436 -0
  331. package/dist/service/docs.d.ts +9 -0
  332. package/dist/service/docs.js +197 -0
  333. package/dist/service/errors.d.ts +145 -0
  334. package/dist/service/errors.js +704 -0
  335. package/dist/service/federation-provider.d.ts +36 -0
  336. package/dist/service/federation-provider.js +110 -0
  337. package/dist/service/federation-server.d.ts +20 -0
  338. package/dist/service/federation-server.js +249 -0
  339. package/dist/service/federation-status.d.ts +40 -0
  340. package/dist/service/federation-status.js +151 -0
  341. package/dist/service/handlers.d.ts +18 -0
  342. package/dist/service/handlers.js +287 -0
  343. package/dist/service/mcp/confirmation.d.ts +68 -0
  344. package/dist/service/mcp/confirmation.js +178 -0
  345. package/dist/service/mcp/find-input.d.ts +12 -0
  346. package/dist/service/mcp/find-input.js +122 -0
  347. package/dist/service/mcp/input-schema.d.ts +6 -0
  348. package/dist/service/mcp/input-schema.js +126 -0
  349. package/dist/service/mcp/listing.d.ts +26 -0
  350. package/dist/service/mcp/listing.js +92 -0
  351. package/dist/service/mcp/metric-tools.d.ts +85 -0
  352. package/dist/service/mcp/metric-tools.js +258 -0
  353. package/dist/service/mcp/request-log.d.ts +5 -0
  354. package/dist/service/mcp/request-log.js +53 -0
  355. package/dist/service/mcp/runtime-policy.d.ts +27 -0
  356. package/dist/service/mcp/runtime-policy.js +62 -0
  357. package/dist/service/mcp/server.d.ts +52 -0
  358. package/dist/service/mcp/server.js +861 -0
  359. package/dist/service/mcp/tools.d.ts +99 -0
  360. package/dist/service/mcp/tools.js +938 -0
  361. package/dist/service/member-file-routes.d.ts +22 -0
  362. package/dist/service/member-file-routes.js +52 -0
  363. package/dist/service/member-files.d.ts +245 -0
  364. package/dist/service/member-files.js +258 -0
  365. package/dist/service/metric-query-platform.d.ts +77 -0
  366. package/dist/service/metric-query-platform.js +198 -0
  367. package/dist/service/metric-query-scopes.d.ts +43 -0
  368. package/dist/service/metric-query-scopes.js +147 -0
  369. package/dist/service/metric-query.d.ts +48 -0
  370. package/dist/service/metric-query.js +200 -0
  371. package/dist/service/name-suggestions.d.ts +3 -0
  372. package/dist/service/name-suggestions.js +38 -0
  373. package/dist/service/navigation-schemas.d.ts +80 -0
  374. package/dist/service/navigation-schemas.js +49 -0
  375. package/dist/service/navigation.d.ts +20 -0
  376. package/dist/service/navigation.js +165 -0
  377. package/dist/service/oauth/protocol.d.ts +70 -0
  378. package/dist/service/oauth/protocol.js +157 -0
  379. package/dist/service/oauth/refresh-replay.d.ts +2 -0
  380. package/dist/service/oauth/refresh-replay.js +20 -0
  381. package/dist/service/oauth/server.d.ts +28 -0
  382. package/dist/service/oauth/server.js +769 -0
  383. package/dist/service/operations.d.ts +170 -0
  384. package/dist/service/operations.js +392 -0
  385. package/dist/service/plan.d.ts +57 -0
  386. package/dist/service/plan.js +96 -0
  387. package/dist/service/rate-limit.d.ts +22 -0
  388. package/dist/service/rate-limit.js +52 -0
  389. package/dist/service/record-reads.d.ts +21 -0
  390. package/dist/service/record-reads.js +155 -0
  391. package/dist/service/replication.d.ts +5 -0
  392. package/dist/service/replication.js +39 -0
  393. package/dist/service/runtime-contract.d.ts +508 -0
  394. package/dist/service/runtime-contract.js +18 -0
  395. package/dist/service/runtime-identity.d.ts +71 -0
  396. package/dist/service/runtime-identity.js +122 -0
  397. package/dist/service/schemas.d.ts +961 -0
  398. package/dist/service/schemas.js +639 -0
  399. package/dist/service/service.d.ts +21 -0
  400. package/dist/service/service.js +526 -0
  401. package/dist/service/warehouse-platform.d.ts +17 -0
  402. package/dist/service/warehouse-platform.js +122 -0
  403. package/dist/service/warehouse-query.d.ts +24 -0
  404. package/dist/service/warehouse-query.js +280 -0
  405. package/dist/service/webhooks.d.ts +106 -0
  406. package/dist/service/webhooks.js +233 -0
  407. package/dist/service/workflow-admission-provider.d.ts +31 -0
  408. package/dist/service/workflow-admission-provider.js +205 -0
  409. package/dist/service/workflow-argument-serialization.d.ts +2 -0
  410. package/dist/service/workflow-argument-serialization.js +14 -0
  411. package/dist/service/workflow-callback.d.ts +22 -0
  412. package/dist/service/workflow-callback.js +75 -0
  413. package/dist/service/workflow-deployment.d.ts +8 -0
  414. package/dist/service/workflow-deployment.js +131 -0
  415. package/dist/service/workflow-diagnostics.d.ts +23 -0
  416. package/dist/service/workflow-diagnostics.js +263 -0
  417. package/dist/service/workflow-errors.d.ts +26 -0
  418. package/dist/service/workflow-errors.js +181 -0
  419. package/dist/service/workflow-logging.d.ts +2 -0
  420. package/dist/service/workflow-logging.js +50 -0
  421. package/dist/service/workflow-queue-fence.d.ts +6 -0
  422. package/dist/service/workflow-queue-fence.js +66 -0
  423. package/dist/service/workflows.d.ts +200 -0
  424. package/dist/service/workflows.js +1549 -0
  425. package/dist/sign-in.d.ts +58 -0
  426. package/dist/sign-in.js +57 -0
  427. package/dist/source.d.ts +30 -0
  428. package/dist/source.js +107 -0
  429. package/dist/start-recovery-contract.d.ts +49 -0
  430. package/dist/start-recovery-contract.js +26 -0
  431. package/dist/start-recovery.d.ts +27 -0
  432. package/dist/start-recovery.js +81 -0
  433. package/dist/storage/api.d.ts +4 -0
  434. package/dist/storage/api.js +40 -0
  435. package/dist/storage/attachments.d.ts +146 -0
  436. package/dist/storage/attachments.js +733 -0
  437. package/dist/storage/authorization.d.ts +38 -0
  438. package/dist/storage/authorization.js +83 -0
  439. package/dist/storage/file-access.d.ts +17 -0
  440. package/dist/storage/file-access.js +8 -0
  441. package/dist/storage/limits.d.ts +12 -0
  442. package/dist/storage/limits.js +17 -0
  443. package/dist/storage/maintenance-auth.d.ts +20 -0
  444. package/dist/storage/maintenance-auth.js +24 -0
  445. package/dist/storage/maintenance.d.ts +11 -0
  446. package/dist/storage/maintenance.js +67 -0
  447. package/dist/storage/neon.d.ts +4 -0
  448. package/dist/storage/neon.js +318 -0
  449. package/dist/storage/operator.d.ts +11 -0
  450. package/dist/storage/operator.js +30 -0
  451. package/dist/storage/provider.d.ts +93 -0
  452. package/dist/storage/provider.js +36 -0
  453. package/dist/storage/sessions.d.ts +184 -0
  454. package/dist/storage/sessions.js +688 -0
  455. package/dist/storage/tables.d.ts +54 -0
  456. package/dist/storage/tables.js +205 -0
  457. package/dist/storage/transfers.d.ts +16 -0
  458. package/dist/storage/transfers.js +153 -0
  459. package/dist/storage/writes.d.ts +7 -0
  460. package/dist/storage/writes.js +88 -0
  461. package/dist/telegram.d.ts +35 -0
  462. package/dist/telegram.js +173 -0
  463. package/dist/user-identity.d.ts +28 -0
  464. package/dist/user-identity.js +106 -0
  465. package/dist/user.d.ts +75 -0
  466. package/dist/user.js +111 -0
  467. package/dist/warehouse-backed.d.ts +6 -0
  468. package/dist/warehouse-backed.js +495 -0
  469. package/dist/webhook-token.d.ts +11 -0
  470. package/dist/webhook-token.js +18 -0
  471. package/dist/webhooks.d.ts +40 -0
  472. package/dist/webhooks.js +55 -0
  473. package/dist/wire.d.ts +10 -0
  474. package/dist/wire.js +35 -0
  475. package/dist/workflow-runtime.d.ts +116 -0
  476. package/dist/workflow-runtime.js +109 -0
  477. package/dist/workflow-topics.d.ts +28 -0
  478. package/dist/workflow-topics.js +28 -0
  479. package/dist/workflow.d.ts +284 -0
  480. package/dist/workflow.js +259 -0
  481. package/dist/workflows.d.ts +24 -0
  482. package/dist/workflows.js +18 -0
  483. package/package.json +127 -4
@@ -0,0 +1,55 @@
1
+ import { Effect } from "effect";
2
+ import type { SqlError } from "effect/unstable/sql/SqlError";
3
+ import { NotFound } from "../errors.js";
4
+ import { type Query, type QueryResult } from "../query.js";
5
+ import type { StoredRecord } from "../runtime.js";
6
+ import { InvalidQuery } from "./errors.js";
7
+ import { HistoryEntry } from "./history.js";
8
+ import { type EntityModel, type LinkModel, type OntologyModel } from "./model.js";
9
+ import { type Row } from "./records.js";
10
+ import { Params } from "./statement.js";
11
+ import { type RowScope, type ScopeReader } from "./where.js";
12
+ /** What reads and writes run against: the ontology's model and one SQL client. */
13
+ export interface SqlContext {
14
+ readonly model: OntologyModel;
15
+ readonly run: (text: string, params: Params) => Effect.Effect<ReadonlyArray<Row>, SqlError>;
16
+ /**
17
+ * The caller whose read scopes the reads honour: only the rows inside them exist for it. Absent
18
+ * for reads with the action's authority and for callers without scoped permissions.
19
+ */
20
+ readonly reader?: ScopeReader;
21
+ }
22
+ export type RowLock = "update" | "key share";
23
+ export declare function notFound(entity: EntityModel, id: string): NotFound;
24
+ /** Record ids as PostgreSQL prints them, so that ids compare as strings. */
25
+ export declare function normalizeId(id: string): string;
26
+ /**
27
+ * One record by id, optionally locked until the transaction ends. With a scope, a record outside it
28
+ * is not found.
29
+ */
30
+ export declare function loadRecord(context: SqlContext, entity: EntityModel, id: string, lock?: RowLock, scope?: RowScope): Effect.Effect<StoredRecord | undefined, SqlError>;
31
+ /**
32
+ * Fails with NotFound unless every record exists, and keeps them from being deleted until the
33
+ * transaction ends (`FOR KEY SHARE`), so that a key written to them stays valid.
34
+ */
35
+ export declare function requireRecords(context: SqlContext, entity: EntityModel, ids: ReadonlyArray<string>): Effect.Effect<void, NotFound | SqlError>;
36
+ /** Checks a query against the entity's query schema. */
37
+ export declare function validateQuery(entity: EntityModel, input: unknown): Effect.Effect<Query, InvalidQuery>;
38
+ export interface QueryOptions {
39
+ /** Lock the matching records until the transaction ends. */
40
+ readonly forUpdate?: boolean;
41
+ /** A further condition on the table aliased `t0`, such as a relationship to one record. */
42
+ readonly condition?: (params: Params) => string;
43
+ }
44
+ /** A page of the entity's records matching a validated query. */
45
+ export declare function runQuery(context: SqlContext, entity: EntityModel, query: Query, options?: QueryOptions): Effect.Effect<QueryResult<StoredRecord>, InvalidQuery | SqlError>;
46
+ /** Included to-many relationships return at most this many records per record. */
47
+ export declare const MAX_INCLUDED = 200;
48
+ /** The condition that a target record is related to `id` through `link`, for traversal. */
49
+ export declare function relatedCondition(link: LinkModel, id: string, keyValue: string | null): (params: Params) => string;
50
+ /** A page of a record's history, newest first. A deleted record keeps its history. */
51
+ export declare function readHistory(context: SqlContext, entity: EntityModel, input: {
52
+ readonly id: string;
53
+ readonly after?: string;
54
+ readonly limit?: number;
55
+ }): Effect.Effect<QueryResult<HistoryEntry>, InvalidQuery | SqlError>;
@@ -0,0 +1,313 @@
1
+ import { Effect, Schema } from "effect";
2
+ import { NotFound } from "../errors.js";
3
+ import { DEFAULT_QUERY_LIMIT, MAX_QUERY_LIMIT, includedRelationships, isInstant, } from "../query.js";
4
+ import { quoteIdentifier } from "../migrate/storage.js";
5
+ import { afterCondition, decodeCursor, encodeCursor, orderByClause, sortKeys } from "./cursor.js";
6
+ import { InvalidQuery } from "./errors.js";
7
+ import { HistoryEntry } from "./history.js";
8
+ import { entityModel } from "./model.js";
9
+ import { canonicalInstant, decodeRecord, decodeRecords, isRecordId, selectList, } from "./records.js";
10
+ import { Aliases, columnOf, Params } from "./statement.js";
11
+ import { validate } from "./validation.js";
12
+ import { compileScope, compileWhere, readScopeOf, } from "./where.js";
13
+ /** The condition `scope` puts on the table aliased `t0`, compiled into `params`. */
14
+ function scopeOnT0(context, entity, params, scope) {
15
+ const aliases = new Aliases();
16
+ aliases.take(); // t0
17
+ return compileScope({ model: context.model, params, aliases }, entity, "t0", scope);
18
+ }
19
+ function lockClause(lock, alias) {
20
+ if (lock === undefined) {
21
+ return "";
22
+ }
23
+ return ` FOR ${lock === "update" ? "UPDATE" : "KEY SHARE"} OF ${quoteIdentifier(alias)}`;
24
+ }
25
+ export function notFound(entity, id) {
26
+ return new NotFound({
27
+ entity: entity.name,
28
+ id,
29
+ message: `There is no ${entity.label.toLowerCase()} with the id ${id}.`,
30
+ });
31
+ }
32
+ /** Record ids as PostgreSQL prints them, so that ids compare as strings. */
33
+ export function normalizeId(id) {
34
+ return id.toLowerCase();
35
+ }
36
+ /**
37
+ * One record by id, optionally locked until the transaction ends. With a scope, a record outside it
38
+ * is not found.
39
+ */
40
+ export function loadRecord(context, entity, id, lock, scope) {
41
+ return Effect.gen(function* () {
42
+ if (!isRecordId(id)) {
43
+ return undefined;
44
+ }
45
+ const params = new Params();
46
+ const key = `"t0"."id" = ${params.add(normalizeId(id), "uuid")}`;
47
+ const condition = scope === undefined ? key : `${key} AND (${scopeOnT0(context, entity, params, scope)})`;
48
+ const rows = yield* context.run(`SELECT ${selectList(entity, "t0")} ` +
49
+ `FROM ${quoteIdentifier(entity.table)} AS "t0" ` +
50
+ `WHERE ${condition}${lockClause(lock, "t0")}`, params);
51
+ const [row] = rows;
52
+ return row === undefined ? undefined : yield* decodeRecord(entity, row);
53
+ });
54
+ }
55
+ /**
56
+ * Fails with NotFound unless every record exists, and keeps them from being deleted until the
57
+ * transaction ends (`FOR KEY SHARE`), so that a key written to them stays valid.
58
+ */
59
+ export function requireRecords(context, entity, ids) {
60
+ return Effect.gen(function* () {
61
+ const wanted = [...new Set(ids.map(normalizeId))];
62
+ const malformed = wanted.find((id) => !isRecordId(id));
63
+ if (malformed !== undefined) {
64
+ return yield* notFound(entity, malformed);
65
+ }
66
+ if (wanted.length === 0) {
67
+ return;
68
+ }
69
+ const params = new Params();
70
+ const placeholders = wanted.map((id) => params.add(id, "uuid"));
71
+ const rows = yield* context.run(`SELECT "t0"."id"::text AS "id" FROM ${quoteIdentifier(entity.table)} AS "t0" ` +
72
+ `WHERE "t0"."id" IN (${placeholders.join(", ")})${lockClause("key share", "t0")}`, params);
73
+ const found = new Set(rows.map((row) => row.id));
74
+ const missing = wanted.find((id) => !found.has(id));
75
+ if (missing !== undefined) {
76
+ return yield* notFound(entity, missing);
77
+ }
78
+ });
79
+ }
80
+ /** Checks a query against the entity's query schema. */
81
+ export function validateQuery(entity, input) {
82
+ const validated = validate(entity.querySchema, input);
83
+ if (validated.ok) {
84
+ return Effect.succeed(validated.value);
85
+ }
86
+ return Effect.fail(new InvalidQuery({
87
+ entity: entity.name,
88
+ message: `The query does not fit ${entity.name}.`,
89
+ issues: validated.issues,
90
+ }));
91
+ }
92
+ /** A page of the entity's records matching a validated query. */
93
+ export function runQuery(context, entity, query, options = {}) {
94
+ return Effect.gen(function* () {
95
+ const keys = sortKeys(entity, query.orderBy);
96
+ const requested = query.select === undefined ? undefined : new Set(["id", ...query.select]);
97
+ const needed = new Set([...(requested ?? []), ...keys.map(({ field }) => field.name)]);
98
+ for (const name of includedRelationships(query.include)) {
99
+ if (entity.links.get(name)?.via === "key") {
100
+ needed.add(`${name}_id`);
101
+ }
102
+ }
103
+ const fields = requested === undefined
104
+ ? entity.fields
105
+ : entity.fields.filter((field) => needed.has(field.name));
106
+ const limit = Math.min(query.limit ?? DEFAULT_QUERY_LIMIT, MAX_QUERY_LIMIT);
107
+ const params = new Params();
108
+ const aliases = new Aliases();
109
+ const alias = aliases.take();
110
+ const where = {
111
+ model: context.model,
112
+ params,
113
+ aliases,
114
+ ...(context.reader === undefined ? {} : { reader: context.reader }),
115
+ };
116
+ const conditions = [compileWhere(where, entity, alias, query.where)];
117
+ const scope = readScopeOf(context.reader, entity);
118
+ if (scope !== undefined) {
119
+ conditions.push(compileScope(where, entity, alias, scope));
120
+ }
121
+ if (options.condition !== undefined) {
122
+ conditions.push(options.condition(params));
123
+ }
124
+ if (query.after !== undefined) {
125
+ const values = decodeCursor(keys, query.after);
126
+ if (values === undefined) {
127
+ return yield* new InvalidQuery({
128
+ entity: entity.name,
129
+ message: "The cursor was not issued for this query.",
130
+ issues: [{ path: ["after"], message: "Expected the nextCursor of the same query" }],
131
+ });
132
+ }
133
+ conditions.push(afterCondition(keys, values, alias, params));
134
+ }
135
+ const rows = yield* context.run(`SELECT ${selectList(entity, alias, fields)} ` +
136
+ `FROM ${quoteIdentifier(entity.table)} AS ${quoteIdentifier(alias)} ` +
137
+ `WHERE ${conditions.map((condition) => `(${condition})`).join(" AND ")} ` +
138
+ `ORDER BY ${orderByClause(keys, alias)} ` +
139
+ `LIMIT ${params.add(limit + 1, "bigint")}` +
140
+ lockClause(options.forUpdate === true ? "update" : undefined, alias), params);
141
+ const records = yield* requested === undefined
142
+ ? decodeRecords(entity, rows.slice(0, limit))
143
+ : Effect.forEach(rows.slice(0, limit), (row) => decodeRecord(entity, row, fields));
144
+ const last = records[records.length - 1];
145
+ const nextCursor = rows.length > limit && last !== undefined ? encodeCursor(keys, last) : null;
146
+ const items = yield* includeRelated(context, entity, records, query.include);
147
+ if (requested === undefined) {
148
+ return { items, nextCursor };
149
+ }
150
+ for (const name of includedRelationships(query.include)) {
151
+ requested.add(name);
152
+ }
153
+ return {
154
+ items: items.map((record) => Object.fromEntries(Object.entries(record).filter(([name]) => requested.has(name)))),
155
+ nextCursor,
156
+ projected: true,
157
+ };
158
+ });
159
+ }
160
+ /** Included to-many relationships return at most this many records per record. */
161
+ export const MAX_INCLUDED = MAX_QUERY_LIMIT;
162
+ function includeRelated(context, entity, records, include) {
163
+ return Effect.gen(function* () {
164
+ const names = includedRelationships(include);
165
+ let items = [...records];
166
+ if (records.length === 0) {
167
+ return items;
168
+ }
169
+ for (const name of names) {
170
+ const link = entity.links.get(name);
171
+ const related = yield* loadRelated(context, link, records);
172
+ items = items.map((record) => ({ ...record, [name]: related(record) }));
173
+ }
174
+ return items;
175
+ });
176
+ }
177
+ /** Loads the records related through one link to all of `records` in one query. */
178
+ function loadRelated(context, link, records) {
179
+ return Effect.gen(function* () {
180
+ const target = entityModel(context.model, link.target);
181
+ const params = new Params();
182
+ const scope = readScopeOf(context.reader, target);
183
+ // A related record outside the reader's scope is left out: a to-one include is null.
184
+ const visible = scope === undefined ? "" : ` AND (${scopeOnT0(context, target, params, scope)})`;
185
+ if (link.via === "key") {
186
+ const keyField = `${link.name}_id`;
187
+ const ids = [...new Set(records.map((record) => record[keyField]).filter(isString))];
188
+ const byId = new Map();
189
+ if (ids.length > 0) {
190
+ const rows = yield* context.run(`SELECT ${selectList(target, "t0")} FROM ${quoteIdentifier(target.table)} AS "t0" ` +
191
+ `WHERE "t0"."id" IN (${ids.map((id) => params.add(id, "uuid")).join(", ")})${visible}`, params);
192
+ for (const related of yield* decodeRecords(target, rows)) {
193
+ byId.set(related.id, related);
194
+ }
195
+ }
196
+ return (record) => byId.get(record[keyField]) ?? null;
197
+ }
198
+ const ids = records.map((record) => params.add(record.id, "uuid")).join(", ");
199
+ const ranked = link.via === "join"
200
+ ? `SELECT ${columnOf("j", link.selfColumn)}::text AS "__source", ${selectList(target, "t0")}, ` +
201
+ `row_number() OVER (PARTITION BY ${columnOf("j", link.selfColumn)} ` +
202
+ `ORDER BY ${columnOf("j", "created_at")}, "t0"."id") AS "__rank" ` +
203
+ `FROM ${quoteIdentifier(link.table)} AS "j" ` +
204
+ `JOIN ${quoteIdentifier(target.table)} AS "t0" ON "t0"."id" = ${columnOf("j", link.otherColumn)} ` +
205
+ `WHERE ${columnOf("j", link.selfColumn)} IN (${ids})${visible}`
206
+ : `SELECT ${columnOf("t0", link.column)}::text AS "__source", ${selectList(target, "t0")}, ` +
207
+ `row_number() OVER (PARTITION BY ${columnOf("t0", link.column)} ` +
208
+ `ORDER BY "t0"."created_at", "t0"."id") AS "__rank" ` +
209
+ `FROM ${quoteIdentifier(target.table)} AS "t0" ` +
210
+ `WHERE ${columnOf("t0", link.column)} IN (${ids})${visible}`;
211
+ const rows = yield* context.run(`SELECT * FROM (${ranked}) AS "ranked" ` +
212
+ `WHERE "ranked"."__rank" <= ${params.add(MAX_INCLUDED, "bigint")} ` +
213
+ `ORDER BY "ranked"."__source", "ranked"."__rank"`, params);
214
+ const bySource = new Map();
215
+ for (const row of rows) {
216
+ const related = yield* decodeRecord(target, row);
217
+ const source = row.__source;
218
+ const list = bySource.get(source) ?? [];
219
+ list.push(related);
220
+ bySource.set(source, list);
221
+ }
222
+ return (record) => bySource.get(record.id) ?? [];
223
+ });
224
+ }
225
+ function isString(value) {
226
+ return typeof value === "string";
227
+ }
228
+ /** The condition that a target record is related to `id` through `link`, for traversal. */
229
+ export function relatedCondition(link, id, keyValue) {
230
+ return (params) => {
231
+ if (link.via === "key") {
232
+ return keyValue === null ? "FALSE" : `"t0"."id" = ${params.add(keyValue, "uuid")}`;
233
+ }
234
+ if (link.via === "inverse-key") {
235
+ return `${columnOf("t0", link.column)} = ${params.add(id, "uuid")}`;
236
+ }
237
+ return (`EXISTS (SELECT 1 FROM ${quoteIdentifier(link.table)} AS "j" ` +
238
+ `WHERE ${columnOf("j", link.otherColumn)} = "t0"."id" ` +
239
+ `AND ${columnOf("j", link.selfColumn)} = ${params.add(id, "uuid")})`);
240
+ };
241
+ }
242
+ const HistoryCursor = Schema.Tuple([Schema.String, Schema.String]);
243
+ function encodeHistoryCursor(entry) {
244
+ return Buffer.from(JSON.stringify([entry.at, entry.id]), "utf8").toString("base64url");
245
+ }
246
+ function decodeHistoryCursor(cursor) {
247
+ try {
248
+ const value = JSON.parse(Buffer.from(cursor, "base64url").toString("utf8"));
249
+ return Schema.is(HistoryCursor)(value) && isInstant(value[0]) && isRecordId(value[1])
250
+ ? value
251
+ : undefined;
252
+ }
253
+ catch {
254
+ return undefined;
255
+ }
256
+ }
257
+ /** A page of a record's history, newest first. A deleted record keeps its history. */
258
+ export function readHistory(context, entity, input) {
259
+ return Effect.gen(function* () {
260
+ const limit = input.limit ?? DEFAULT_QUERY_LIMIT;
261
+ if (!Number.isInteger(limit) || limit < 1 || limit > MAX_QUERY_LIMIT) {
262
+ return yield* new InvalidQuery({
263
+ entity: entity.name,
264
+ message: "The limit is out of range.",
265
+ issues: [{ path: ["limit"], message: `Expected a value between 1 and ${MAX_QUERY_LIMIT}` }],
266
+ });
267
+ }
268
+ if (!isRecordId(input.id)) {
269
+ return { items: [], nextCursor: null };
270
+ }
271
+ const params = new Params();
272
+ const conditions = [`"h"."record_id" = ${params.add(normalizeId(input.id), "uuid")}`];
273
+ if (input.after !== undefined) {
274
+ const cursor = decodeHistoryCursor(input.after);
275
+ if (cursor === undefined) {
276
+ return yield* new InvalidQuery({
277
+ entity: entity.name,
278
+ message: "The cursor was not issued for this history.",
279
+ issues: [{ path: ["after"], message: "Expected the nextCursor of the previous page" }],
280
+ });
281
+ }
282
+ const at = params.add(cursor[0], "timestamptz");
283
+ conditions.push(`("h"."at" < ${at} OR ("h"."at" = ${at} AND "h"."id" < ${params.add(cursor[1], "uuid")}))`);
284
+ }
285
+ const presenceParams = new Params();
286
+ const [presence] = yield* context.run("SELECT to_regclass('_ontology_action_attribution') IS NOT NULL AS present", presenceParams);
287
+ const attribution = presence?.present === true;
288
+ const rows = yield* context.run(`SELECT "h"."id"::text AS "id", "h"."record_id"::text AS "recordId", "h"."action" AS "action", ` +
289
+ `"h"."action_id"::text AS "actionId", "h"."kind" AS "kind", ` +
290
+ `"h"."principal_id"::text AS "principalId", ` +
291
+ `to_char("h"."at" AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.US"Z"') AS "at", ` +
292
+ `"h"."changes"::text AS "changes" ` +
293
+ (attribution ? `, "a"."execution" AS "execution" ` : "") +
294
+ `FROM ${quoteIdentifier(entity.historyTable)} AS "h" ` +
295
+ (attribution
296
+ ? `LEFT JOIN "_ontology_action_attribution" AS "a" ON "a"."action_id" = "h"."action_id" `
297
+ : "") +
298
+ `WHERE ${conditions.join(" AND ")} ` +
299
+ `ORDER BY "h"."at" DESC, "h"."id" DESC ` +
300
+ `LIMIT ${params.add(limit + 1, "bigint")}`, params);
301
+ const items = rows.slice(0, limit).map((row) => Schema.decodeUnknownSync(HistoryEntry)({
302
+ ...Object.fromEntries(Object.entries(row).filter(([key, value]) => key !== "execution" || value != null)),
303
+ ...(row.execution == null ? {} : { execution: row.execution }),
304
+ at: canonicalInstant(String(row.at)),
305
+ changes: JSON.parse(String(row.changes)),
306
+ }));
307
+ const last = items[items.length - 1];
308
+ return {
309
+ items,
310
+ nextCursor: rows.length > limit && last !== undefined ? encodeHistoryCursor(last) : null,
311
+ };
312
+ });
313
+ }
@@ -0,0 +1,42 @@
1
+ import { Effect } from "effect";
2
+ import type { StoredRecord, StoredValues } from "../runtime.js";
3
+ import { type EntityModel, type FieldModel, type JoinLink, type KeyLink } from "./model.js";
4
+ export type Row = Readonly<Record<string, unknown>>;
5
+ /** The select list of an entity's records from the table aliased `alias`. */
6
+ export declare function selectList(entity: EntityModel, alias: string, fields?: ReadonlyArray<FieldModel>): string;
7
+ /** `2026-10-04T09:30:00.120000Z` → `2026-10-04T09:30:00.120Z`: milliseconds, then any further digits. */
8
+ export declare function canonicalInstant(value: string): string;
9
+ /** Decodes a row read with {@link selectList} against the entity's record schema. */
10
+ export declare function decodeRecord(entity: EntityModel, row: Row, fields?: ReadonlyArray<FieldModel>): Effect.Effect<StoredRecord>;
11
+ export declare function decodeRecords(entity: EntityModel, rows: ReadonlyArray<Row>): Effect.Effect<Array<StoredRecord>>;
12
+ /** The parameter a value of a field is bound as. JSON is bound as text and cast to `jsonb`. */
13
+ export declare function bindValue(field: FieldModel, value: unknown): unknown;
14
+ export interface ColumnWrite {
15
+ readonly field: FieldModel;
16
+ readonly value: unknown;
17
+ }
18
+ export interface CollectionWrite {
19
+ readonly link: JoinLink;
20
+ readonly ids: ReadonlyArray<string>;
21
+ }
22
+ export interface ReferenceWrite {
23
+ readonly link: KeyLink;
24
+ readonly id: string;
25
+ }
26
+ /** Values of a write, checked against the entity and split by where they are stored. */
27
+ export interface PreparedWrite {
28
+ readonly columns: ReadonlyArray<ColumnWrite>;
29
+ /** `rel.many` collections to set. */
30
+ readonly collections: ReadonlyArray<CollectionWrite>;
31
+ /** `rel.one` targets that must exist. */
32
+ readonly references: ReadonlyArray<ReferenceWrite>;
33
+ }
34
+ /**
35
+ * Checks the values a handler writes. Properties take their property's values, `rel.one`
36
+ * relationships a record id (or `null` when optional), `rel.many` relationships a list of ids,
37
+ * which replaces the collection. `undefined` leaves a value as it is; on create, a property without
38
+ * a value takes its default, or `null` when optional. Anything else is a defect in the handler.
39
+ */
40
+ export declare function prepareWrite(entity: EntityModel, values: StoredValues, mode: "create" | "update"): Effect.Effect<PreparedWrite>;
41
+ /** Whether a string can be a record id. Anything else names no record. */
42
+ export declare function isRecordId(value: string): boolean;
@@ -0,0 +1,245 @@
1
+ import { Effect, Schema } from "effect";
2
+ import { isCalendarDate, isInstant, isUuid } from "../query.js";
3
+ import { quoteIdentifier } from "../migrate/storage.js";
4
+ import { InvalidValues, StoredRecordMismatch } from "./errors.js";
5
+ import { propertyValueSchema, } from "./model.js";
6
+ import { columnOf } from "./statement.js";
7
+ import { userRolesExpression } from "./user-roles.js";
8
+ import { validate } from "./validation.js";
9
+ const projectionSchemas = new WeakMap();
10
+ function projectionSchema(entity, fields) {
11
+ if (fields === entity.fields) {
12
+ return entity.recordSchema;
13
+ }
14
+ const key = fields.map((field) => field.name).join(",");
15
+ const cached = projectionSchemas.get(entity) ?? new Map();
16
+ const existing = cached.get(key);
17
+ if (existing !== undefined) {
18
+ return existing;
19
+ }
20
+ // entityRecordSchema builds a Struct; derive each SQL projection from those field schemas.
21
+ const complete = entity.recordSchema;
22
+ const schema = Schema.Struct(Object.fromEntries(fields.map((field) => [field.name, complete.fields[field.name]])));
23
+ cached.set(key, schema);
24
+ projectionSchemas.set(entity, cached);
25
+ return schema;
26
+ }
27
+ /**
28
+ * How a column is read. Values come back as text where the driver's own decoding would lose
29
+ * information or depend on the driver: timestamps keep their microseconds in UTC, dates stay
30
+ * calendar dates, `bigint` and `jsonb` are parsed here, and enums are read as their labels. The
31
+ * user's `roles` is read from the role assignments by the row's id, its column.
32
+ */
33
+ function readExpression(field, column) {
34
+ switch (field.storage) {
35
+ case "list":
36
+ return `${userRolesExpression(column)}::text`;
37
+ case "blob":
38
+ return (`(SELECT json_build_object('id', b.id::text, 'filename', b.filename, ` +
39
+ `'contentType', b.content_type, 'size', b.size, 'createdAt', ` +
40
+ `to_char(b.created_at AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'))::text ` +
41
+ `FROM "_blobs" b WHERE b.id = ${column})`);
42
+ case "timestamp":
43
+ return `to_char(${column} AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.US"Z"')`;
44
+ case "date":
45
+ return `to_char(${column}, 'YYYY-MM-DD')`;
46
+ case "integer":
47
+ case "json":
48
+ case "select":
49
+ case "uuid":
50
+ return `${column}::text`;
51
+ default:
52
+ return column;
53
+ }
54
+ }
55
+ /** The select list of an entity's records from the table aliased `alias`. */
56
+ export function selectList(entity, alias, fields = entity.fields) {
57
+ return fields
58
+ .map((field) => `${readExpression(field, columnOf(alias, field.column))} AS ${quoteIdentifier(field.name)}`)
59
+ .join(", ");
60
+ }
61
+ /** `2026-10-04T09:30:00.120000Z` → `2026-10-04T09:30:00.120Z`: milliseconds, then any further digits. */
62
+ export function canonicalInstant(value) {
63
+ return value.replace(/\.(\d{3})(\d*?)0*Z$/, ".$1$2Z");
64
+ }
65
+ function readValue(field, value) {
66
+ if (value === null || value === undefined) {
67
+ return null;
68
+ }
69
+ switch (field.storage) {
70
+ case "integer":
71
+ return Number(value);
72
+ case "blob":
73
+ case "json":
74
+ case "list":
75
+ return typeof value === "string" ? JSON.parse(value) : value;
76
+ case "timestamp":
77
+ return canonicalInstant(String(value));
78
+ default:
79
+ return value;
80
+ }
81
+ }
82
+ /** Decodes a row read with {@link selectList} against the entity's record schema. */
83
+ export function decodeRecord(entity, row, fields = entity.fields) {
84
+ return Effect.suspend(() => {
85
+ const values = {};
86
+ for (const field of fields) {
87
+ values[field.name] = readValue(field, row[field.name]);
88
+ }
89
+ const schema = projectionSchema(entity, fields);
90
+ const decoded = validate(schema, values);
91
+ if (!decoded.ok) {
92
+ const fields = decoded.issues.map((issue) => issue.path.join(".")).join(", ");
93
+ return Effect.die(new StoredRecordMismatch({
94
+ entity: entity.name,
95
+ message: `A stored ${entity.name} record does not match the definition (${fields}).`,
96
+ }));
97
+ }
98
+ return Effect.succeed(decoded.value);
99
+ });
100
+ }
101
+ export function decodeRecords(entity, rows) {
102
+ return Effect.forEach(rows, (row) => decodeRecord(entity, row));
103
+ }
104
+ /** The parameter a value of a field is bound as. JSON is bound as text and cast to `jsonb`. */
105
+ export function bindValue(field, value) {
106
+ if (value === null) {
107
+ return null;
108
+ }
109
+ if (field.storage === "blob") {
110
+ return typeof value === "string" ? value : value.id;
111
+ }
112
+ return field.storage === "json" ? JSON.stringify(value) : value;
113
+ }
114
+ function propertyIssue(field, value) {
115
+ const property = field.property;
116
+ if (property === undefined) {
117
+ return undefined;
118
+ }
119
+ const decoded = validate(propertyValueSchema(property), value);
120
+ if (!decoded.ok) {
121
+ return { path: [field.name], message: decoded.issues[0]?.message ?? "Invalid value" };
122
+ }
123
+ // A pattern accepts days that do not exist; PostgreSQL would reject them mid-transaction.
124
+ if (field.storage === "date" && !isCalendarDate(value)) {
125
+ return { path: [field.name], message: "Expected a date that exists" };
126
+ }
127
+ if (field.storage === "timestamp" && !isInstant(value)) {
128
+ return { path: [field.name], message: "Expected an instant that exists" };
129
+ }
130
+ return undefined;
131
+ }
132
+ function isIdList(value) {
133
+ return Array.isArray(value) && value.every((item) => typeof item === "string");
134
+ }
135
+ /**
136
+ * Checks the values a handler writes. Properties take their property's values, `rel.one`
137
+ * relationships a record id (or `null` when optional), `rel.many` relationships a list of ids,
138
+ * which replaces the collection. `undefined` leaves a value as it is; on create, a property without
139
+ * a value takes its default, or `null` when optional. Anything else is a defect in the handler.
140
+ */
141
+ export function prepareWrite(entity, values, mode) {
142
+ return Effect.suspend(() => {
143
+ const issues = [];
144
+ const columns = [];
145
+ const collections = [];
146
+ const references = [];
147
+ for (const [name, value] of Object.entries(values)) {
148
+ const field = entity.fieldsByName.get(name);
149
+ const link = entity.links.get(name);
150
+ if (value === undefined) {
151
+ continue;
152
+ }
153
+ if (field?.source === "property") {
154
+ if (value === null && !field.nullable) {
155
+ issues.push({ path: [name], message: `${name} is required` });
156
+ continue;
157
+ }
158
+ const issue = value === null ? undefined : propertyIssue(field, value);
159
+ if (issue !== undefined) {
160
+ issues.push(issue);
161
+ continue;
162
+ }
163
+ columns.push({ field, value });
164
+ }
165
+ else if (field?.source === "projection") {
166
+ issues.push({ path: [name], message: `${name} is read-only; the platform keeps it` });
167
+ }
168
+ else if (link?.via === "key") {
169
+ const key = entity.fieldsByName.get(`${name}_id`);
170
+ if (value === null && !link.optional) {
171
+ issues.push({ path: [name], message: `${name} is required` });
172
+ }
173
+ else if (value !== null && typeof value !== "string") {
174
+ issues.push({ path: [name], message: "Expected a record id" });
175
+ }
176
+ else {
177
+ columns.push({ field: key, value });
178
+ if (value !== null) {
179
+ references.push({ link, id: value });
180
+ }
181
+ }
182
+ }
183
+ else if (link?.via === "join" && !link.inverse) {
184
+ if (isIdList(value)) {
185
+ collections.push({ link, ids: [...new Set(value)] });
186
+ }
187
+ else {
188
+ issues.push({ path: [name], message: "Expected a list of record ids" });
189
+ }
190
+ }
191
+ else {
192
+ issues.push({ path: [name], message: `${name} is not a property or relationship` });
193
+ }
194
+ }
195
+ if (mode === "create") {
196
+ completeCreate(entity, values, columns, issues);
197
+ }
198
+ if (issues.length > 0) {
199
+ const summary = issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`);
200
+ return Effect.die(new InvalidValues({
201
+ entity: entity.name,
202
+ message: `Invalid ${entity.name} values: ${summary.join("; ")}.`,
203
+ issues,
204
+ }));
205
+ }
206
+ return Effect.succeed({ columns, collections, references });
207
+ });
208
+ }
209
+ /** Defaults, `null` for optional values and missing required values, on create. */
210
+ function completeCreate(entity, values, columns, issues) {
211
+ for (const field of entity.fields) {
212
+ if (field.source === "system" ||
213
+ field.source === "projection" ||
214
+ values[field.name] !== undefined) {
215
+ continue;
216
+ }
217
+ if (field.source === "relationship") {
218
+ const relationship = field.relationship;
219
+ if (values[relationship] !== undefined) {
220
+ continue;
221
+ }
222
+ if (field.nullable) {
223
+ columns.push({ field, value: null });
224
+ }
225
+ else {
226
+ issues.push({ path: [relationship], message: `${relationship} is required` });
227
+ }
228
+ continue;
229
+ }
230
+ const definition = field.property?.definition;
231
+ if (definition !== undefined && "default" in definition) {
232
+ columns.push({ field, value: definition.default });
233
+ }
234
+ else if (field.nullable) {
235
+ columns.push({ field, value: null });
236
+ }
237
+ else {
238
+ issues.push({ path: [field.name], message: `${field.name} is required` });
239
+ }
240
+ }
241
+ }
242
+ /** Whether a string can be a record id. Anything else names no record. */
243
+ export function isRecordId(value) {
244
+ return isUuid(value);
245
+ }
@@ -0,0 +1,6 @@
1
+ import { Effect } from "effect";
2
+ import type { SqlClient } from "effect/unstable/sql";
3
+ import type { Ontology } from "../ontology.js";
4
+ import type { AgentResolution, AgentStore, ResolveIdentityInput } from "../service/runtime-contract.js";
5
+ /** Account admission shares pairing's lock and creates User plus identity in one transaction. */
6
+ export declare function resolveAgentIdentity(ontology: Ontology, sql: SqlClient.SqlClient, store: AgentStore, input: ResolveIdentityInput, context?: "agent" | "channel_app"): Effect.Effect<AgentResolution>;