@memberjunction/server 6.2.0-edge.4 → 6.2.0-edge.6

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 (560) hide show
  1. package/README.md +47 -1
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/agentSessions/SessionJanitor.d.ts +91 -30
  4. package/dist/agentSessions/SessionJanitor.d.ts.map +1 -1
  5. package/dist/agentSessions/SessionJanitor.js +311 -81
  6. package/dist/agentSessions/SessionJanitor.js.map +1 -1
  7. package/dist/agentSessions/SessionManager.d.ts +17 -3
  8. package/dist/agentSessions/SessionManager.d.ts.map +1 -1
  9. package/dist/agentSessions/SessionManager.js +44 -10
  10. package/dist/agentSessions/SessionManager.js.map +1 -1
  11. package/dist/apiRoot.d.ts +32 -0
  12. package/dist/apiRoot.d.ts.map +1 -0
  13. package/dist/apiRoot.js +67 -0
  14. package/dist/apiRoot.js.map +1 -0
  15. package/dist/auth/AuthProviderCatalogRouter.d.ts.map +1 -1
  16. package/dist/auth/AuthProviderCatalogRouter.js +27 -0
  17. package/dist/auth/AuthProviderCatalogRouter.js.map +1 -1
  18. package/dist/auth/LoginScreenEngine.d.ts +22 -0
  19. package/dist/auth/LoginScreenEngine.d.ts.map +1 -0
  20. package/dist/auth/LoginScreenEngine.js +57 -0
  21. package/dist/auth/LoginScreenEngine.js.map +1 -0
  22. package/dist/auth/index.d.ts +1 -0
  23. package/dist/auth/index.d.ts.map +1 -1
  24. package/dist/auth/index.js +52 -10
  25. package/dist/auth/index.js.map +1 -1
  26. package/dist/auth/initializeProviders.d.ts +10 -0
  27. package/dist/auth/initializeProviders.d.ts.map +1 -1
  28. package/dist/auth/initializeProviders.js +37 -1
  29. package/dist/auth/initializeProviders.js.map +1 -1
  30. package/dist/auth/localDevAuth.d.ts +79 -0
  31. package/dist/auth/localDevAuth.d.ts.map +1 -0
  32. package/dist/auth/localDevAuth.js +439 -0
  33. package/dist/auth/localDevAuth.js.map +1 -0
  34. package/dist/auth/magicLink/MagicLinkKeys.d.ts +2 -2
  35. package/dist/auth/magicLink/MagicLinkKeys.d.ts.map +1 -1
  36. package/dist/auth/magicLink/MagicLinkKeys.js +1 -1
  37. package/dist/auth/magicLink/MagicLinkKeys.js.map +1 -1
  38. package/dist/auth/magicLink/MagicLinkRouter.d.ts.map +1 -1
  39. package/dist/auth/magicLink/MagicLinkRouter.js +3 -2
  40. package/dist/auth/magicLink/MagicLinkRouter.js.map +1 -1
  41. package/dist/auth/magicLink/types.d.ts +12 -0
  42. package/dist/auth/magicLink/types.d.ts.map +1 -1
  43. package/dist/auth/sessionUserClone.d.ts +1 -1
  44. package/dist/auth/sessionUserClone.d.ts.map +1 -1
  45. package/dist/auth/sessionUserClone.js +3 -2
  46. package/dist/auth/sessionUserClone.js.map +1 -1
  47. package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.d.ts +292 -0
  48. package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.d.ts.map +1 -0
  49. package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.js +442 -0
  50. package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.js.map +1 -0
  51. package/dist/broadcast/index.d.ts +6 -0
  52. package/dist/broadcast/index.d.ts.map +1 -0
  53. package/dist/broadcast/index.js +6 -0
  54. package/dist/broadcast/index.js.map +1 -0
  55. package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.d.ts +43 -0
  56. package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.d.ts.map +1 -0
  57. package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.js +144 -0
  58. package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.js.map +1 -0
  59. package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.d.ts +46 -0
  60. package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.d.ts.map +1 -0
  61. package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.js +149 -0
  62. package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.js.map +1 -0
  63. package/dist/broadcast/providers/GCPPubSubBroadcastProvider.d.ts +49 -0
  64. package/dist/broadcast/providers/GCPPubSubBroadcastProvider.d.ts.map +1 -0
  65. package/dist/broadcast/providers/GCPPubSubBroadcastProvider.js +131 -0
  66. package/dist/broadcast/providers/GCPPubSubBroadcastProvider.js.map +1 -0
  67. package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.d.ts +24 -0
  68. package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.d.ts.map +1 -0
  69. package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.js +51 -0
  70. package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.js.map +1 -0
  71. package/dist/cache.d.ts +3 -2
  72. package/dist/cache.d.ts.map +1 -1
  73. package/dist/cache.js.map +1 -1
  74. package/dist/config.d.ts +632 -22
  75. package/dist/config.d.ts.map +1 -1
  76. package/dist/config.js +104 -4
  77. package/dist/config.js.map +1 -1
  78. package/dist/context.d.ts +3 -1
  79. package/dist/context.d.ts.map +1 -1
  80. package/dist/context.js +29 -8
  81. package/dist/context.js.map +1 -1
  82. package/dist/coreRoutes.d.ts +29 -0
  83. package/dist/coreRoutes.d.ts.map +1 -0
  84. package/dist/coreRoutes.js +156 -0
  85. package/dist/coreRoutes.js.map +1 -0
  86. package/dist/generated/graphql-schemas/__mj.d.ts +1016 -29
  87. package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
  88. package/dist/generated/graphql-schemas/__mj.js +5125 -434
  89. package/dist/generated/graphql-schemas/__mj.js.map +1 -1
  90. package/dist/generic/CacheInvalidationResolver.d.ts +85 -30
  91. package/dist/generic/CacheInvalidationResolver.d.ts.map +1 -1
  92. package/dist/generic/CacheInvalidationResolver.js +175 -60
  93. package/dist/generic/CacheInvalidationResolver.js.map +1 -1
  94. package/dist/generic/OrphanedConversationDetailReconciler.d.ts.map +1 -1
  95. package/dist/generic/OrphanedConversationDetailReconciler.js +2 -0
  96. package/dist/generic/OrphanedConversationDetailReconciler.js.map +1 -1
  97. package/dist/generic/PubSubManager.d.ts +10 -0
  98. package/dist/generic/PubSubManager.d.ts.map +1 -1
  99. package/dist/generic/PubSubManager.js +44 -1
  100. package/dist/generic/PubSubManager.js.map +1 -1
  101. package/dist/generic/PushStatusResolver.d.ts +39 -6
  102. package/dist/generic/PushStatusResolver.d.ts.map +1 -1
  103. package/dist/generic/PushStatusResolver.js +94 -12
  104. package/dist/generic/PushStatusResolver.js.map +1 -1
  105. package/dist/generic/ResolverBase.d.ts +168 -69
  106. package/dist/generic/ResolverBase.d.ts.map +1 -1
  107. package/dist/generic/ResolverBase.js +464 -405
  108. package/dist/generic/ResolverBase.js.map +1 -1
  109. package/dist/generic/RunViewResolver.d.ts +11 -3
  110. package/dist/generic/RunViewResolver.d.ts.map +1 -1
  111. package/dist/generic/RunViewResolver.js +91 -13
  112. package/dist/generic/RunViewResolver.js.map +1 -1
  113. package/dist/generic/actionOutputFieldSecurity.d.ts +26 -0
  114. package/dist/generic/actionOutputFieldSecurity.d.ts.map +1 -0
  115. package/dist/generic/actionOutputFieldSecurity.js +47 -0
  116. package/dist/generic/actionOutputFieldSecurity.js.map +1 -0
  117. package/dist/generic/fieldSecurityTransport.d.ts +30 -0
  118. package/dist/generic/fieldSecurityTransport.d.ts.map +1 -0
  119. package/dist/generic/fieldSecurityTransport.js +30 -0
  120. package/dist/generic/fieldSecurityTransport.js.map +1 -0
  121. package/dist/globalCors.d.ts +33 -0
  122. package/dist/globalCors.d.ts.map +1 -0
  123. package/dist/globalCors.js +58 -0
  124. package/dist/globalCors.js.map +1 -0
  125. package/dist/index.d.ts +14 -0
  126. package/dist/index.d.ts.map +1 -1
  127. package/dist/index.js +230 -222
  128. package/dist/index.js.map +1 -1
  129. package/dist/integration/CustomColumnPromoter.d.ts.map +1 -1
  130. package/dist/integration/CustomColumnPromoter.js +6 -1
  131. package/dist/integration/CustomColumnPromoter.js.map +1 -1
  132. package/dist/logging/variablesLoggingMiddleware.d.ts +12 -0
  133. package/dist/logging/variablesLoggingMiddleware.d.ts.map +1 -1
  134. package/dist/logging/variablesLoggingMiddleware.js +50 -1
  135. package/dist/logging/variablesLoggingMiddleware.js.map +1 -1
  136. package/dist/multiTenancy/index.d.ts.map +1 -1
  137. package/dist/multiTenancy/index.js +22 -2
  138. package/dist/multiTenancy/index.js.map +1 -1
  139. package/dist/realtimeSessions/RealtimeSessionVerificationService.d.ts.map +1 -1
  140. package/dist/realtimeSessions/RealtimeSessionVerificationService.js +2 -1
  141. package/dist/realtimeSessions/RealtimeSessionVerificationService.js.map +1 -1
  142. package/dist/realtimeSessions/RealtimeVerifyRouter.d.ts.map +1 -1
  143. package/dist/realtimeSessions/RealtimeVerifyRouter.js +2 -1
  144. package/dist/realtimeSessions/RealtimeVerifyRouter.js.map +1 -1
  145. package/dist/realtimeSessions/RecordingAssemblyScheduler.d.ts +100 -0
  146. package/dist/realtimeSessions/RecordingAssemblyScheduler.d.ts.map +1 -0
  147. package/dist/realtimeSessions/RecordingAssemblyScheduler.js +173 -0
  148. package/dist/realtimeSessions/RecordingAssemblyScheduler.js.map +1 -0
  149. package/dist/realtimeSessions/SessionVerificationPortsBase.d.ts.map +1 -1
  150. package/dist/realtimeSessions/SessionVerificationPortsBase.js +1 -0
  151. package/dist/realtimeSessions/SessionVerificationPortsBase.js.map +1 -1
  152. package/dist/realtimeSessions/index.d.ts +2 -0
  153. package/dist/realtimeSessions/index.d.ts.map +1 -1
  154. package/dist/realtimeSessions/index.js +2 -0
  155. package/dist/realtimeSessions/index.js.map +1 -1
  156. package/dist/realtimeSessions/ownedRealtimeSession.d.ts +32 -0
  157. package/dist/realtimeSessions/ownedRealtimeSession.d.ts.map +1 -0
  158. package/dist/realtimeSessions/ownedRealtimeSession.js +56 -0
  159. package/dist/realtimeSessions/ownedRealtimeSession.js.map +1 -0
  160. package/dist/realtimeSessions/sessionAccess.d.ts +91 -8
  161. package/dist/realtimeSessions/sessionAccess.d.ts.map +1 -1
  162. package/dist/realtimeSessions/sessionAccess.js +127 -20
  163. package/dist/realtimeSessions/sessionAccess.js.map +1 -1
  164. package/dist/realtimeSessions/sessionConfigStamps.js +1 -1
  165. package/dist/realtimeSessions/sessionConfigStamps.js.map +1 -1
  166. package/dist/realtimeSessions/subscriptionAuthorization.d.ts.map +1 -1
  167. package/dist/realtimeSessions/subscriptionAuthorization.js +5 -2
  168. package/dist/realtimeSessions/subscriptionAuthorization.js.map +1 -1
  169. package/dist/realtimeSessions/verificationWorkflow.d.ts +2 -0
  170. package/dist/realtimeSessions/verificationWorkflow.d.ts.map +1 -1
  171. package/dist/realtimeSessions/verificationWorkflow.js +1 -1
  172. package/dist/realtimeSessions/verificationWorkflow.js.map +1 -1
  173. package/dist/realtimeWidget/WidgetRouter.d.ts.map +1 -1
  174. package/dist/realtimeWidget/WidgetRouter.js +19 -3
  175. package/dist/realtimeWidget/WidgetRouter.js.map +1 -1
  176. package/dist/realtimeWidget/WidgetSessionService.d.ts +67 -7
  177. package/dist/realtimeWidget/WidgetSessionService.d.ts.map +1 -1
  178. package/dist/realtimeWidget/WidgetSessionService.js +201 -19
  179. package/dist/realtimeWidget/WidgetSessionService.js.map +1 -1
  180. package/dist/realtimeWidget/host-identity.d.ts +1 -1
  181. package/dist/realtimeWidget/host-identity.js +1 -1
  182. package/dist/realtimeWidget/widgetCore.d.ts +20 -1
  183. package/dist/realtimeWidget/widgetCore.d.ts.map +1 -1
  184. package/dist/realtimeWidget/widgetCore.js +17 -1
  185. package/dist/realtimeWidget/widgetCore.js.map +1 -1
  186. package/dist/realtimeWidget/widgetGuestElevation.d.ts +1 -1
  187. package/dist/realtimeWidget/widgetGuestElevation.d.ts.map +1 -1
  188. package/dist/realtimeWidget/widgetGuestElevation.js +2 -1
  189. package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -1
  190. package/dist/resolvers/ActionResolver.d.ts +19 -1
  191. package/dist/resolvers/ActionResolver.d.ts.map +1 -1
  192. package/dist/resolvers/ActionResolver.js +63 -12
  193. package/dist/resolvers/ActionResolver.js.map +1 -1
  194. package/dist/resolvers/AdhocQueryResolver.d.ts.map +1 -1
  195. package/dist/resolvers/AdhocQueryResolver.js +1 -0
  196. package/dist/resolvers/AdhocQueryResolver.js.map +1 -1
  197. package/dist/resolvers/AgentRunStatusPublisher.d.ts +18 -4
  198. package/dist/resolvers/AgentRunStatusPublisher.d.ts.map +1 -1
  199. package/dist/resolvers/AgentRunStatusPublisher.js +32 -8
  200. package/dist/resolvers/AgentRunStatusPublisher.js.map +1 -1
  201. package/dist/resolvers/AgentSessionResolver.d.ts +10 -4
  202. package/dist/resolvers/AgentSessionResolver.d.ts.map +1 -1
  203. package/dist/resolvers/AgentSessionResolver.js +40 -17
  204. package/dist/resolvers/AgentSessionResolver.js.map +1 -1
  205. package/dist/resolvers/ArtifactFileResolver.d.ts +5 -1
  206. package/dist/resolvers/ArtifactFileResolver.d.ts.map +1 -1
  207. package/dist/resolvers/ArtifactFileResolver.js +9 -7
  208. package/dist/resolvers/ArtifactFileResolver.js.map +1 -1
  209. package/dist/resolvers/ConversationRunEventsResolver.d.ts +8 -4
  210. package/dist/resolvers/ConversationRunEventsResolver.d.ts.map +1 -1
  211. package/dist/resolvers/ConversationRunEventsResolver.js +6 -6
  212. package/dist/resolvers/ConversationRunEventsResolver.js.map +1 -1
  213. package/dist/resolvers/DatasetResolver.d.ts +24 -3
  214. package/dist/resolvers/DatasetResolver.d.ts.map +1 -1
  215. package/dist/resolvers/DatasetResolver.js +57 -8
  216. package/dist/resolvers/DatasetResolver.js.map +1 -1
  217. package/dist/resolvers/EntityCommunicationsResolver.d.ts +13 -1
  218. package/dist/resolvers/EntityCommunicationsResolver.d.ts.map +1 -1
  219. package/dist/resolvers/EntityCommunicationsResolver.js +50 -14
  220. package/dist/resolvers/EntityCommunicationsResolver.js.map +1 -1
  221. package/dist/resolvers/EntityRecordNameResolver.d.ts +2 -1
  222. package/dist/resolvers/EntityRecordNameResolver.d.ts.map +1 -1
  223. package/dist/resolvers/EntityRecordNameResolver.js +3 -2
  224. package/dist/resolvers/EntityRecordNameResolver.js.map +1 -1
  225. package/dist/resolvers/FetchEntityVectorsResolver.d.ts +46 -3
  226. package/dist/resolvers/FetchEntityVectorsResolver.d.ts.map +1 -1
  227. package/dist/resolvers/FetchEntityVectorsResolver.js +211 -50
  228. package/dist/resolvers/FetchEntityVectorsResolver.js.map +1 -1
  229. package/dist/resolvers/FileCategoryResolver.d.ts.map +1 -1
  230. package/dist/resolvers/FileCategoryResolver.js +1 -0
  231. package/dist/resolvers/FileCategoryResolver.js.map +1 -1
  232. package/dist/resolvers/FileResolver.d.ts +87 -11
  233. package/dist/resolvers/FileResolver.d.ts.map +1 -1
  234. package/dist/resolvers/FileResolver.js +292 -105
  235. package/dist/resolvers/FileResolver.js.map +1 -1
  236. package/dist/resolvers/GetDataContextDataResolver.d.ts +33 -7
  237. package/dist/resolvers/GetDataContextDataResolver.d.ts.map +1 -1
  238. package/dist/resolvers/GetDataContextDataResolver.js +117 -38
  239. package/dist/resolvers/GetDataContextDataResolver.js.map +1 -1
  240. package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
  241. package/dist/resolvers/GetDataResolver.js +6 -3
  242. package/dist/resolvers/GetDataResolver.js.map +1 -1
  243. package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
  244. package/dist/resolvers/IntegrationDiscoveryResolver.js +49 -9
  245. package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
  246. package/dist/resolvers/MergeRecordsResolver.d.ts +8 -1
  247. package/dist/resolvers/MergeRecordsResolver.d.ts.map +1 -1
  248. package/dist/resolvers/MergeRecordsResolver.js +31 -3
  249. package/dist/resolvers/MergeRecordsResolver.js.map +1 -1
  250. package/dist/resolvers/PipelineProgressResolver.d.ts +6 -0
  251. package/dist/resolvers/PipelineProgressResolver.d.ts.map +1 -1
  252. package/dist/resolvers/PipelineProgressResolver.js +5 -3
  253. package/dist/resolvers/PipelineProgressResolver.js.map +1 -1
  254. package/dist/resolvers/QueryResolver.d.ts +2 -0
  255. package/dist/resolvers/QueryResolver.d.ts.map +1 -1
  256. package/dist/resolvers/QueryResolver.js +33 -6
  257. package/dist/resolvers/QueryResolver.js.map +1 -1
  258. package/dist/resolvers/QuerySystemUserResolver.d.ts +2 -0
  259. package/dist/resolvers/QuerySystemUserResolver.d.ts.map +1 -1
  260. package/dist/resolvers/QuerySystemUserResolver.js +15 -6
  261. package/dist/resolvers/QuerySystemUserResolver.js.map +1 -1
  262. package/dist/resolvers/RSUResolver.d.ts.map +1 -1
  263. package/dist/resolvers/RSUResolver.js +12 -0
  264. package/dist/resolvers/RSUResolver.js.map +1 -1
  265. package/dist/resolvers/RealtimeClientSessionResolver.d.ts +18 -10
  266. package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
  267. package/dist/resolvers/RealtimeClientSessionResolver.js +92 -54
  268. package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
  269. package/dist/resolvers/RemoteBrowserActionResolver.d.ts.map +1 -1
  270. package/dist/resolvers/RemoteBrowserActionResolver.js +11 -9
  271. package/dist/resolvers/RemoteBrowserActionResolver.js.map +1 -1
  272. package/dist/resolvers/RunAIAgentResolver.d.ts +56 -8
  273. package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
  274. package/dist/resolvers/RunAIAgentResolver.js +241 -67
  275. package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
  276. package/dist/resolvers/RunTemplateResolver.d.ts.map +1 -1
  277. package/dist/resolvers/RunTemplateResolver.js +4 -4
  278. package/dist/resolvers/RunTemplateResolver.js.map +1 -1
  279. package/dist/resolvers/RunTestResolver.d.ts.map +1 -1
  280. package/dist/resolvers/RunTestResolver.js +3 -1
  281. package/dist/resolvers/RunTestResolver.js.map +1 -1
  282. package/dist/resolvers/SearchKnowledgeStreamResolver.d.ts +12 -1
  283. package/dist/resolvers/SearchKnowledgeStreamResolver.d.ts.map +1 -1
  284. package/dist/resolvers/SearchKnowledgeStreamResolver.js +15 -2
  285. package/dist/resolvers/SearchKnowledgeStreamResolver.js.map +1 -1
  286. package/dist/resolvers/SqlLoggingConfigResolver.d.ts.map +1 -1
  287. package/dist/resolvers/SqlLoggingConfigResolver.js +2 -3
  288. package/dist/resolvers/SqlLoggingConfigResolver.js.map +1 -1
  289. package/dist/resolvers/SyncDataResolver.d.ts.map +1 -1
  290. package/dist/resolvers/SyncDataResolver.js +4 -0
  291. package/dist/resolvers/SyncDataResolver.js.map +1 -1
  292. package/dist/resolvers/TaskGraphFrameResolver.d.ts +2 -1
  293. package/dist/resolvers/TaskGraphFrameResolver.d.ts.map +1 -1
  294. package/dist/resolvers/TaskGraphFrameResolver.js +28 -1
  295. package/dist/resolvers/TaskGraphFrameResolver.js.map +1 -1
  296. package/dist/resolvers/TestQuerySQLResolver.d.ts +24 -0
  297. package/dist/resolvers/TestQuerySQLResolver.d.ts.map +1 -1
  298. package/dist/resolvers/TestQuerySQLResolver.js +66 -13
  299. package/dist/resolvers/TestQuerySQLResolver.js.map +1 -1
  300. package/dist/resolvers/TransactionGroupResolver.d.ts +34 -2
  301. package/dist/resolvers/TransactionGroupResolver.d.ts.map +1 -1
  302. package/dist/resolvers/TransactionGroupResolver.js +150 -27
  303. package/dist/resolvers/TransactionGroupResolver.js.map +1 -1
  304. package/dist/resolvers/UserViewResolver.d.ts +1 -1
  305. package/dist/resolvers/UserViewResolver.d.ts.map +1 -1
  306. package/dist/resolvers/UserViewResolver.js +2 -1
  307. package/dist/resolvers/UserViewResolver.js.map +1 -1
  308. package/dist/resolvers/agent-run-data-guard.d.ts +31 -0
  309. package/dist/resolvers/agent-run-data-guard.d.ts.map +1 -0
  310. package/dist/resolvers/agent-run-data-guard.js +72 -0
  311. package/dist/resolvers/agent-run-data-guard.js.map +1 -0
  312. package/dist/rest/EntityCRUDHandler.d.ts +6 -0
  313. package/dist/rest/EntityCRUDHandler.d.ts.map +1 -1
  314. package/dist/rest/EntityCRUDHandler.js +19 -5
  315. package/dist/rest/EntityCRUDHandler.js.map +1 -1
  316. package/dist/rest/RESTEndpointHandler.d.ts.map +1 -1
  317. package/dist/rest/RESTEndpointHandler.js +8 -5
  318. package/dist/rest/RESTEndpointHandler.js.map +1 -1
  319. package/dist/rest/RealtimeRecordingHandler.d.ts +49 -0
  320. package/dist/rest/RealtimeRecordingHandler.d.ts.map +1 -0
  321. package/dist/rest/RealtimeRecordingHandler.js +383 -0
  322. package/dist/rest/RealtimeRecordingHandler.js.map +1 -0
  323. package/dist/rest/ViewOperationsHandler.d.ts +9 -1
  324. package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
  325. package/dist/rest/ViewOperationsHandler.js +43 -17
  326. package/dist/rest/ViewOperationsHandler.js.map +1 -1
  327. package/dist/rest/setupRESTEndpoints.d.ts +6 -0
  328. package/dist/rest/setupRESTEndpoints.d.ts.map +1 -1
  329. package/dist/rest/setupRESTEndpoints.js +6 -0
  330. package/dist/rest/setupRESTEndpoints.js.map +1 -1
  331. package/dist/serverExtensionReservedRoots.d.ts +12 -10
  332. package/dist/serverExtensionReservedRoots.d.ts.map +1 -1
  333. package/dist/serverExtensionReservedRoots.js +14 -17
  334. package/dist/serverExtensionReservedRoots.js.map +1 -1
  335. package/dist/serverRoleConfigUnits.d.ts +29 -0
  336. package/dist/serverRoleConfigUnits.d.ts.map +1 -0
  337. package/dist/serverRoleConfigUnits.js +33 -0
  338. package/dist/serverRoleConfigUnits.js.map +1 -0
  339. package/dist/services/MJStorageBlobStore.d.ts +8 -1
  340. package/dist/services/MJStorageBlobStore.d.ts.map +1 -1
  341. package/dist/services/MJStorageBlobStore.js +25 -19
  342. package/dist/services/MJStorageBlobStore.js.map +1 -1
  343. package/dist/services/StartTaskGraphDispatcher.js +2 -2
  344. package/dist/services/StartTaskGraphDispatcher.js.map +1 -1
  345. package/dist/services/TaskGraphActionRunner.d.ts +5 -3
  346. package/dist/services/TaskGraphActionRunner.d.ts.map +1 -1
  347. package/dist/services/TaskGraphActionRunner.js +27 -5
  348. package/dist/services/TaskGraphActionRunner.js.map +1 -1
  349. package/dist/services/TaskGraphAgentRunner.d.ts +14 -2
  350. package/dist/services/TaskGraphAgentRunner.d.ts.map +1 -1
  351. package/dist/services/TaskGraphAgentRunner.js +157 -9
  352. package/dist/services/TaskGraphAgentRunner.js.map +1 -1
  353. package/dist/services/TaskGraphContinuationDeliverer.d.ts +59 -2
  354. package/dist/services/TaskGraphContinuationDeliverer.d.ts.map +1 -1
  355. package/dist/services/TaskGraphContinuationDeliverer.js +626 -16
  356. package/dist/services/TaskGraphContinuationDeliverer.js.map +1 -1
  357. package/dist/sharedCache.d.ts.map +1 -1
  358. package/dist/sharedCache.js +3 -0
  359. package/dist/sharedCache.js.map +1 -1
  360. package/dist/types.d.ts +23 -1
  361. package/dist/types.d.ts.map +1 -1
  362. package/dist/types.js.map +1 -1
  363. package/package.json +99 -98
  364. package/src/__tests__/ActionResolver.fieldSecurity.test.ts +237 -0
  365. package/src/__tests__/AdhocQueryResolver.dialect.test.ts +137 -0
  366. package/src/__tests__/AgentRunStatusPublisher.test.ts +49 -0
  367. package/src/__tests__/AgentSessionResolver.ownership.test.ts +137 -0
  368. package/src/__tests__/CustomColumnPromoterOnePass.test.ts +15 -1
  369. package/src/__tests__/DatasetResolver.itemFilters.test.ts +201 -0
  370. package/src/__tests__/EntityCommunicationsResolver.actingUser.test.ts +151 -0
  371. package/src/__tests__/EntityRecordNameResolver.rowSecurity.test.ts +152 -0
  372. package/src/__tests__/EvolutionActsOnWhatItDetects.test.ts +113 -0
  373. package/src/__tests__/FetchEntityVectorsResolver.test.ts +369 -18
  374. package/src/__tests__/FileResolver.fieldSecurity.test.ts +82 -0
  375. package/src/__tests__/FileResolver.storageAccess.test.ts +562 -0
  376. package/src/__tests__/GetDataContextDataResolver.sqlItems.test.ts +416 -0
  377. package/src/__tests__/ListOperationsResolver.adhocScreen.test.ts +137 -0
  378. package/src/__tests__/LoginScreenEngine.test.ts +86 -0
  379. package/src/__tests__/MJStorageBlobStore.storageGate.test.ts +63 -0
  380. package/src/__tests__/PipelineProgressResolver.filter.test.ts +58 -0
  381. package/src/__tests__/QuerySystemUserResolver.fieldSecurity.test.ts +49 -0
  382. package/src/__tests__/RESTEndpointHandler.test.ts +25 -0
  383. package/src/__tests__/RealtimeClientSessionResolver.configTamper.test.ts +23 -3
  384. package/src/__tests__/RealtimeClientSessionResolver.test.ts +324 -46
  385. package/src/__tests__/RecordingAssemblyScheduler.test.ts +178 -0
  386. package/src/__tests__/RemoteBrowserActionResolver.ownership.test.ts +98 -0
  387. package/src/__tests__/ResolverBase.adhocReadScope.test.ts +133 -2
  388. package/src/__tests__/ResolverBase.balancedClause.test.ts +155 -0
  389. package/src/__tests__/ResolverBase.clauseUnscopedRead.test.ts +127 -0
  390. package/src/__tests__/ResolverBase.clientOldValues.test.ts +243 -7
  391. package/src/__tests__/ResolverBase.deleteReturnProjection.test.ts +52 -0
  392. package/src/__tests__/ResolverBase.entityMessageRelay.test.ts +176 -0
  393. package/src/__tests__/ResolverBase.filterEscaping.test.ts +5 -2
  394. package/src/__tests__/ResolverBase.includeBinaryFields.test.ts +23 -1
  395. package/src/__tests__/ResolverBase.publishStatusUpdate.test.ts +68 -0
  396. package/src/__tests__/ResolverBase.userViewCacheAndDedup.test.ts +130 -0
  397. package/src/__tests__/RunAIAgentResolver.branch.test.ts +69 -13
  398. package/src/__tests__/RunAIAgentResolver.conversationWriter.test.ts +210 -0
  399. package/src/__tests__/RunAIAgentResolver.fireAndForgetCompletion.test.ts +209 -0
  400. package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +20 -28
  401. package/src/__tests__/RunAIAgentResolver.runDataGuard.test.ts +264 -0
  402. package/src/__tests__/RunAIAgentResolver.serverReply.test.ts +358 -0
  403. package/src/__tests__/RunAIAgentResolver.stoppedPredecessor.test.ts +4 -1
  404. package/src/__tests__/RunTemplateResolver.test.ts +35 -2
  405. package/src/__tests__/RunViewResolver.cacheCheckForwarding.test.ts +11 -0
  406. package/src/__tests__/RunViewResolver.cacheCheckScreen.test.ts +165 -0
  407. package/src/__tests__/SearchKnowledgeStreamResolver.test.ts +161 -0
  408. package/src/__tests__/SessionJanitor.test.ts +365 -10
  409. package/src/__tests__/SessionManager.test.ts +122 -0
  410. package/src/__tests__/TaskGraphActionRunner.durablePayload.test.ts +25 -0
  411. package/src/__tests__/TaskGraphAgentRunner.test.ts +266 -0
  412. package/src/__tests__/TaskGraphContinuationDeliverer.test.ts +468 -23
  413. package/src/__tests__/TaskGraphFrameResolver.test.ts +22 -0
  414. package/src/__tests__/TestQuerySQLResolver.test.ts +274 -0
  415. package/src/__tests__/TransactionGroupResolver.fieldSecurity.test.ts +199 -0
  416. package/src/__tests__/TransactionGroupResolver.refusals.test.ts +98 -1
  417. package/src/__tests__/UpdateMJDataContextItem.oldValues.test.ts +220 -0
  418. package/src/__tests__/UserViewResolver.updateWhereClause.test.ts +15 -0
  419. package/src/__tests__/ViewOperationsHandler.clauseScreen.test.ts +157 -0
  420. package/src/__tests__/ViewOperationsHandler.test.ts +7 -2
  421. package/src/__tests__/WidgetSessionService.test.ts +583 -4
  422. package/src/__tests__/agent-run-data-guard.test.ts +130 -0
  423. package/src/__tests__/apiRootBoot.test.ts +202 -0
  424. package/src/__tests__/buildMagicLinkSessionUser.test.ts +96 -0
  425. package/src/__tests__/cacheBroadcastProviders.test.ts +403 -0
  426. package/src/__tests__/cacheInvalidationRecordData.test.ts +109 -0
  427. package/src/__tests__/conversationRunEvents.test.ts +56 -14
  428. package/src/__tests__/fieldSecurityFixtures.ts +91 -0
  429. package/src/__tests__/globalCors.test.ts +217 -0
  430. package/src/__tests__/localDevAuth.test.ts +196 -0
  431. package/src/__tests__/multiTenancy.postgresRewrite.test.ts +181 -0
  432. package/src/__tests__/multiTenancy.security.test.ts +51 -0
  433. package/src/__tests__/multiTenancy.test.ts +1 -1
  434. package/src/__tests__/orphanedConversationDetailReconciler.test.ts +10 -0
  435. package/src/__tests__/ownedRealtimeSession.test.ts +39 -0
  436. package/src/__tests__/pushStatusResolver.filter.test.ts +64 -1
  437. package/src/__tests__/realtimeRecordingHandler.test.ts +669 -0
  438. package/src/__tests__/realtimeSessions/RealtimeSessionEventsResolver.test.ts +29 -1
  439. package/src/__tests__/realtimeSessions/ownedRealtimeSession.anonymous.test.ts +31 -0
  440. package/src/__tests__/realtimeSessions/ownedRealtimeSession.namedScoped.test.ts +37 -0
  441. package/src/__tests__/realtimeSessions/sessionAccess.test.ts +146 -7
  442. package/src/__tests__/realtimeSessions/sessionConfigStamps.test.ts +1 -1
  443. package/src/__tests__/realtimeSessions/verificationWorkflow.test.ts +25 -4
  444. package/src/__tests__/resolverBase.cloudEventChangedFields.test.ts +157 -0
  445. package/src/__tests__/resolverBase.fieldSecurityTransport.test.ts +222 -0
  446. package/src/__tests__/resolverBase.fls.test.ts +146 -97
  447. package/src/__tests__/restTransport.fieldSecurity.test.ts +148 -0
  448. package/src/__tests__/runParamsTimeZone.test.ts +179 -0
  449. package/src/__tests__/runStreams.fieldSecurity.test.ts +100 -0
  450. package/src/__tests__/runViewProperties.test.ts +114 -0
  451. package/src/__tests__/scalabilityBenchmarks.test.ts +765 -0
  452. package/src/__tests__/scalabilityDatabaseIntegration.test.ts +207 -0
  453. package/src/__tests__/serverExtensionHostOverlay.test.ts +66 -0
  454. package/src/__tests__/serverExtensionReservedRoots.test.ts +11 -98
  455. package/src/__tests__/sessionUserClone.test.ts +5 -1
  456. package/src/__tests__/sharedCache.test.ts +5 -3
  457. package/src/__tests__/startupSweepOrder.test.ts +40 -0
  458. package/src/__tests__/unifiedAuth.test.ts +28 -0
  459. package/src/__tests__/widgetGuestElevation.test.ts +2 -0
  460. package/src/agentSessions/SessionJanitor.ts +369 -93
  461. package/src/agentSessions/SessionManager.ts +45 -10
  462. package/src/apiRoot.ts +78 -0
  463. package/src/auth/AuthProviderCatalogRouter.ts +29 -0
  464. package/src/auth/LoginScreenEngine.ts +50 -0
  465. package/src/auth/index.ts +57 -12
  466. package/src/auth/initializeProviders.ts +43 -1
  467. package/src/auth/localDevAuth.ts +528 -0
  468. package/src/auth/magicLink/MagicLinkKeys.ts +2 -2
  469. package/src/auth/magicLink/MagicLinkRouter.ts +3 -2
  470. package/src/auth/magicLink/types.ts +10 -0
  471. package/src/auth/sessionUserClone.ts +3 -2
  472. package/src/broadcast/BaseCacheInvalidationBroadcastProvider.ts +674 -0
  473. package/src/broadcast/index.ts +5 -0
  474. package/src/broadcast/providers/AWSIoTCoreBroadcastProvider.ts +180 -0
  475. package/src/broadcast/providers/AzureWebPubSubBroadcastProvider.ts +182 -0
  476. package/src/broadcast/providers/GCPPubSubBroadcastProvider.ts +169 -0
  477. package/src/broadcast/providers/SequencedRoleBucketBroadcastProvider.ts +57 -0
  478. package/src/cache.ts +2 -1
  479. package/src/config.ts +115 -5
  480. package/src/context.ts +32 -8
  481. package/src/coreRoutes.ts +181 -0
  482. package/src/generated/graphql-schemas/__mj.ts +3684 -284
  483. package/src/generic/CacheInvalidationResolver.ts +172 -60
  484. package/src/generic/OrphanedConversationDetailReconciler.ts +4 -2
  485. package/src/generic/PubSubManager.ts +54 -1
  486. package/src/generic/PushStatusResolver.ts +109 -12
  487. package/src/generic/ResolverBase.ts +540 -431
  488. package/src/generic/RunViewResolver.ts +97 -15
  489. package/src/generic/actionOutputFieldSecurity.ts +75 -0
  490. package/src/generic/fieldSecurityTransport.ts +62 -0
  491. package/src/globalCors.ts +71 -0
  492. package/src/index.ts +239 -238
  493. package/src/integration/CustomColumnPromoter.ts +6 -1
  494. package/src/logging/variablesLoggingMiddleware.ts +59 -3
  495. package/src/multiTenancy/index.ts +24 -2
  496. package/src/realtimeSessions/README.md +7 -3
  497. package/src/realtimeSessions/RealtimeSessionVerificationService.ts +2 -1
  498. package/src/realtimeSessions/RealtimeVerifyRouter.ts +2 -1
  499. package/src/realtimeSessions/RecordingAssemblyScheduler.ts +234 -0
  500. package/src/realtimeSessions/SessionVerificationPortsBase.ts +1 -0
  501. package/src/realtimeSessions/index.ts +2 -0
  502. package/src/realtimeSessions/ownedRealtimeSession.ts +69 -0
  503. package/src/realtimeSessions/sessionAccess.ts +183 -23
  504. package/src/realtimeSessions/sessionConfigStamps.ts +1 -1
  505. package/src/realtimeSessions/subscriptionAuthorization.ts +4 -2
  506. package/src/realtimeSessions/verificationWorkflow.ts +3 -1
  507. package/src/realtimeWidget/WidgetRouter.ts +22 -4
  508. package/src/realtimeWidget/WidgetSessionService.ts +252 -17
  509. package/src/realtimeWidget/host-identity.ts +1 -1
  510. package/src/realtimeWidget/widgetCore.ts +30 -1
  511. package/src/realtimeWidget/widgetGuestElevation.ts +2 -1
  512. package/src/resolvers/ActionResolver.ts +78 -15
  513. package/src/resolvers/AdhocQueryResolver.ts +1 -0
  514. package/src/resolvers/AgentRunStatusPublisher.ts +36 -8
  515. package/src/resolvers/AgentSessionResolver.ts +46 -18
  516. package/src/resolvers/ArtifactFileResolver.ts +9 -8
  517. package/src/resolvers/ConversationRunEventsResolver.ts +15 -11
  518. package/src/resolvers/DatasetResolver.ts +70 -10
  519. package/src/resolvers/EntityCommunicationsResolver.ts +56 -15
  520. package/src/resolvers/EntityRecordNameResolver.ts +3 -2
  521. package/src/resolvers/FetchEntityVectorsResolver.ts +248 -55
  522. package/src/resolvers/FileCategoryResolver.ts +1 -0
  523. package/src/resolvers/FileResolver.ts +334 -109
  524. package/src/resolvers/GetDataContextDataResolver.ts +139 -41
  525. package/src/resolvers/GetDataResolver.ts +6 -3
  526. package/src/resolvers/IntegrationDiscoveryResolver.ts +53 -9
  527. package/src/resolvers/MergeRecordsResolver.ts +23 -2
  528. package/src/resolvers/PipelineProgressResolver.ts +12 -3
  529. package/src/resolvers/QueryResolver.ts +31 -6
  530. package/src/resolvers/QuerySystemUserResolver.ts +15 -6
  531. package/src/resolvers/RSUResolver.ts +12 -0
  532. package/src/resolvers/RealtimeClientSessionResolver.ts +114 -66
  533. package/src/resolvers/RemoteBrowserActionResolver.ts +15 -10
  534. package/src/resolvers/RunAIAgentResolver.ts +296 -85
  535. package/src/resolvers/RunTemplateResolver.ts +6 -4
  536. package/src/resolvers/RunTestResolver.ts +3 -1
  537. package/src/resolvers/SearchKnowledgeStreamResolver.ts +19 -3
  538. package/src/resolvers/SqlLoggingConfigResolver.ts +2 -4
  539. package/src/resolvers/SyncDataResolver.ts +4 -0
  540. package/src/resolvers/TaskGraphFrameResolver.ts +33 -1
  541. package/src/resolvers/TestQuerySQLResolver.ts +69 -13
  542. package/src/resolvers/TransactionGroupResolver.ts +185 -30
  543. package/src/resolvers/UserViewResolver.ts +2 -1
  544. package/src/resolvers/__tests__/GetDataResolver.validation.test.ts +95 -0
  545. package/src/resolvers/__tests__/MergeRecordsResolver.test.ts +43 -0
  546. package/src/resolvers/agent-run-data-guard.ts +89 -0
  547. package/src/rest/EntityCRUDHandler.ts +22 -5
  548. package/src/rest/RESTEndpointHandler.ts +8 -5
  549. package/src/rest/RealtimeRecordingHandler.ts +467 -0
  550. package/src/rest/ViewOperationsHandler.ts +52 -18
  551. package/src/rest/setupRESTEndpoints.ts +6 -0
  552. package/src/serverExtensionReservedRoots.ts +14 -17
  553. package/src/serverRoleConfigUnits.ts +48 -0
  554. package/src/services/MJStorageBlobStore.ts +31 -30
  555. package/src/services/StartTaskGraphDispatcher.ts +2 -2
  556. package/src/services/TaskGraphActionRunner.ts +25 -5
  557. package/src/services/TaskGraphAgentRunner.ts +188 -11
  558. package/src/services/TaskGraphContinuationDeliverer.ts +738 -16
  559. package/src/sharedCache.ts +3 -0
  560. package/src/types.ts +23 -1
