@segmentstream/ontology 0.0.0-stage → 0.92.1

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,411 @@
1
+ import { Effect } from "effect";
2
+ import { entityStorage, quoteIdentifier } from "../migrate/storage.js";
3
+ import { isCalendarDate } from "../query.js";
4
+ import { InvalidQuery } from "./errors.js";
5
+ import { decodeRecord, selectList } from "./records.js";
6
+ import { validateQuery } from "./reads.js";
7
+ import { Aliases, columnOf, Params } from "./statement.js";
8
+ import { compileWhere, fieldFilter } from "./where.js";
9
+ /**
10
+ * Fresh metric queries: an entity's declared metrics computed in PostgreSQL over the records a
11
+ * `where` matches, inside the caller's transaction (docs/ontology.md, "Fresh metric queries inside an
12
+ * action").
13
+ * Each metric is computed as SegmentStream computes it in the warehouse
14
+ * (backend-next's `semantics/adapters/bigquery-expressions.ts` and `bigquery-predicates.ts`):
15
+ * columns as decimals with nine places, aggregates ignoring nulls, a filtered aggregate over the
16
+ * rows its conditions hold for, division by zero as null, and values as decimal strings.
17
+ *
18
+ * One statement computes every metric over every matching record. The `where` must match the
19
+ * leading column of an index with `eq` or `in`, so that finding the records never scans the table:
20
+ * the cost follows the records the indexed condition selects.
21
+ */
22
+ const OPTIONS = new Set(["metrics", "groupBy", "where"]);
23
+ /** Properties a metric's sum, avg, min and max read. */
24
+ const NUMERIC = new Set(["integer", "number"]);
25
+ /** Fields a fresh metric query cannot group by: their values are documents or sets, not groups. */
26
+ const UNGROUPABLE = new Set(["json", "blob", "list"]);
27
+ /** How deep metric references and arithmetic may nest, as `check` bounds them. */
28
+ const MAX_DEPTH = 30;
29
+ function invalid(entity, path, message) {
30
+ return new InvalidQuery({
31
+ entity: entity.name,
32
+ message: `The metric query does not fit ${entity.name}: ${message}`,
33
+ issues: [{ path, message }],
34
+ });
35
+ }
36
+ function isPlainObject(value) {
37
+ return typeof value === "object" && value !== null && !Array.isArray(value);
38
+ }
39
+ /** The fields whose column leads an index of the entity's table, the primary key included. */
40
+ const indexedFields = new WeakMap();
41
+ export function indexedFieldsOf(entity) {
42
+ const cached = indexedFields.get(entity);
43
+ if (cached !== undefined) {
44
+ return cached;
45
+ }
46
+ const { table } = entityStorage(entity.manifest);
47
+ const leading = new Set([table.primaryKey.columns[0], ...table.indexes.map((index) => index.columns[0])].filter((column) => column !== undefined));
48
+ const fields = new Set(entity.fields
49
+ .filter((field) => field.source !== "projection" && leading.has(field.column))
50
+ .map((field) => field.name));
51
+ indexedFields.set(entity, fields);
52
+ return fields;
53
+ }
54
+ /** Whether a field condition is `eq` on a value or `in`, which an index can look up. */
55
+ function looksUp(field, condition) {
56
+ if (condition === null) {
57
+ return false;
58
+ }
59
+ const filter = fieldFilter(field, condition);
60
+ return (filter.eq !== undefined && filter.eq !== null) || filter.in !== undefined;
61
+ }
62
+ /**
63
+ * Whether a validated `where` confines the records to an index lookup: a condition of its own, or
64
+ * of an `and` entry, that looks up an indexed field, or an `or` every branch of which does. `not`
65
+ * never confines.
66
+ */
67
+ export function anchored(entity, where) {
68
+ if (where === undefined) {
69
+ return false;
70
+ }
71
+ const indexed = indexedFieldsOf(entity);
72
+ return Object.entries(where).some(([key, condition]) => {
73
+ if (condition === undefined || key === "not") {
74
+ return false;
75
+ }
76
+ if (key === "and") {
77
+ return condition.some((sub) => anchored(entity, sub));
78
+ }
79
+ if (key === "or") {
80
+ const branches = condition;
81
+ return branches.length > 0 && branches.every((sub) => anchored(entity, sub));
82
+ }
83
+ const field = entity.fieldsByName.get(key);
84
+ return field !== undefined && indexed.has(key) && looksUp(field, condition);
85
+ });
86
+ }
87
+ /**
88
+ * Inlines a metric's references to other metrics of the entity, refusing what a fresh metric query
89
+ * does not compute: a balance, which only the warehouse's balance rule makes meaningful, and an
90
+ * operator this SDK does not know.
91
+ */
92
+ function expand(entity, name, path) {
93
+ const metrics = new Map((entity.manifest.metrics ?? []).map((metric) => [metric.name, metric]));
94
+ const visit = (current, stack) => {
95
+ const metric = metrics.get(current);
96
+ if (metric === undefined) {
97
+ throw invalid(entity, path, `${entity.name} has no metric ${current}.`);
98
+ }
99
+ if (stack.includes(current) || stack.length > MAX_DEPTH) {
100
+ throw invalid(entity, path, `${entity.name}.${name} references itself.`);
101
+ }
102
+ if (metric.balanceOver !== undefined) {
103
+ throw invalid(entity, path, `${entity.name}.${current} is a balance over ${metric.balanceOver}, which only the ` +
104
+ "warehouse computes.");
105
+ }
106
+ const inline = (expression, depth) => {
107
+ if (depth > MAX_DEPTH) {
108
+ throw invalid(entity, path, `${entity.name}.${name} nests too deeply.`);
109
+ }
110
+ switch (expression.op) {
111
+ case "metric":
112
+ return visit(expression.name, [...stack, current]);
113
+ case "count":
114
+ case "column":
115
+ case "literal":
116
+ return expression;
117
+ case "filtered":
118
+ return { ...expression, args: expression.args.map((arg) => inline(arg, depth + 1)) };
119
+ case "sum":
120
+ case "countDistinct":
121
+ case "avg":
122
+ case "min":
123
+ case "max":
124
+ case "add":
125
+ case "subtract":
126
+ case "multiply":
127
+ case "divide":
128
+ return { ...expression, args: expression.args.map((arg) => inline(arg, depth + 1)) };
129
+ default:
130
+ throw invalid(entity, path, `${entity.name}.${current} uses an operator this SDK does not compute.`);
131
+ }
132
+ };
133
+ return inline(metric.expression, 0);
134
+ };
135
+ return visit(name, []);
136
+ }
137
+ /** Compiles metric expressions over the table aliased `alias`, binding values into `params`. */
138
+ class MetricCompiler {
139
+ entity;
140
+ alias;
141
+ params;
142
+ path;
143
+ constructor(entity, alias, params, path) {
144
+ this.entity = entity;
145
+ this.alias = alias;
146
+ this.params = params;
147
+ this.path = path;
148
+ }
149
+ /** The field a metric names: a property or system field, by its wire name. */
150
+ field(name) {
151
+ const field = this.entity.fieldsByName.get(name);
152
+ if (field === undefined || (field.source !== "property" && field.source !== "system")) {
153
+ throw invalid(this.entity, this.path, `a metric reads ${name}, which is not a property.`);
154
+ }
155
+ return field;
156
+ }
157
+ column(field) {
158
+ return columnOf(this.alias, field.column);
159
+ }
160
+ /** A numeric column as the warehouse casts it: a decimal with nine places. */
161
+ decimal(name) {
162
+ const field = this.field(name);
163
+ if (!NUMERIC.has(field.storage)) {
164
+ throw invalid(this.entity, this.path, `a metric's aggregate reads ${name}, a non-numeric property.`);
165
+ }
166
+ return field.storage === "integer"
167
+ ? `${this.column(field)}::numeric`
168
+ : `round(${this.column(field)}::numeric, 9)`;
169
+ }
170
+ /** The value an aggregate reads: one numeric column. */
171
+ argument(expression) {
172
+ if (expression?.op !== "column") {
173
+ throw invalid(this.entity, this.path, "an aggregate reads one property.");
174
+ }
175
+ return this.decimal(expression.name);
176
+ }
177
+ /** One aggregate, restricted to the rows `filter` holds for when there is one. */
178
+ aggregate(expression, filter) {
179
+ const only = filter === undefined ? "" : ` FILTER (WHERE ${filter})`;
180
+ switch (expression.op) {
181
+ case "count":
182
+ return `(count(*)${only})::numeric`;
183
+ case "countDistinct": {
184
+ const [argument] = expression.args;
185
+ if (argument?.op !== "column") {
186
+ throw invalid(this.entity, this.path, "countDistinct reads one property.");
187
+ }
188
+ return `(count(DISTINCT ${this.column(this.field(argument.name))})${only})::numeric`;
189
+ }
190
+ case "sum":
191
+ case "min":
192
+ case "max":
193
+ return `${expression.op}(${this.argument(expression.args[0])})${only}`;
194
+ case "avg":
195
+ return `round(avg(${this.argument(expression.args[0])})${only}, 9)`;
196
+ default:
197
+ throw invalid(this.entity, this.path, "a filtered metric wraps one aggregate.");
198
+ }
199
+ }
200
+ compile(expression) {
201
+ switch (expression.op) {
202
+ case "count":
203
+ case "countDistinct":
204
+ case "sum":
205
+ case "avg":
206
+ case "min":
207
+ case "max":
208
+ return this.aggregate(expression);
209
+ case "filtered": {
210
+ const [aggregate] = expression.args;
211
+ if (aggregate === undefined || expression.where.length === 0) {
212
+ throw invalid(this.entity, this.path, "a filtered metric wraps one aggregate.");
213
+ }
214
+ return this.aggregate(aggregate, expression.where.map((condition) => `(${this.condition(condition)})`).join(" AND "));
215
+ }
216
+ case "literal":
217
+ return this.params.add(expression.value, "numeric");
218
+ case "add":
219
+ case "subtract":
220
+ case "multiply":
221
+ case "divide": {
222
+ const [left, right] = expression.args.map((arg) => this.compile(arg));
223
+ if (left === undefined || right === undefined) {
224
+ throw invalid(this.entity, this.path, "arithmetic combines two expressions.");
225
+ }
226
+ // The warehouse's decimals keep nine places, and a zero denominator divides to null.
227
+ return expression.op === "add"
228
+ ? `(${left} + ${right})`
229
+ : expression.op === "subtract"
230
+ ? `(${left} - ${right})`
231
+ : expression.op === "multiply"
232
+ ? `round(${left} * ${right}, 9)`
233
+ : `round(${left} / NULLIF(${right}, 0), 9)`;
234
+ }
235
+ default:
236
+ throw invalid(this.entity, this.path, "a metric uses an operator this SDK does not compute.");
237
+ }
238
+ }
239
+ /**
240
+ * A metric condition, exactly as the warehouse reads it: negative operators match nulls, text
241
+ * operators compare case-sensitively, and date bounds on a timestamp cover whole days in UTC, a
242
+ * stored entity's timezone.
243
+ */
244
+ condition(condition) {
245
+ const field = this.field(condition.column);
246
+ const storage = field.storage;
247
+ const text = storage === "select" ? `${this.column(field)}::text` : this.column(field);
248
+ const type = storage === "integer" || storage === "number"
249
+ ? "numeric"
250
+ : storage === "date" || storage === "boolean"
251
+ ? storage
252
+ : storage === "timestamp"
253
+ ? "timestamptz"
254
+ : "text";
255
+ const bind = (value) => this.params.add(type === "numeric" ? String(value) : value, type);
256
+ const one = () => bind(condition.value);
257
+ const several = () => (condition.values ?? []).map(bind).join(", ");
258
+ const day = (value) => `(${this.params.add(value, "date")}::timestamp AT TIME ZONE 'UTC')`;
259
+ const nextDay = (value) => `((${this.params.add(value, "date")} + 1)::timestamp AT TIME ZONE 'UTC')`;
260
+ const isDay = (value) => storage === "timestamp" && typeof value === "string" && isCalendarDate(value);
261
+ switch (condition.operator) {
262
+ case "isNull":
263
+ return `${text} IS NULL`;
264
+ case "isNotNull":
265
+ return `${text} IS NOT NULL`;
266
+ case "equals":
267
+ return `${text} = ${one()}`;
268
+ case "notEquals":
269
+ return `(${text} IS NULL OR ${text} <> ${one()})`;
270
+ case "in":
271
+ return `${text} IN (${several()})`;
272
+ case "notIn":
273
+ return `(${text} IS NULL OR ${text} NOT IN (${several()}))`;
274
+ case "between": {
275
+ const [from, to] = condition.values ?? [];
276
+ return isDay(from) && isDay(to)
277
+ ? `${text} >= ${day(from)} AND ${text} < ${nextDay(to)}`
278
+ : `${text} >= ${bind(from)} AND ${text} <= ${bind(to)}`;
279
+ }
280
+ case "gt":
281
+ return isDay(condition.value)
282
+ ? `${text} >= ${nextDay(condition.value)}`
283
+ : `${text} > ${one()}`;
284
+ case "gte":
285
+ return isDay(condition.value)
286
+ ? `${text} >= ${day(condition.value)}`
287
+ : `${text} >= ${one()}`;
288
+ case "lt":
289
+ return isDay(condition.value) ? `${text} < ${day(condition.value)}` : `${text} < ${one()}`;
290
+ case "lte":
291
+ return isDay(condition.value)
292
+ ? `${text} < ${nextDay(condition.value)}`
293
+ : `${text} <= ${one()}`;
294
+ case "contains":
295
+ return `strpos(${text}, ${one()}) > 0`;
296
+ case "startsWith": {
297
+ const value = one();
298
+ return `left(${text}, char_length(${value})) = ${value}`;
299
+ }
300
+ case "endsWith": {
301
+ const value = one();
302
+ return `right(${text}, char_length(${value})) = ${value}`;
303
+ }
304
+ default:
305
+ throw invalid(this.entity, this.path, "a metric condition uses an unknown operator.");
306
+ }
307
+ }
308
+ }
309
+ /** The order of a grouped field: nulls first and text by its bytes, as the warehouse orders it. */
310
+ function orderOf(alias, field) {
311
+ const column = columnOf(alias, field.column);
312
+ const text = ["text", "email", "url", "select"].includes(field.storage);
313
+ return `${text ? `${column}::text COLLATE "C"` : column} ASC NULLS FIRST`;
314
+ }
315
+ function plan(entity, input) {
316
+ return Effect.gen(function* () {
317
+ if (entity.manifest.builtIn || (entity.manifest.metrics ?? []).length === 0) {
318
+ return yield* invalid(entity, [], `${entity.name} declares no metrics.`);
319
+ }
320
+ if (!isPlainObject(input)) {
321
+ return yield* invalid(entity, [], "the options are not an object.");
322
+ }
323
+ const unknown = Object.keys(input).find((key) => !OPTIONS.has(key));
324
+ if (unknown === "forUpdate") {
325
+ return yield* invalid(entity, ["forUpdate"], "metric queries lock no records; lock the record the decision depends on with forUpdate.");
326
+ }
327
+ if (unknown !== undefined) {
328
+ return yield* invalid(entity, [unknown], `${unknown} is not a metric query option.`);
329
+ }
330
+ const names = input.metrics;
331
+ if (!Array.isArray(names) ||
332
+ names.length === 0 ||
333
+ names.some((name) => typeof name !== "string") ||
334
+ new Set(names).size !== names.length) {
335
+ return yield* invalid(entity, ["metrics"], "metrics names one or more distinct metrics.");
336
+ }
337
+ const metrics = yield* Effect.try({
338
+ try: () => names.map((name, index) => ({
339
+ name,
340
+ expression: expand(entity, name, ["metrics", index]),
341
+ })),
342
+ catch: (error) => error instanceof InvalidQuery ? error : invalid(entity, ["metrics"], String(error)),
343
+ });
344
+ const groupNames = input.groupBy ?? [];
345
+ if (!Array.isArray(groupNames) ||
346
+ groupNames.some((name) => typeof name !== "string") ||
347
+ new Set(groupNames).size !== groupNames.length) {
348
+ return yield* invalid(entity, ["groupBy"], "groupBy names distinct fields.");
349
+ }
350
+ const groups = [];
351
+ for (const [index, name] of groupNames.entries()) {
352
+ const field = entity.fieldsByName.get(name);
353
+ if (field === undefined ||
354
+ (field.source !== "property" && field.source !== "relationship") ||
355
+ UNGROUPABLE.has(field.storage)) {
356
+ return yield* invalid(entity, ["groupBy", index], `${name} is not a property or relationship key ${entity.name} can group by.`);
357
+ }
358
+ if (names.includes(name)) {
359
+ return yield* invalid(entity, ["groupBy", index], `${name} names both a metric and a grouped field.`);
360
+ }
361
+ groups.push(field);
362
+ }
363
+ if (!isPlainObject(input.where)) {
364
+ return yield* invalid(entity, ["where"], "where is required.");
365
+ }
366
+ const { where } = yield* validateQuery(entity, { where: input.where });
367
+ if (where === undefined || !anchored(entity, where)) {
368
+ const indexed = [...indexedFieldsOf(entity)].sort().join(", ");
369
+ return yield* invalid(entity, ["where"], `where must match an indexed field (${indexed}) with eq or in, so that the records are ` +
370
+ "found through an index.");
371
+ }
372
+ return { metrics, groups, where };
373
+ });
374
+ }
375
+ /**
376
+ * Computes the metrics over the records the `where` matches, grouped by the fields of `groupBy`:
377
+ * one row per group, ordered by the groups, or one row without them. One statement.
378
+ */
379
+ export function runMetricQuery(context, entity, options) {
380
+ return Effect.gen(function* () {
381
+ const planned = yield* plan(entity, options);
382
+ const params = new Params();
383
+ const aliases = new Aliases();
384
+ const alias = aliases.take();
385
+ const condition = compileWhere({ model: context.model, params, aliases }, entity, alias, planned.where);
386
+ const compiler = new MetricCompiler(entity, alias, params, ["metrics"]);
387
+ const metrics = yield* Effect.try({
388
+ try: () => planned.metrics.map(({ expression }, index) => `trim_scale(${compiler.compile(expression)})::text AS ${quoteIdentifier(`__m${index}`)}`),
389
+ catch: (error) => error instanceof InvalidQuery ? error : invalid(entity, ["metrics"], String(error)),
390
+ });
391
+ const select = [
392
+ ...(planned.groups.length === 0 ? [] : [selectList(entity, alias, planned.groups)]),
393
+ ...metrics,
394
+ ].join(", ");
395
+ const rows = yield* context.run(`SELECT ${select} FROM ${quoteIdentifier(entity.table)} AS ${quoteIdentifier(alias)} ` +
396
+ `WHERE ${condition}` +
397
+ (planned.groups.length === 0
398
+ ? ""
399
+ : ` GROUP BY ${planned.groups.map((field) => columnOf(alias, field.column)).join(", ")}` +
400
+ ` ORDER BY ${planned.groups.map((field) => orderOf(alias, field)).join(", ")}`), params);
401
+ return yield* Effect.forEach(rows, (row) => Effect.map(planned.groups.length === 0
402
+ ? Effect.succeed({})
403
+ : decodeRecord(entity, row, planned.groups), (groups) => ({
404
+ ...groups,
405
+ ...Object.fromEntries(planned.metrics.map(({ name }, index) => {
406
+ const value = row[`__m${index}`];
407
+ return [name, value === null || value === undefined ? null : String(value)];
408
+ })),
409
+ })));
410
+ });
411
+ }
@@ -0,0 +1,67 @@
1
+ import { Schema } from "effect";
2
+ import type { ResolvedEntity, ResolvedProperty } from "../analyze.js";
3
+ import type { EntityManifest } from "../manifest.js";
4
+ import type { Ontology } from "../ontology.js";
5
+ import { type Query, type QueryField, type QueryLink } from "../query.js";
6
+ import type { OnDelete } from "../relationship.js";
7
+ /**
8
+ * A record field with its column. A projection, the built-in user's `roles`, has none of its own:
9
+ * it is read from the platform's tables by the row's id, which is its `column`, and never written.
10
+ */
11
+ export interface FieldModel extends QueryField {
12
+ readonly column: string;
13
+ /** The type its parameters are cast to. */
14
+ readonly sqlType: string;
15
+ readonly source: "system" | "property" | "relationship" | "projection";
16
+ /** The declared property, for properties. */
17
+ readonly property?: ResolvedProperty;
18
+ /** The relationship whose key the field holds, for `<relationship>_id`. */
19
+ readonly relationship?: string;
20
+ }
21
+ /** A declared `rel.one`: this entity's key column points at the target's id. */
22
+ export interface KeyLink extends QueryLink {
23
+ readonly via: "key";
24
+ readonly column: string;
25
+ readonly optional: boolean;
26
+ }
27
+ /** A `rel.many`, from either side: rows of a join table. */
28
+ export interface JoinLink extends QueryLink {
29
+ readonly via: "join";
30
+ readonly table: string;
31
+ /** The join column holding this entity's id, and the one holding the target's. */
32
+ readonly selfColumn: string;
33
+ readonly otherColumn: string;
34
+ /** The relationship's name on the target's side. */
35
+ readonly inverseName: string;
36
+ }
37
+ /** The inverse of a `rel.one`: the target's key column points at this entity's id. */
38
+ export interface InverseKeyLink extends QueryLink {
39
+ readonly via: "inverse-key";
40
+ readonly column: string;
41
+ readonly onDelete: OnDelete;
42
+ }
43
+ export type LinkModel = KeyLink | JoinLink | InverseKeyLink;
44
+ export interface EntityModel {
45
+ readonly name: string;
46
+ readonly label: string;
47
+ readonly table: string;
48
+ readonly historyTable: string;
49
+ readonly resolved: ResolvedEntity;
50
+ readonly manifest: EntityManifest;
51
+ /** System fields, properties and `<relationship>_id` keys, in record order. */
52
+ readonly fields: ReadonlyArray<FieldModel>;
53
+ readonly fieldsByName: ReadonlyMap<string, FieldModel>;
54
+ readonly links: ReadonlyMap<string, LinkModel>;
55
+ readonly recordSchema: Schema.Top;
56
+ readonly querySchema: Schema.Codec<Query>;
57
+ }
58
+ export interface OntologyModel {
59
+ readonly ontology: Ontology;
60
+ readonly entities: ReadonlyMap<string, EntityModel>;
61
+ }
62
+ /** The physical model of an ontology: tables, columns and relationship paths per entity. */
63
+ export declare function ontologyModel(ontology: Ontology): OntologyModel;
64
+ /** The model of an entity. An unknown name is a programming error in the caller. */
65
+ export declare function entityModel(model: OntologyModel, name: string): EntityModel;
66
+ /** The schema of a property's value, without the optional-key wrapper. */
67
+ export declare function propertyValueSchema(property: ResolvedProperty): Schema.Top;
@@ -0,0 +1,150 @@
1
+ import { Schema } from "effect";
2
+ import { entityQuerySchema, entityRecordSchema, findEntityManifest, queryFields, queryLinks, } from "../query.js";
3
+ import { COLUMN_TYPES, columnName, enumTypeName, historyTableName, joinColumnNames, joinTableName, quoteIdentifier, relationshipColumnName, SYSTEM_COLUMNS, tableName, } from "../migrate/storage.js";
4
+ import { User } from "../user.js";
5
+ import { USER_ROLES_PROPERTY } from "./user-roles.js";
6
+ /**
7
+ * The type a field's parameters are cast to: the planner's column type, the enum type of a
8
+ * `select`, `uuid` for ids and keys, and the item type of a `list`, whose filters bind items.
9
+ */
10
+ function sqlType(storage, entity, field) {
11
+ if (storage === "uuid") {
12
+ return "uuid";
13
+ }
14
+ if (storage === "list") {
15
+ return "text";
16
+ }
17
+ return storage === "select"
18
+ ? quoteIdentifier(enumTypeName(entity, field))
19
+ : COLUMN_TYPES[storage];
20
+ }
21
+ const models = new WeakMap();
22
+ /** The physical model of an ontology: tables, columns and relationship paths per entity. */
23
+ export function ontologyModel(ontology) {
24
+ const cached = models.get(ontology);
25
+ if (cached !== undefined) {
26
+ return cached;
27
+ }
28
+ const entities = new Map();
29
+ for (const resolved of ontology.entities) {
30
+ if (resolved.entity.definition.source !== undefined) {
31
+ continue;
32
+ }
33
+ entities.set(resolved.name, buildEntity(ontology, resolved));
34
+ }
35
+ const model = { ontology, entities };
36
+ models.set(ontology, model);
37
+ return model;
38
+ }
39
+ /** The model of an entity. An unknown name is a programming error in the caller. */
40
+ export function entityModel(model, name) {
41
+ const entity = model.entities.get(name);
42
+ if (entity === undefined) {
43
+ throw new Error(`"${name}" is not an entity of this ontology.`);
44
+ }
45
+ return entity;
46
+ }
47
+ function buildEntity(ontology, resolved) {
48
+ const manifest = findEntityManifest(ontology.manifest, resolved.name);
49
+ const properties = new Map(resolved.properties.map((property) => [property.name, property]));
50
+ const fields = queryFields(manifest).map((field) => buildField(resolved.name, field, properties));
51
+ return {
52
+ name: resolved.name,
53
+ label: manifest.label,
54
+ table: tableName(resolved.name),
55
+ historyTable: historyTableName(resolved.name),
56
+ resolved,
57
+ manifest,
58
+ fields,
59
+ fieldsByName: new Map(fields.map((field) => [field.name, field])),
60
+ links: new Map(queryLinks(ontology.manifest, resolved.name).map((link) => [
61
+ link.name,
62
+ buildLink(ontology, link),
63
+ ])),
64
+ recordSchema: entityRecordSchema(manifest),
65
+ querySchema: entityQuerySchema(ontology.manifest, resolved.name),
66
+ };
67
+ }
68
+ function buildField(entity, field, properties) {
69
+ const property = properties.get(field.name);
70
+ const system = SYSTEM_COLUMNS[field.name];
71
+ if (system !== undefined) {
72
+ return {
73
+ ...field,
74
+ column: system,
75
+ sqlType: sqlType(field.storage, entity, field.name),
76
+ source: "system",
77
+ };
78
+ }
79
+ if (property !== undefined && field.storage === "list") {
80
+ // `check` refuses a list anywhere else, so another one is a defect in the ontology.
81
+ if (entity !== User.name || field.name !== USER_ROLES_PROPERTY) {
82
+ throw new Error(`${entity}.${field.name} is a list, which only the built-in user has.`);
83
+ }
84
+ return {
85
+ ...field,
86
+ column: SYSTEM_COLUMNS.id,
87
+ sqlType: sqlType(field.storage, entity, field.name),
88
+ source: "projection",
89
+ property,
90
+ };
91
+ }
92
+ if (property !== undefined) {
93
+ return {
94
+ ...field,
95
+ column: columnName(field.name),
96
+ sqlType: sqlType(field.storage, entity, field.name),
97
+ source: "property",
98
+ property,
99
+ };
100
+ }
101
+ const relationship = field.name.slice(0, -"_id".length);
102
+ return {
103
+ ...field,
104
+ column: relationshipColumnName(relationship),
105
+ sqlType: sqlType(field.storage, entity, field.name),
106
+ source: "relationship",
107
+ relationship,
108
+ };
109
+ }
110
+ function buildLink(ontology, link) {
111
+ const declaringEntity = findEntityManifest(ontology.manifest, link.declaredBy);
112
+ const declaration = declaringEntity.relationships.find((candidate) => candidate.name === link.relationship);
113
+ if (declaration === undefined) {
114
+ throw new Error(`${link.declaredBy}.${link.relationship} is not declared.`);
115
+ }
116
+ if (link.declared === "many") {
117
+ const columns = joinColumnNames({
118
+ entity: declaringEntity.name,
119
+ relationship: declaration.name,
120
+ target: declaration.to,
121
+ });
122
+ return {
123
+ ...link,
124
+ via: "join",
125
+ table: joinTableName(declaringEntity.name, declaration.name),
126
+ selfColumn: link.inverse ? columns.target : columns.source,
127
+ otherColumn: link.inverse ? columns.source : columns.target,
128
+ inverseName: link.inverse ? declaration.name : declaration.inverse,
129
+ };
130
+ }
131
+ if (link.inverse) {
132
+ return {
133
+ ...link,
134
+ via: "inverse-key",
135
+ column: relationshipColumnName(declaration.name),
136
+ onDelete: declaration.onDelete ?? "restrict",
137
+ };
138
+ }
139
+ return {
140
+ ...link,
141
+ via: "key",
142
+ column: relationshipColumnName(declaration.name),
143
+ optional: declaration.optional === true,
144
+ };
145
+ }
146
+ /** The schema of a property's value, without the optional-key wrapper. */
147
+ export function propertyValueSchema(property) {
148
+ const { schema } = property;
149
+ return "schema" in schema && Schema.isSchema(schema.schema) ? schema.schema : schema;
150
+ }
@@ -0,0 +1,6 @@
1
+ import { Effect } from "effect";
2
+ import { SqlClient } from "effect/unstable/sql";
3
+ import type { Ontology } from "../ontology.js";
4
+ import type { Principal } from "../runtime.js";
5
+ /** Runs after admission commits, before a model turn or channel-app session. True means retry pending. */
6
+ export declare function runNewUserHook(ontology: Ontology, sql: SqlClient.SqlClient, principal: Principal): Effect.Effect<boolean>;
@@ -0,0 +1,37 @@
1
+ import { Cause, Effect } from "effect";
2
+ import { SqlClient } from "effect/unstable/sql";
3
+ import { CHANNEL_USERS_TABLE } from "../migrate/storage.js";
4
+ import { permissionsOf, principalScopes } from "../permissions.js";
5
+ import { runAction } from "./pipeline.js";
6
+ /** Runs after admission commits, before a model turn or channel-app session. True means retry pending. */
7
+ export function runNewUserHook(ontology, sql, principal) {
8
+ const hook = ontology.signIn.onNewUser;
9
+ if (hook === undefined) {
10
+ return Effect.succeed(false);
11
+ }
12
+ const [entity, action] = hook.split(":");
13
+ return runAction(ontology, {
14
+ entity: entity,
15
+ action: action,
16
+ input: {},
17
+ principal: {
18
+ id: principal.id,
19
+ kind: "member",
20
+ ...(principal.authenticatedVia === undefined
21
+ ? {}
22
+ : { authenticatedVia: principal.authenticatedVia }),
23
+ roles: ["member"],
24
+ permissions: permissionsOf(ontology.roles, ["member"]),
25
+ ...principalScopes(ontology.roles, ["member"]),
26
+ },
27
+ options: { newUserHook: true },
28
+ }).pipe(Effect.provideService(SqlClient.SqlClient, sql), Effect.flatMap((outcome) => outcome.validation.ok ? Effect.void : Effect.die(new Error("Invalid onNewUser input."))), Effect.catchCause((cause) => Effect.logWarning("ontology.channel.on_new_user_pending", Cause.pretty(cause)
29
+ .replace(/(postgres(?:ql)?:\/\/[^:\s]+:)[^@\s]+@/gi, "$1[redacted]@")
30
+ .replace(/Bearer\s+[^\s"']+/gi, "Bearer [redacted]")
31
+ .replace(/\b(?:sso|ssr|ssc|sss|ssk|ssw)_[A-Za-z0-9_-]+/g, "[redacted]")).pipe(Effect.annotateLogs({
32
+ operation: "ontology.channel.on_new_user",
33
+ userId: principal.id,
34
+ action: hook,
35
+ }))), Effect.andThen(sql.unsafe(`SELECT "on_new_user_completed_at" IS NULL AS "pending" FROM "${CHANNEL_USERS_TABLE}"
36
+ WHERE "user_id" = $1::uuid AND "created_via" NOT IN ('invite', 'email')`, [principal.id])), Effect.map(([stored]) => stored?.pending ?? false), Effect.orDie);
37
+ }