@@ -300,7 +300,12 @@ export class IntegrationCustomColumnPromoter {
300
300
  // step with the database.
301
301
  let batchResults: RSUPipelineResult[] = [];
302
302
  if (batchInputs.length > 0) {
303
- const batch = await RuntimeSchemaManager.Instance.RunPipelineBatch(batchInputs);
303
+ // Retrying variant. This runs UNATTENDED, mid-sync, with no operator watching: a
304
+ // transient ExecuteMigration / RunCodeGen / CompileTypeScript / RestartMJAPI failure
305
+ // drops the whole promotion, and the columns simply stay in overflow until something
306
+ // triggers a promotion again. The wrapper replays only those four steps and only while
307
+ // nothing in the batch was applied, so a partially-applied batch is still returned as-is.
308
+ const batch = await RuntimeSchemaManager.Instance.RunPipelineBatchWithRetry(batchInputs);
304
309
  batchResults = batch.Results ?? [];
305
310
  // M3: make the freshly-created EntityFields + regenerated sprocs visible in-process
306
311
  // ONCE for the whole batch. CRITICAL: the spread below builds sproc calls from this
@@ -1,7 +1,7 @@
1
- import type { MiddlewareFn } from 'type-graphql';
1
+ import type { MiddlewareFn, ResolverData } from 'type-graphql';
2
2
  import { getMetadataStorage } from 'type-graphql';
3
- import { getNamedType } from 'graphql';
4
- import type { GraphQLArgument } from 'graphql';
3
+ import { defaultFieldResolver, getNamedType } from 'graphql';
4
+ import type { GraphQLArgument, GraphQLField, GraphQLObjectType, GraphQLSchema } from 'graphql';
5
5
  import { configInfo } from '../config.js';
6
6
  import type { AppContext } from '../types.js';
7
7
  import { RedactArg } from './secretRedactor.js';
@@ -191,6 +191,62 @@ export const VariablesLoggingMiddleware: MiddlewareFn<AppContext> = async (actio
191
191
  /** @deprecated Use {@link VariablesLoggingMiddleware}. */
192
192
  export const variablesLoggingMiddleware: MiddlewareFn<AppContext> = VariablesLoggingMiddleware;
193
193
 
194
+ /**
195
+ * Attaches {@link VariablesLoggingMiddleware} ONLY to root `Query`, `Mutation`, and `Subscription`
196
+ * fields on the compiled GraphQLSchema instead of registering it via TypeGraphQL `globalMiddlewares`.
197
+ *
198
+ * Registering a global middleware in TypeGraphQL wraps every scalar and child field resolver across
199
+ * all 300+ `@ObjectType` entities in an async middleware chain, allocating $O(\text{Rows} \times \text{Fields})$
200
+ * Promises per query even when `logVariables` is false or `info.path.prev !== undefined`.
201
+ * Wrapping only the root operation fields reduces middleware invocations from ~15,000 per 500-row
202
+ * `RunView` response down to 1.
203
+ */
204
+ export function ApplyRootVariablesLoggingMiddleware(
205
+ schema: GraphQLSchema,
206
+ middleware: MiddlewareFn<AppContext> = VariablesLoggingMiddleware
207
+ ): GraphQLSchema {
208
+ const rootTypes: Array<GraphQLObjectType | null | undefined> = [
209
+ schema.getQueryType(),
210
+ schema.getMutationType(),
211
+ schema.getSubscriptionType(),
212
+ ];
213
+
214
+ for (const rootType of rootTypes) {
215
+ if (!rootType) continue;
216
+ const fields = rootType.getFields();
217
+ for (const field of Object.values(fields) as Array<GraphQLField<unknown, AppContext>>) {
218
+ if (field.resolve) {
219
+ const originalResolve = field.resolve;
220
+ field.resolve = (root, args, context, info) => {
221
+ const action: ResolverData<AppContext> = {
222
+ root,
223
+ args: args as Record<string, unknown>,
224
+ context,
225
+ info,
226
+ };
227
+ return middleware(action, async () => originalResolve(root, args, context, info));
228
+ };
229
+ }
230
+ if (field.subscribe) {
231
+ const originalSubscribe = field.subscribe;
232
+ field.subscribe = (root, args, context, info) => {
233
+ const action: ResolverData<AppContext> = {
234
+ root,
235
+ args: args as Record<string, unknown>,
236
+ context,
237
+ info,
238
+ };
239
+ return middleware(action, async () =>
240
+ originalSubscribe ? originalSubscribe(root, args, context, info) : defaultFieldResolver(root, args, context, info)
241
+ );
242
+ };
243
+ }
244
+ }
245
+ }
246
+
247
+ return schema;
248
+ }
249
+
194
250
  /**
195
251
  * Heuristic: an arg is "custom" (i.e. needs `@NoLog` discipline because metadata can't redact it)
196
252
  * when its GraphQL input type is not a known `Create<X>Input` / `Update<X>Input` for an entity
@@ -9,7 +9,9 @@
9
9
 
10
10
  import type { RequestHandler } from 'express';
11
11
  import type { PreRunViewHook, PreSaveHook } from '@memberjunction/core';
12
- import { Metadata, type UserInfo, type TenantContext } from '@memberjunction/core';
12
+ import { DatabaseProviderBase, Metadata, type UserInfo, type TenantContext } from '@memberjunction/core';
13
+ import { PostgreSQLDialect, SQLServerDialect, type SQLParserDialect } from '@memberjunction/sql-dialect';
14
+ import { IsBalancedSQLFragment } from '@memberjunction/sql-parser';
13
15
  import type { MultiTenancyConfig } from '../config.js';
14
16
  import type { UserPayload } from '../types.js';
15
17
  import { CloneUserForSessionContext } from '../auth/sessionUserClone.js';
@@ -161,6 +163,25 @@ function isAdminUser(user: UserInfo, adminRoles: string[]): boolean {
161
163
  );
162
164
  }
163
165
 
166
+ /** Dialects to read an ExtraFilter with when the active provider's dialect cannot be resolved. */
167
+ const ALL_FILTER_DIALECTS: SQLParserDialect[] = [new SQLServerDialect(), new PostgreSQLDialect()];
168
+
169
+ /**
170
+ * Throws unless the caller's ExtraFilter stays inside the parentheses the tenant predicate is
171
+ * ANDed after. A filter such as `1=1) OR (1=1` would close them early and leave the tenant
172
+ * predicate on one side of an OR the caller controls.
173
+ */
174
+ function assertExtraFilterBalanced(extraFilter: string): void {
175
+ const provider = Metadata.Provider; // global-provider-ok: same rationale as isEntityScoped above — hooks carry no per-request provider
176
+ const dialects = provider instanceof DatabaseProviderBase ? [provider.Dialect] : ALL_FILTER_DIALECTS;
177
+ for (const dialect of dialects) {
178
+ const check = IsBalancedSQLFragment(extraFilter, dialect);
179
+ if (!check.IsBalanced) {
180
+ throw new Error(`[MultiTenancy] Invalid ExtraFilter: ${check.Reason}`);
181
+ }
182
+ }
183
+ }
184
+
164
185
  /**
165
186
  * Creates a PreRunViewHook that auto-injects tenant WHERE clauses
166
187
  * into RunView queries for scoped entities.
@@ -206,7 +227,8 @@ export function CreateTenantPreRunViewHook(config: MultiTenancyConfig): PreRunVi
206
227
 
207
228
  // Inject the tenant filter
208
229
  if (params.ExtraFilter && typeof params.ExtraFilter === 'string' && params.ExtraFilter.trim().length > 0) {
209
- params.ExtraFilter = `(${params.ExtraFilter}) AND ${tenantFilter}`;
230
+ assertExtraFilterBalanced(params.ExtraFilter);
231
+ params.ExtraFilter = `(${params.ExtraFilter}) AND (${tenantFilter})`;
210
232
  } else {
211
233
  params.ExtraFilter = tenantFilter;
212
234
  }
@@ -64,9 +64,13 @@ The principal comes from the **server-authenticated** context (`userPayload.user
64
64
  argument. An id argument only selects *which of the caller's own sessions*.
65
65
 
66
66
  A caller may use a session when `AIAgentSession.UserID` equals their user (`UUIDsEqual`). Widget guests all
67
- share one Anonymous user, so for an anonymous/magic-link principal that is **not enough**: the guest's
68
- signed per-session scope (`MagicLinkScope.ResourceID`) must equal the session's conversation `ExternalID`.
69
- An anonymous principal with no scope is refused outright.
67
+ share one Anonymous user, so for an anonymous/magic-link principal that is **not enough**: the session's
68
+ conversation `ExternalID` must equal the principal's scope identity (`ResolveSessionScopeIdentity`): the
69
+ signed `MagicLinkScope.ResourceID` when the token carries one, else the anonymous visitor's `mj_sid`.
70
+ `SessionManager` stamps that same value when it creates the conversation. An anonymous principal with
71
+ neither is refused outright. A *named* user with a resource scope must match too, which keeps one person's
72
+ different links apart; but it may also use its own session on a conversation that carries no stamp (one
73
+ started from the Conversations app) when its own row-level security let it read that conversation.
70
74
 
71
75
  - Refusals are uniform ("session not found") whether the session is missing or simply not yours, so ids
72
76
  cannot be probed.
@@ -30,6 +30,7 @@ import {
30
30
  type VerificationOperationResult,
31
31
  type VerificationSettings,
32
32
  } from './verificationWorkflow.js';
33
+ import { ConfiguredPublicUrl } from '../apiRoot.js';
33
34
 
34
35
  /** Purpose label for principal-resolution diagnostics. */
35
36
  const PRINCIPAL_PURPOSE = 'RealtimeVerification';
@@ -37,7 +38,7 @@ const PRINCIPAL_PURPOSE = 'RealtimeVerification';
37
38
  /** The base URL emailed links are built from: explicit setting, else the server's public URL (same derivation magic links use). */
38
39
  function resolvePublicBaseUrl(explicit: string | undefined): string | undefined {
39
40
  const candidate =
40
- explicit?.trim() || configInfo.publicUrl || `${configInfo.baseUrl}:${configInfo.graphqlPort}${configInfo.graphqlRootPath || ''}`;
41
+ explicit?.trim() || ConfiguredPublicUrl();
41
42
  return candidate ? TrimTrailingSlashes(candidate) : undefined;
42
43
  }
43
44
 
@@ -31,6 +31,7 @@ import { LogError } from '@memberjunction/core';
31
31
  import { configInfo } from '../config.js';
32
32
  import { RealtimeSessionVerificationService } from './RealtimeSessionVerificationService.js';
33
33
  import { BuildVerifyConfirmHtml, BuildVerifyErrorHtml, BuildVerifyFailureHtml, BuildVerifySuccessHtml } from './verificationPages.js';
34
+ import { ApiRoute } from '../apiRoot.js';
34
35
 
35
36
  /** Mount path of the public verify routes. Under `/realtime`, which is already reserved against server extensions. */
36
37
  export const REALTIME_VERIFY_MOUNT_PATH = '/realtime/verify';
@@ -79,7 +80,7 @@ export function CreateRealtimeVerifyRouter(
79
80
  // SAFE: renders the confirmation button. Never consumes the token (see the module header).
80
81
  router.get('/:token', limiter, (req: Request, res: Response) => {
81
82
  const token = typeof req.params.token === 'string' ? req.params.token : '';
82
- sendPage(res, 200, BuildVerifyConfirmHtml(token, REALTIME_VERIFY_MOUNT_PATH));
83
+ sendPage(res, 200, BuildVerifyConfirmHtml(token, ApiRoute(REALTIME_VERIFY_MOUNT_PATH)));
83
84
  });
84
85
 
85
86
  // The side-effecting redemption, gated by a human gesture.
@@ -0,0 +1,234 @@
1
+ /**
2
+ * @fileoverview Per-session timers that assemble a client-direct realtime recording from its shard ledger
3
+ * off the request path.
4
+ *
5
+ * The recording REST routes only record shards and the terminal signal; they never decode. When a route
6
+ * learns a session is ready (every expected shard present) it asks for an assembly now; when shards are
7
+ * missing it asks for one after the grace period, forced to `Partial`. This scheduler turns those requests
8
+ * into at most one pending timer and at most one running assembly per session in this process.
9
+ *
10
+ * Correctness across processes does not depend on it: every run starts with the ledger's atomic
11
+ * `ClaimAssembly`, so of two instances (or two timers) only the claim winner assembles. The per-session
12
+ * guard here only avoids wasted claims. A run that dies with the process leaves the session `Assembling`,
13
+ * and the session janitor's stale re-claim is the backstop for that and for any request dropped here.
14
+ *
15
+ * @module @memberjunction/server/realtimeSessions
16
+ */
17
+ import { DatabaseProviderBase, LogError, LogStatus, UserInfo } from '@memberjunction/core';
18
+ import { BaseSingleton, IShutdownable, ShutdownRegistry } from '@memberjunction/global';
19
+ import {
20
+ AssembleRealtimeRecordingFromLedger, AssembleRealtimeRecordingInput, AssembleRealtimeRecordingOutcome,
21
+ IRealtimeRecordingLedger, SqlRealtimeRecordingLedger,
22
+ } from '@memberjunction/ai-agents';
23
+
24
+ /** A cancellable one-shot timer. */
25
+ export interface RecordingAssemblyTimer {
26
+ Cancel(): void;
27
+ }
28
+
29
+ /** Time source of the scheduler; injectable so tests can drive it. */
30
+ export interface RecordingAssemblyClock {
31
+ /** Milliseconds since the epoch. */
32
+ Now(): number;
33
+ /** Runs `callback` once after `delayMs`. The timer must not keep the process alive. */
34
+ StartTimer(callback: () => void, delayMs: number): RecordingAssemblyTimer;
35
+ }
36
+
37
+ /** The narrow scheduling contract the recording routes depend on. */
38
+ export interface IRecordingAssemblyScheduler {
39
+ /**
40
+ * Requests an assembly of `sessionID` after `delayMs`. `forcePartial` assembles what exists even when
41
+ * shards are missing (the grace period ran out). See {@link RecordingAssemblyScheduler.ScheduleAssembly}.
42
+ */
43
+ ScheduleAssembly(sessionID: string, delayMs: number, forcePartial: boolean): void;
44
+ }
45
+
46
+ /** What {@link RecordingAssemblyScheduler.Start} needs. */
47
+ export interface RecordingAssemblySchedulerOptions {
48
+ /** The server's own provider; assembly is server-owned background work, not a request. */
49
+ Provider: DatabaseProviderBase;
50
+ /** The user assembly runs as (the system user). */
51
+ SystemUser: UserInfo;
52
+ /** Grace before a `Deferred` (incomplete) assembly is retried as forced `Partial`. */
53
+ GraceMs: () => number;
54
+ /** Defaults to {@link SqlRealtimeRecordingLedger}. */
55
+ CreateLedger?: (provider: DatabaseProviderBase, contextUser: UserInfo) => IRealtimeRecordingLedger;
56
+ /** Defaults to {@link AssembleRealtimeRecordingFromLedger}. */
57
+ Assemble?: (input: AssembleRealtimeRecordingInput) => Promise<AssembleRealtimeRecordingOutcome>;
58
+ /** Defaults to `Date.now` and unref'd `setTimeout`. */
59
+ Clock?: RecordingAssemblyClock;
60
+ }
61
+
62
+ interface PendingAssembly {
63
+ DueAt: number;
64
+ ForcePartial: boolean;
65
+ Timer: RecordingAssemblyTimer;
66
+ }
67
+
68
+ const NODE_CLOCK: RecordingAssemblyClock = {
69
+ Now: () => Date.now(),
70
+ StartTimer: (callback, delayMs) => {
71
+ const handle = setTimeout(callback, delayMs);
72
+ handle.unref?.();
73
+ return { Cancel: () => clearTimeout(handle) };
74
+ },
75
+ };
76
+
77
+ /**
78
+ * Process-wide scheduler of recording assemblies (see the file overview). Call {@link Start} once at
79
+ * server startup; requests made before it (or after {@link Shutdown}) are logged and dropped, leaving the
80
+ * session to the janitor.
81
+ */
82
+ export class RecordingAssemblyScheduler extends BaseSingleton<RecordingAssemblyScheduler> implements IShutdownable, IRecordingAssemblyScheduler {
83
+ private _options: Required<RecordingAssemblySchedulerOptions> | null = null;
84
+ private _registered = false;
85
+ /** Pending timers keyed by lowercase session id. */
86
+ private readonly pending = new Map<string, PendingAssembly>();
87
+ /** Lowercase ids of sessions with an assembly running in this process. */
88
+ private readonly running = new Set<string>();
89
+ /** Sessions asked for again while running, with the ForcePartial to re-run with. */
90
+ private readonly rerun = new Map<string, boolean>();
91
+
92
+ protected constructor() {
93
+ super();
94
+ }
95
+
96
+ /** Process-wide singleton accessor. */
97
+ public static get Instance(): RecordingAssemblyScheduler {
98
+ return super.getInstance<RecordingAssemblyScheduler>();
99
+ }
100
+
101
+ /** Identifier surfaced in graceful-shutdown logs. */
102
+ public readonly ShutdownName = 'RecordingAssemblyScheduler';
103
+
104
+ /** Configures the scheduler and enables it; calling again replaces the configuration. */
105
+ public Start(options: RecordingAssemblySchedulerOptions): void {
106
+ this._options = {
107
+ CreateLedger: (provider, contextUser) => new SqlRealtimeRecordingLedger(provider, contextUser),
108
+ Assemble: AssembleRealtimeRecordingFromLedger,
109
+ Clock: NODE_CLOCK,
110
+ ...options,
111
+ };
112
+ if (!this._registered) {
113
+ ShutdownRegistry.Instance.Register(this);
114
+ this._registered = true;
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Requests an assembly of `sessionID` after `delayMs`. One pending timer per session: a request
120
+ * replaces the pending one only when it would fire sooner (at the same time, the merged request keeps
121
+ * `forcePartial` if either had it). A timer that fires while the session's previous run is still going
122
+ * is remembered and run right after it, never alongside it.
123
+ *
124
+ * Trade-off: a sooner un-forced request replaces a pending forced one. If that run comes back
125
+ * `Deferred` (still incomplete), the forced `Partial` is re-scheduled a full grace from then, so a
126
+ * forced Partial can land up to ~2× the grace after the first terminal signal. Accepted: the sooner
127
+ * run completes the recording outright whenever the missing shards did arrive.
128
+ */
129
+ public ScheduleAssembly(sessionID: string, delayMs: number, forcePartial: boolean): void {
130
+ const options = this._options;
131
+ if (!options) {
132
+ LogError(`RecordingAssemblyScheduler: not running; dropped the assembly request for session ${sessionID} (the session janitor will assemble it)`);
133
+ return;
134
+ }
135
+ const key = sessionID.toLowerCase();
136
+ const dueAt = options.Clock.Now() + Math.max(0, delayMs);
137
+ const existing = this.pending.get(key);
138
+ if (existing && existing.DueAt < dueAt) {
139
+ return;
140
+ }
141
+ if (existing && existing.DueAt === dueAt) {
142
+ existing.ForcePartial = existing.ForcePartial || forcePartial;
143
+ return;
144
+ }
145
+ existing?.Timer.Cancel();
146
+ const timer = options.Clock.StartTimer(() => this.onTimer(key, sessionID), dueAt - options.Clock.Now());
147
+ this.pending.set(key, { DueAt: dueAt, ForcePartial: forcePartial, Timer: timer });
148
+ }
149
+
150
+ /**
151
+ * Cancels every pending timer and stops accepting requests until the next {@link Start}. A running
152
+ * assembly is not awaited: if the process exits under it, the session stays `Assembling` and the
153
+ * janitor's stale re-claim finishes it. Idempotent.
154
+ */
155
+ public Shutdown(): void {
156
+ for (const entry of this.pending.values()) {
157
+ entry.Timer.Cancel();
158
+ }
159
+ this.pending.clear();
160
+ this.rerun.clear();
161
+ this._options = null;
162
+ }
163
+
164
+ private onTimer(key: string, sessionID: string): void {
165
+ const entry = this.pending.get(key);
166
+ if (!entry) {
167
+ return;
168
+ }
169
+ this.pending.delete(key);
170
+ if (this.running.has(key)) {
171
+ this.rerun.set(key, (this.rerun.get(key) ?? false) || entry.ForcePartial);
172
+ return;
173
+ }
174
+ void this.runUntilSettled(key, sessionID, entry.ForcePartial);
175
+ }
176
+
177
+ /** Runs the session's assembly, then any re-run requested meanwhile. Never rejects. */
178
+ private async runUntilSettled(key: string, sessionID: string, forcePartial: boolean): Promise<void> {
179
+ this.running.add(key);
180
+ try {
181
+ let next: boolean | undefined = forcePartial;
182
+ while (next !== undefined) {
183
+ await this.runOnce(sessionID, next);
184
+ next = this.rerun.get(key);
185
+ this.rerun.delete(key);
186
+ }
187
+ } finally {
188
+ this.running.delete(key);
189
+ }
190
+ }
191
+
192
+ /** One claim + assembly. Logs every failure with the session id; never throws. */
193
+ private async runOnce(sessionID: string, forcePartial: boolean): Promise<void> {
194
+ const options = this._options;
195
+ if (!options) {
196
+ LogStatus(`RecordingAssemblyScheduler: shut down before session ${sessionID} could assemble; the session janitor will assemble it`);
197
+ return;
198
+ }
199
+ try {
200
+ const ledger = options.CreateLedger(options.Provider, options.SystemUser);
201
+ const version = await ledger.ClaimAssembly(sessionID, null);
202
+ if (version === null) {
203
+ LogStatus(`RecordingAssemblyScheduler: session ${sessionID} not claimable (assembled, assembling elsewhere, or failed); skipping`);
204
+ return;
205
+ }
206
+ const outcome = await options.Assemble({
207
+ SessionID: sessionID, Version: version, Ledger: ledger,
208
+ ContextUser: options.SystemUser, Provider: options.Provider, ForcePartial: forcePartial,
209
+ });
210
+ this.handleOutcome(sessionID, version, outcome, options);
211
+ } catch (error) {
212
+ LogError(`RecordingAssemblyScheduler: assembly of session ${sessionID} failed: ${error instanceof Error ? error.message : String(error)}`);
213
+ }
214
+ }
215
+
216
+ private handleOutcome(
217
+ sessionID: string,
218
+ version: number,
219
+ outcome: AssembleRealtimeRecordingOutcome,
220
+ options: Required<RecordingAssemblySchedulerOptions>,
221
+ ): void {
222
+ if (outcome === 'Deferred') {
223
+ // Incomplete and not forced: give missing shards the grace period, then assemble what exists.
224
+ LogStatus(`RecordingAssemblyScheduler: session ${sessionID} (version ${version}) is missing shards; assembling as Partial after the grace period`);
225
+ this.ScheduleAssembly(sessionID, options.GraceMs(), true);
226
+ return;
227
+ }
228
+ if (outcome === 'Retry') {
229
+ LogError(`RecordingAssemblyScheduler: assembly of session ${sessionID} (version ${version}) hit a transient error; the session janitor re-claims it later`);
230
+ return;
231
+ }
232
+ LogStatus(`RecordingAssemblyScheduler: session ${sessionID} (version ${version}) assembly finished: ${outcome}`);
233
+ }
234
+ }
@@ -54,6 +54,7 @@ function toSnapshot(loaded: LoadedSessionForAccess): SessionSnapshot {
54
54
  AgentSessionID: Session.ID,
55
55
  OwnerUserID: Session.UserID,
56
56
  ConversationExternalID: loaded.ConversationExternalID,
57
+ ConversationReadable: loaded.ConversationReadable,
57
58
  Status: Session.Status,
58
59
  ConfigRaw: Session.Config_,
59
60
  // `__mj_CreatedAt` is the row's creation instant — i.e. the session start. It is read-only and
@@ -14,3 +14,5 @@ export * from './sessionConfigStamps.js';
14
14
  export * from './SessionVerificationPortsBase.js';
15
15
  export * from './RealtimeSessionVerificationService.js';
16
16
  export * from './RealtimeVerifyRouter.js';
17
+ export * from './ownedRealtimeSession.js';
18
+ export * from './RecordingAssemblyScheduler.js';
@@ -0,0 +1,69 @@
1
+ /**
2
+ * @fileoverview The ownership gate for client-direct realtime session writes: the GraphQL mutations of
3
+ * `RealtimeClientSessionResolver` and the recording REST routes both load the session through
4
+ * {@link LoadOwnedRealtimeSession}, so "may this caller write to this session?" is decided in one place.
5
+ *
6
+ * @module @memberjunction/server/realtimeSessions
7
+ */
8
+ import { IMetadataProvider, LogError, UserInfo } from '@memberjunction/core';
9
+ import { UUIDsEqual } from '@memberjunction/global';
10
+ import type { MJAIAgentSessionEntity } from '@memberjunction/core-entities';
11
+ import { AuthorizeSessionAccess, LoadSessionConversationScope } from './sessionAccess.js';
12
+
13
+ const SESSION_ENTITY = 'MJ: AI Agent Sessions';
14
+
15
+ /** The session does not exist, or the caller cannot read it. */
16
+ export class RealtimeSessionNotFoundError extends Error {
17
+ constructor(public readonly AgentSessionID: string) {
18
+ super(`Realtime session ${AgentSessionID} not found`);
19
+ this.name = 'RealtimeSessionNotFoundError';
20
+ }
21
+ }
22
+
23
+ /** The session exists but the caller may not use it: another user owns it, or (for a scoped or anonymous caller) its conversation carries another scope identity. */
24
+ export class RealtimeSessionOwnershipError extends Error {
25
+ constructor(public readonly AgentSessionID: string) {
26
+ super('Not authorized: you do not own this realtime session');
27
+ this.name = 'RealtimeSessionOwnershipError';
28
+ }
29
+ }
30
+
31
+ /**
32
+ * Loads a session under the caller's identity and enforces ownership: `UserID === contextUser.ID`, then the
33
+ * scope rule of {@link AuthorizeSessionAccess} (every anonymous visitor shares one Anonymous user, so the
34
+ * session's conversation `ExternalID` must equal the caller's scope identity). It deliberately does NOT
35
+ * reject `Closed` sessions: the final channel-state flush and the recording terminal signal legitimately
36
+ * arrive after the session closed. Loading as the caller also applies the entity's row-level security.
37
+ *
38
+ * @throws RealtimeSessionNotFoundError when the row does not load
39
+ * @throws RealtimeSessionOwnershipError when another user owns the session (logged with both user ids) or
40
+ * the scope rule refuses the caller (logged with the refusal reason)
41
+ */
42
+ export async function LoadOwnedRealtimeSession(
43
+ agentSessionId: string,
44
+ contextUser: UserInfo,
45
+ provider: IMetadataProvider,
46
+ ): Promise<MJAIAgentSessionEntity> {
47
+ const session = await provider.GetEntityObject<MJAIAgentSessionEntity>(SESSION_ENTITY, contextUser);
48
+ if (!(await session.Load(agentSessionId))) {
49
+ throw new RealtimeSessionNotFoundError(agentSessionId);
50
+ }
51
+ if (!UUIDsEqual(session.UserID, contextUser.ID)) {
52
+ LogError(
53
+ `LoadOwnedRealtimeSession: ownership check failed — user ${contextUser.ID} attempted to operate on session ${agentSessionId} owned by ${session.UserID}`,
54
+ );
55
+ throw new RealtimeSessionOwnershipError(agentSessionId);
56
+ }
57
+ const conversation = await LoadSessionConversationScope(session, contextUser, provider);
58
+ const access = AuthorizeSessionAccess(
59
+ { SessionUserID: session.UserID, ConversationExternalID: conversation.ExternalID, ConversationReadable: conversation.Readable },
60
+ contextUser,
61
+ );
62
+ if (!access.Allowed) {
63
+ LogError(
64
+ `LoadOwnedRealtimeSession: session access refused (${access.Reason}) — user ${contextUser.ID} attempted to operate on session ${agentSessionId}`,
65
+ );
66
+ throw new RealtimeSessionOwnershipError(agentSessionId);
67
+ }
68
+ return session;
69
+ }