@memberjunction/server 6.2.0-edge.4 → 6.2.0-edge.5
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.
- package/README.md +20 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/agentSessions/SessionJanitor.d.ts +91 -30
- package/dist/agentSessions/SessionJanitor.d.ts.map +1 -1
- package/dist/agentSessions/SessionJanitor.js +311 -81
- package/dist/agentSessions/SessionJanitor.js.map +1 -1
- package/dist/agentSessions/SessionManager.d.ts +5 -1
- package/dist/agentSessions/SessionManager.d.ts.map +1 -1
- package/dist/agentSessions/SessionManager.js +13 -1
- package/dist/agentSessions/SessionManager.js.map +1 -1
- package/dist/apiRoot.d.ts +32 -0
- package/dist/apiRoot.d.ts.map +1 -0
- package/dist/apiRoot.js +67 -0
- package/dist/apiRoot.js.map +1 -0
- package/dist/auth/AuthProviderCatalogRouter.d.ts.map +1 -1
- package/dist/auth/AuthProviderCatalogRouter.js +25 -0
- package/dist/auth/AuthProviderCatalogRouter.js.map +1 -1
- package/dist/auth/LoginScreenEngine.d.ts +22 -0
- package/dist/auth/LoginScreenEngine.d.ts.map +1 -0
- package/dist/auth/LoginScreenEngine.js +57 -0
- package/dist/auth/LoginScreenEngine.js.map +1 -0
- package/dist/auth/index.d.ts +1 -0
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +1 -0
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/magicLink/MagicLinkRouter.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkRouter.js +3 -2
- package/dist/auth/magicLink/MagicLinkRouter.js.map +1 -1
- package/dist/config.d.ts +136 -22
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +43 -4
- package/dist/config.js.map +1 -1
- package/dist/coreRoutes.d.ts +29 -0
- package/dist/coreRoutes.d.ts.map +1 -0
- package/dist/coreRoutes.js +142 -0
- package/dist/coreRoutes.js.map +1 -0
- package/dist/generated/graphql-schemas/__mj.d.ts +369 -3
- package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
- package/dist/generated/graphql-schemas/__mj.js +1750 -7
- package/dist/generated/graphql-schemas/__mj.js.map +1 -1
- package/dist/generic/CacheInvalidationResolver.d.ts +43 -8
- package/dist/generic/CacheInvalidationResolver.d.ts.map +1 -1
- package/dist/generic/CacheInvalidationResolver.js +59 -19
- package/dist/generic/CacheInvalidationResolver.js.map +1 -1
- package/dist/generic/PushStatusResolver.js +1 -1
- package/dist/generic/PushStatusResolver.js.map +1 -1
- package/dist/generic/ResolverBase.d.ts +103 -44
- package/dist/generic/ResolverBase.d.ts.map +1 -1
- package/dist/generic/ResolverBase.js +264 -305
- package/dist/generic/ResolverBase.js.map +1 -1
- package/dist/generic/RunViewResolver.d.ts.map +1 -1
- package/dist/generic/RunViewResolver.js +12 -0
- package/dist/generic/RunViewResolver.js.map +1 -1
- package/dist/globalCors.d.ts +33 -0
- package/dist/globalCors.d.ts.map +1 -0
- package/dist/globalCors.js +58 -0
- package/dist/globalCors.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +112 -160
- package/dist/index.js.map +1 -1
- package/dist/multiTenancy/index.d.ts.map +1 -1
- package/dist/multiTenancy/index.js +22 -2
- package/dist/multiTenancy/index.js.map +1 -1
- package/dist/realtimeSessions/RealtimeSessionVerificationService.d.ts.map +1 -1
- package/dist/realtimeSessions/RealtimeSessionVerificationService.js +2 -1
- package/dist/realtimeSessions/RealtimeSessionVerificationService.js.map +1 -1
- package/dist/realtimeSessions/RealtimeVerifyRouter.d.ts.map +1 -1
- package/dist/realtimeSessions/RealtimeVerifyRouter.js +2 -1
- package/dist/realtimeSessions/RealtimeVerifyRouter.js.map +1 -1
- package/dist/realtimeSessions/RecordingAssemblyScheduler.d.ts +100 -0
- package/dist/realtimeSessions/RecordingAssemblyScheduler.d.ts.map +1 -0
- package/dist/realtimeSessions/RecordingAssemblyScheduler.js +173 -0
- package/dist/realtimeSessions/RecordingAssemblyScheduler.js.map +1 -0
- package/dist/realtimeSessions/index.d.ts +2 -0
- package/dist/realtimeSessions/index.d.ts.map +1 -1
- package/dist/realtimeSessions/index.js +2 -0
- package/dist/realtimeSessions/index.js.map +1 -1
- package/dist/realtimeSessions/ownedRealtimeSession.d.ts +30 -0
- package/dist/realtimeSessions/ownedRealtimeSession.d.ts.map +1 -0
- package/dist/realtimeSessions/ownedRealtimeSession.js +47 -0
- package/dist/realtimeSessions/ownedRealtimeSession.js.map +1 -0
- package/dist/realtimeSessions/sessionAccess.d.ts +6 -0
- package/dist/realtimeSessions/sessionAccess.d.ts.map +1 -1
- package/dist/realtimeSessions/sessionAccess.js +7 -3
- package/dist/realtimeSessions/sessionAccess.js.map +1 -1
- package/dist/resolvers/ArtifactFileResolver.d.ts +5 -1
- package/dist/resolvers/ArtifactFileResolver.d.ts.map +1 -1
- package/dist/resolvers/ArtifactFileResolver.js +9 -7
- package/dist/resolvers/ArtifactFileResolver.js.map +1 -1
- package/dist/resolvers/ConversationRunEventsResolver.d.ts +8 -4
- package/dist/resolvers/ConversationRunEventsResolver.d.ts.map +1 -1
- package/dist/resolvers/ConversationRunEventsResolver.js +6 -6
- package/dist/resolvers/ConversationRunEventsResolver.js.map +1 -1
- package/dist/resolvers/DatasetResolver.d.ts +24 -3
- package/dist/resolvers/DatasetResolver.d.ts.map +1 -1
- package/dist/resolvers/DatasetResolver.js +57 -8
- package/dist/resolvers/DatasetResolver.js.map +1 -1
- package/dist/resolvers/EntityRecordNameResolver.d.ts +2 -1
- package/dist/resolvers/EntityRecordNameResolver.d.ts.map +1 -1
- package/dist/resolvers/EntityRecordNameResolver.js +3 -2
- package/dist/resolvers/EntityRecordNameResolver.js.map +1 -1
- package/dist/resolvers/FetchEntityVectorsResolver.d.ts +18 -3
- package/dist/resolvers/FetchEntityVectorsResolver.d.ts.map +1 -1
- package/dist/resolvers/FetchEntityVectorsResolver.js +100 -35
- package/dist/resolvers/FetchEntityVectorsResolver.js.map +1 -1
- package/dist/resolvers/FileResolver.d.ts +82 -11
- package/dist/resolvers/FileResolver.d.ts.map +1 -1
- package/dist/resolvers/FileResolver.js +279 -101
- package/dist/resolvers/FileResolver.js.map +1 -1
- package/dist/resolvers/GetDataContextDataResolver.d.ts +33 -7
- package/dist/resolvers/GetDataContextDataResolver.d.ts.map +1 -1
- package/dist/resolvers/GetDataContextDataResolver.js +117 -38
- package/dist/resolvers/GetDataContextDataResolver.js.map +1 -1
- package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
- package/dist/resolvers/GetDataResolver.js +6 -3
- package/dist/resolvers/GetDataResolver.js.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.js +4 -2
- package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
- package/dist/resolvers/QueryResolver.d.ts +2 -0
- package/dist/resolvers/QueryResolver.d.ts.map +1 -1
- package/dist/resolvers/QueryResolver.js +13 -0
- package/dist/resolvers/QueryResolver.js.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts +2 -8
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.js +10 -26
- package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.js +35 -6
- package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
- package/dist/resolvers/SearchKnowledgeStreamResolver.d.ts +12 -1
- package/dist/resolvers/SearchKnowledgeStreamResolver.d.ts.map +1 -1
- package/dist/resolvers/SearchKnowledgeStreamResolver.js +15 -2
- package/dist/resolvers/SearchKnowledgeStreamResolver.js.map +1 -1
- package/dist/resolvers/SqlLoggingConfigResolver.d.ts.map +1 -1
- package/dist/resolvers/SqlLoggingConfigResolver.js +2 -3
- package/dist/resolvers/SqlLoggingConfigResolver.js.map +1 -1
- package/dist/resolvers/TaskGraphFrameResolver.d.ts +2 -1
- package/dist/resolvers/TaskGraphFrameResolver.d.ts.map +1 -1
- package/dist/resolvers/TaskGraphFrameResolver.js +28 -1
- package/dist/resolvers/TaskGraphFrameResolver.js.map +1 -1
- package/dist/resolvers/TestQuerySQLResolver.d.ts +24 -0
- package/dist/resolvers/TestQuerySQLResolver.d.ts.map +1 -1
- package/dist/resolvers/TestQuerySQLResolver.js +65 -13
- package/dist/resolvers/TestQuerySQLResolver.js.map +1 -1
- package/dist/resolvers/TransactionGroupResolver.d.ts +19 -2
- package/dist/resolvers/TransactionGroupResolver.d.ts.map +1 -1
- package/dist/resolvers/TransactionGroupResolver.js +102 -24
- package/dist/resolvers/TransactionGroupResolver.js.map +1 -1
- package/dist/resolvers/agent-run-data-guard.d.ts +31 -0
- package/dist/resolvers/agent-run-data-guard.d.ts.map +1 -0
- package/dist/resolvers/agent-run-data-guard.js +72 -0
- package/dist/resolvers/agent-run-data-guard.js.map +1 -0
- package/dist/rest/RealtimeRecordingHandler.d.ts +49 -0
- package/dist/rest/RealtimeRecordingHandler.d.ts.map +1 -0
- package/dist/rest/RealtimeRecordingHandler.js +383 -0
- package/dist/rest/RealtimeRecordingHandler.js.map +1 -0
- package/dist/rest/ViewOperationsHandler.d.ts +3 -1
- package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
- package/dist/rest/ViewOperationsHandler.js +21 -12
- package/dist/rest/ViewOperationsHandler.js.map +1 -1
- package/dist/rest/setupRESTEndpoints.d.ts +6 -0
- package/dist/rest/setupRESTEndpoints.d.ts.map +1 -1
- package/dist/rest/setupRESTEndpoints.js +6 -0
- package/dist/rest/setupRESTEndpoints.js.map +1 -1
- package/dist/serverExtensionReservedRoots.d.ts +12 -10
- package/dist/serverExtensionReservedRoots.d.ts.map +1 -1
- package/dist/serverExtensionReservedRoots.js +14 -17
- package/dist/serverExtensionReservedRoots.js.map +1 -1
- package/dist/services/MJStorageBlobStore.d.ts +8 -1
- package/dist/services/MJStorageBlobStore.d.ts.map +1 -1
- package/dist/services/MJStorageBlobStore.js +25 -19
- package/dist/services/MJStorageBlobStore.js.map +1 -1
- package/dist/services/StartTaskGraphDispatcher.js +2 -2
- package/dist/services/StartTaskGraphDispatcher.js.map +1 -1
- package/dist/services/TaskGraphActionRunner.d.ts +5 -3
- package/dist/services/TaskGraphActionRunner.d.ts.map +1 -1
- package/dist/services/TaskGraphActionRunner.js +27 -5
- package/dist/services/TaskGraphActionRunner.js.map +1 -1
- package/dist/services/TaskGraphAgentRunner.d.ts +14 -2
- package/dist/services/TaskGraphAgentRunner.d.ts.map +1 -1
- package/dist/services/TaskGraphAgentRunner.js +157 -9
- package/dist/services/TaskGraphAgentRunner.js.map +1 -1
- package/dist/services/TaskGraphContinuationDeliverer.d.ts +54 -2
- package/dist/services/TaskGraphContinuationDeliverer.d.ts.map +1 -1
- package/dist/services/TaskGraphContinuationDeliverer.js +598 -15
- package/dist/services/TaskGraphContinuationDeliverer.js.map +1 -1
- package/dist/sharedCache.d.ts.map +1 -1
- package/dist/sharedCache.js +3 -0
- package/dist/sharedCache.js.map +1 -1
- package/package.json +99 -98
- package/src/__tests__/DatasetResolver.itemFilters.test.ts +201 -0
- package/src/__tests__/EntityRecordNameResolver.rowSecurity.test.ts +152 -0
- package/src/__tests__/FetchEntityVectorsResolver.test.ts +163 -15
- package/src/__tests__/FileResolver.storageAccess.test.ts +562 -0
- package/src/__tests__/GetDataContextDataResolver.sqlItems.test.ts +416 -0
- package/src/__tests__/ListOperationsResolver.adhocScreen.test.ts +137 -0
- package/src/__tests__/LoginScreenEngine.test.ts +86 -0
- package/src/__tests__/MJStorageBlobStore.storageGate.test.ts +63 -0
- package/src/__tests__/RecordingAssemblyScheduler.test.ts +178 -0
- package/src/__tests__/ResolverBase.adhocReadScope.test.ts +133 -2
- package/src/__tests__/ResolverBase.balancedClause.test.ts +155 -0
- package/src/__tests__/ResolverBase.clauseUnscopedRead.test.ts +127 -0
- package/src/__tests__/ResolverBase.clientOldValues.test.ts +209 -6
- package/src/__tests__/ResolverBase.filterEscaping.test.ts +5 -2
- package/src/__tests__/RunAIAgentResolver.branch.test.ts +1 -0
- package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +5 -3
- package/src/__tests__/RunAIAgentResolver.runDataGuard.test.ts +258 -0
- package/src/__tests__/RunViewResolver.cacheCheckScreen.test.ts +165 -0
- package/src/__tests__/SearchKnowledgeStreamResolver.test.ts +161 -0
- package/src/__tests__/SessionJanitor.test.ts +365 -10
- package/src/__tests__/SessionManager.test.ts +27 -0
- package/src/__tests__/TaskGraphActionRunner.durablePayload.test.ts +25 -0
- package/src/__tests__/TaskGraphAgentRunner.test.ts +266 -0
- package/src/__tests__/TaskGraphContinuationDeliverer.test.ts +356 -22
- package/src/__tests__/TaskGraphFrameResolver.test.ts +22 -0
- package/src/__tests__/TestQuerySQLResolver.test.ts +274 -0
- package/src/__tests__/TransactionGroupResolver.refusals.test.ts +98 -1
- package/src/__tests__/UpdateMJDataContextItem.oldValues.test.ts +220 -0
- package/src/__tests__/ViewOperationsHandler.clauseScreen.test.ts +157 -0
- package/src/__tests__/agent-run-data-guard.test.ts +130 -0
- package/src/__tests__/apiRootBoot.test.ts +202 -0
- package/src/__tests__/cacheInvalidationRecordData.test.ts +64 -0
- package/src/__tests__/conversationRunEvents.test.ts +56 -14
- package/src/__tests__/globalCors.test.ts +217 -0
- package/src/__tests__/multiTenancy.postgresRewrite.test.ts +181 -0
- package/src/__tests__/multiTenancy.security.test.ts +51 -0
- package/src/__tests__/multiTenancy.test.ts +1 -1
- package/src/__tests__/ownedRealtimeSession.test.ts +39 -0
- package/src/__tests__/pushStatusResolver.filter.test.ts +7 -0
- package/src/__tests__/realtimeRecordingHandler.test.ts +652 -0
- package/src/__tests__/serverExtensionHostOverlay.test.ts +66 -0
- package/src/__tests__/serverExtensionReservedRoots.test.ts +11 -98
- package/src/__tests__/sharedCache.test.ts +5 -3
- package/src/agentSessions/SessionJanitor.ts +369 -93
- package/src/agentSessions/SessionManager.ts +13 -1
- package/src/apiRoot.ts +78 -0
- package/src/auth/AuthProviderCatalogRouter.ts +26 -0
- package/src/auth/LoginScreenEngine.ts +50 -0
- package/src/auth/index.ts +1 -0
- package/src/auth/magicLink/MagicLinkRouter.ts +3 -2
- package/src/config.ts +46 -5
- package/src/coreRoutes.ts +166 -0
- package/src/generated/graphql-schemas/__mj.ts +1273 -10
- package/src/generic/CacheInvalidationResolver.ts +73 -18
- package/src/generic/PushStatusResolver.ts +1 -1
- package/src/generic/ResolverBase.ts +304 -325
- package/src/generic/RunViewResolver.ts +17 -0
- package/src/globalCors.ts +71 -0
- package/src/index.ts +116 -174
- package/src/multiTenancy/index.ts +24 -2
- package/src/realtimeSessions/RealtimeSessionVerificationService.ts +2 -1
- package/src/realtimeSessions/RealtimeVerifyRouter.ts +2 -1
- package/src/realtimeSessions/RecordingAssemblyScheduler.ts +234 -0
- package/src/realtimeSessions/index.ts +2 -0
- package/src/realtimeSessions/ownedRealtimeSession.ts +55 -0
- package/src/realtimeSessions/sessionAccess.ts +7 -3
- package/src/resolvers/ArtifactFileResolver.ts +9 -8
- package/src/resolvers/ConversationRunEventsResolver.ts +15 -11
- package/src/resolvers/DatasetResolver.ts +70 -10
- package/src/resolvers/EntityRecordNameResolver.ts +3 -2
- package/src/resolvers/FetchEntityVectorsResolver.ts +121 -39
- package/src/resolvers/FileResolver.ts +321 -106
- package/src/resolvers/GetDataContextDataResolver.ts +139 -41
- package/src/resolvers/GetDataResolver.ts +6 -3
- package/src/resolvers/IntegrationDiscoveryResolver.ts +4 -2
- package/src/resolvers/QueryResolver.ts +11 -0
- package/src/resolvers/RealtimeClientSessionResolver.ts +10 -33
- package/src/resolvers/RunAIAgentResolver.ts +39 -4
- package/src/resolvers/SearchKnowledgeStreamResolver.ts +19 -3
- package/src/resolvers/SqlLoggingConfigResolver.ts +2 -4
- package/src/resolvers/TaskGraphFrameResolver.ts +33 -1
- package/src/resolvers/TestQuerySQLResolver.ts +68 -13
- package/src/resolvers/TransactionGroupResolver.ts +131 -27
- package/src/resolvers/__tests__/GetDataResolver.validation.test.ts +95 -0
- package/src/resolvers/agent-run-data-guard.ts +89 -0
- package/src/rest/RealtimeRecordingHandler.ts +464 -0
- package/src/rest/ViewOperationsHandler.ts +29 -13
- package/src/rest/setupRESTEndpoints.ts +6 -0
- package/src/serverExtensionReservedRoots.ts +14 -17
- package/src/services/MJStorageBlobStore.ts +31 -30
- package/src/services/StartTaskGraphDispatcher.ts +2 -2
- package/src/services/TaskGraphActionRunner.ts +25 -5
- package/src/services/TaskGraphAgentRunner.ts +188 -11
- package/src/services/TaskGraphContinuationDeliverer.ts +704 -14
- package/src/sharedCache.ts +3 -0
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview REST routes the browser uses to upload a client-direct realtime call's recording as
|
|
3
|
+
* `MJOPUS1` shards, and to send the terminal signal that says how many shards and samples the call
|
|
4
|
+
* captured:
|
|
5
|
+
*
|
|
6
|
+
* - `POST /realtime/recording/:agentSessionId/shard/:index` — one shard as raw `application/octet-stream`.
|
|
7
|
+
* - `POST /realtime/recording/:agentSessionId/end?lastShardIndex=&capturedSamples=[&final=false]` — the
|
|
8
|
+
* terminal signal, with the final partial shard (the tail) as an optional body. The browser sends it with
|
|
9
|
+
* `keepalive` on End, `pagehide` and `visibilitychange→hidden`, so it may arrive more than once, and late.
|
|
10
|
+
* A hidden tab sends `final=false`: the call may well go on, so the counts are stamped but the recording
|
|
11
|
+
* is assembled only after the grace period.
|
|
12
|
+
*
|
|
13
|
+
* Assembly is never scheduled sooner than the grace period while the session is still open, except for a
|
|
14
|
+
* final terminal: a hidden tab's terminal and the shards re-sent after it would otherwise rewrite
|
|
15
|
+
* `recording.wav` on every tab switch. Closing the session (`SessionManager.CloseSession`) schedules it
|
|
16
|
+
* right away.
|
|
17
|
+
*
|
|
18
|
+
* Both run after the unified auth middleware and are owner- and scope-gated (see `loadAuthorizedSession`). A request does only cheap work: parse
|
|
19
|
+
* the shard header and packet bounds, hash, one guarded ledger proc, maybe a count. It never decodes:
|
|
20
|
+
* assembly runs off the request path through the {@link IRecordingAssemblyScheduler}.
|
|
21
|
+
*
|
|
22
|
+
* @module @memberjunction/server
|
|
23
|
+
*/
|
|
24
|
+
import { createHash } from 'node:crypto';
|
|
25
|
+
import express from 'express';
|
|
26
|
+
import { LogError, LogStatus } from '@memberjunction/core';
|
|
27
|
+
import { IsValidUUID } from '@memberjunction/global';
|
|
28
|
+
import { ParseRecordingShard, RecordingShardFormatError, RECORDING_SAMPLE_RATE, RECORDING_SHARD_MAX_BYTES, RECORDING_TERMINAL_MAX_BYTES, } from '@memberjunction/ai-core-plus';
|
|
29
|
+
import { MAX_ASSEMBLY_SHARDS } from '@memberjunction/ai-agents';
|
|
30
|
+
import { RealtimeSessionNotFoundError, RealtimeSessionOwnershipError, } from '../realtimeSessions/ownedRealtimeSession.js';
|
|
31
|
+
import { AuthorizeSessionAccess } from '../realtimeSessions/sessionAccess.js';
|
|
32
|
+
/** Where {@link CreateRealtimeRecordingRouter} is mounted (under the reserved `/realtime` root). */
|
|
33
|
+
export const REALTIME_RECORDING_MOUNT_PATH = '/realtime/recording';
|
|
34
|
+
/**
|
|
35
|
+
* How long after a session closed it still accepts recording requests (a late gap shard re-assembles).
|
|
36
|
+
* Past it the recording is settled: shards and terminals are refused with 410 and nothing is stored.
|
|
37
|
+
*/
|
|
38
|
+
const LATE_SHARD_WINDOW_MS = 24 * 60 * 60 * 1000;
|
|
39
|
+
/**
|
|
40
|
+
* Allowance on top of a session's lifetime when bounding how much audio a request may claim: the
|
|
41
|
+
* recorder starts after the session row exists, so a real claim never exceeds the lifetime, but a
|
|
42
|
+
* request in flight while the session closes must not be refused.
|
|
43
|
+
*/
|
|
44
|
+
const SESSION_LIFETIME_SLACK_MS = 2 * 60 * 1000;
|
|
45
|
+
const OCTET_STREAM = 'application/octet-stream';
|
|
46
|
+
/**
|
|
47
|
+
* How soon a final terminal that found shards missing looks again. The browser sends the terminal first
|
|
48
|
+
* and re-sends its unacknowledged shards right after it (all `keepalive`), so they normally land within a
|
|
49
|
+
* second or two; when the tab closed right after End, no close follows to trigger assembly. A re-check
|
|
50
|
+
* that is still incomplete comes back `Deferred`, and the scheduler then arms the forced-`Partial` grace.
|
|
51
|
+
*/
|
|
52
|
+
export const FINAL_TERMINAL_RECHECK_MS = 5000;
|
|
53
|
+
const NON_NEGATIVE_INT = /^\d+$/;
|
|
54
|
+
const INT = /^-?\d+$/;
|
|
55
|
+
/** A request failure with the HTTP status to answer. */
|
|
56
|
+
class RecordingRequestError extends Error {
|
|
57
|
+
constructor(Status, message) {
|
|
58
|
+
super(message);
|
|
59
|
+
this.Status = Status;
|
|
60
|
+
this.name = 'RecordingRequestError';
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Builds the router for the shard and terminal routes (see the file overview). Status codes: 200 on
|
|
65
|
+
* success (`{ stored, duplicate }` / `{ accepted, ignored }`), 400 bad params or shard format, 401 no
|
|
66
|
+
* caller, 403 not the owner, 404 no such session, 409 same shard index with different bytes, 413 body
|
|
67
|
+
* over the cap, 500 unexpected (logged).
|
|
68
|
+
*/
|
|
69
|
+
export function CreateRealtimeRecordingRouter(deps) {
|
|
70
|
+
const router = express.Router();
|
|
71
|
+
router.post('/:agentSessionId/shard/:index', validateBeforeBody(deps, RECORDING_SHARD_MAX_BYTES), express.raw({ type: OCTET_STREAM, limit: RECORDING_SHARD_MAX_BYTES }), (req, res) => respond(req, res, 'shard', () => handleShard(deps, req, res)));
|
|
72
|
+
router.post('/:agentSessionId/end', validateBeforeBody(deps, RECORDING_TERMINAL_MAX_BYTES), express.raw({ type: OCTET_STREAM, limit: RECORDING_TERMINAL_MAX_BYTES }), (req, res) => respond(req, res, 'terminal', () => handleTerminal(deps, req, res)));
|
|
73
|
+
router.use(handleBodyError);
|
|
74
|
+
return router;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Rejects what can be rejected before reading the body: a malformed session id, no caller, or a declared
|
|
78
|
+
* `Content-Length` over the cap (`express.raw` enforces the cap on the bytes actually streamed too).
|
|
79
|
+
*/
|
|
80
|
+
function validateBeforeBody(deps, maxBytes) {
|
|
81
|
+
return (req, res, next) => {
|
|
82
|
+
const sessionID = String(req.params['agentSessionId']);
|
|
83
|
+
if (!IsValidUUID(sessionID)) {
|
|
84
|
+
res.status(400).json({ error: 'agentSessionId must be a UUID' });
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const caller = deps.ResolveCaller(req);
|
|
88
|
+
if (!caller) {
|
|
89
|
+
res.status(401).json({ error: 'Not authenticated' });
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const declared = Number(req.headers['content-length']);
|
|
93
|
+
if (Number.isFinite(declared) && declared > maxBytes) {
|
|
94
|
+
LogStatus(`RealtimeRecordingHandler: refused a ${declared}-byte body for session ${sessionID} (cap ${maxBytes})`);
|
|
95
|
+
res.status(413).json({ error: `Body exceeds ${maxBytes} bytes` });
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const context = { SessionID: sessionID, Caller: caller };
|
|
99
|
+
res.locals['recording'] = context;
|
|
100
|
+
next();
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/** Runs a handler, mapping its failures to status codes; unexpected ones are logged and answered 500. */
|
|
104
|
+
async function respond(req, res, kind, handler) {
|
|
105
|
+
try {
|
|
106
|
+
await handler();
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
const sessionID = String(req.params['agentSessionId']);
|
|
110
|
+
if (error instanceof RecordingRequestError) {
|
|
111
|
+
res.status(error.Status).json({ error: error.message });
|
|
112
|
+
}
|
|
113
|
+
else if (error instanceof RealtimeSessionNotFoundError) {
|
|
114
|
+
res.status(404).json({ error: 'Realtime session not found' });
|
|
115
|
+
}
|
|
116
|
+
else if (error instanceof RealtimeSessionOwnershipError) {
|
|
117
|
+
res.status(403).json({ error: 'Not authorized for this realtime session' });
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
LogError(`RealtimeRecordingHandler: ${kind} request for session ${sessionID} failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
121
|
+
res.status(500).json({ error: 'Recording request failed' });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
async function handleShard(deps, req, res) {
|
|
126
|
+
const { SessionID, Caller } = res.locals['recording'];
|
|
127
|
+
const index = parseInteger(req.params['index'], 'shard index', NON_NEGATIVE_INT);
|
|
128
|
+
if (index >= MAX_ASSEMBLY_SHARDS) {
|
|
129
|
+
throw new RecordingRequestError(400, `shard index ${index} is past the ${MAX_ASSEMBLY_SHARDS} shards one recording can assemble`);
|
|
130
|
+
}
|
|
131
|
+
const body = Buffer.isBuffer(req.body) ? req.body : null;
|
|
132
|
+
if (!body || body.length === 0) {
|
|
133
|
+
throw new RecordingRequestError(400, `The shard must be a non-empty ${OCTET_STREAM} body`);
|
|
134
|
+
}
|
|
135
|
+
const header = parseShard(body, SessionID);
|
|
136
|
+
if (header.ShardIndex !== index) {
|
|
137
|
+
throw new RecordingRequestError(400, `Shard header index ${header.ShardIndex} does not match the path index ${index}`);
|
|
138
|
+
}
|
|
139
|
+
const session = await loadAuthorizedSession(deps, SessionID, Caller);
|
|
140
|
+
assertWithinSessionLifetime(session, header.StartSample + header.SampleCount, `shard ${index}`);
|
|
141
|
+
const ledger = deps.CreateLedger(Caller.Provider, Caller.ContextUser);
|
|
142
|
+
const result = await recordShard(ledger, SessionID, header, body);
|
|
143
|
+
if (result.Outcome === 'Inserted') {
|
|
144
|
+
await scheduleAfterLateShard(deps, Caller.Provider, SessionID, index, result);
|
|
145
|
+
}
|
|
146
|
+
res.status(200).json({ stored: true, duplicate: result.Outcome === 'Duplicate' });
|
|
147
|
+
}
|
|
148
|
+
async function handleTerminal(deps, req, res) {
|
|
149
|
+
const { SessionID, Caller } = res.locals['recording'];
|
|
150
|
+
const lastShardIndex = parseInteger(req.query['lastShardIndex'], 'lastShardIndex', INT);
|
|
151
|
+
const capturedSamples = parseInteger(req.query['capturedSamples'], 'capturedSamples', NON_NEGATIVE_INT);
|
|
152
|
+
if (lastShardIndex < -1) {
|
|
153
|
+
throw new RecordingRequestError(400, `lastShardIndex must be -1 or more, got ${lastShardIndex}`);
|
|
154
|
+
}
|
|
155
|
+
if (lastShardIndex >= MAX_ASSEMBLY_SHARDS) {
|
|
156
|
+
throw new RecordingRequestError(400, `lastShardIndex ${lastShardIndex} lists more than the ${MAX_ASSEMBLY_SHARDS} shards one recording can assemble`);
|
|
157
|
+
}
|
|
158
|
+
if (lastShardIndex === -1 && capturedSamples !== 0) {
|
|
159
|
+
throw new RecordingRequestError(400, `lastShardIndex -1 (no shards) contradicts capturedSamples ${capturedSamples}`);
|
|
160
|
+
}
|
|
161
|
+
const final = parseFinalFlag(req.query['final']);
|
|
162
|
+
const tail = readOptionalTail(req, SessionID, lastShardIndex);
|
|
163
|
+
const session = await loadAuthorizedSession(deps, SessionID, Caller);
|
|
164
|
+
assertWithinSessionLifetime(session, capturedSamples, 'captured samples');
|
|
165
|
+
if (tail) {
|
|
166
|
+
assertWithinSessionLifetime(session, tail.Header.StartSample + tail.Header.SampleCount, `tail shard ${tail.Header.ShardIndex}`);
|
|
167
|
+
}
|
|
168
|
+
const ledger = deps.CreateLedger(Caller.Provider, Caller.ContextUser);
|
|
169
|
+
if (tail) {
|
|
170
|
+
const tailResult = await recordShard(ledger, SessionID, tail.Header, tail.Bytes);
|
|
171
|
+
if (tailResult.Outcome === 'Inserted') {
|
|
172
|
+
// A re-sent tail can fill a gap of a recording already assembled, exactly like a late shard.
|
|
173
|
+
await scheduleAfterLateShard(deps, Caller.Provider, SessionID, tail.Header.ShardIndex, tailResult);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (lastShardIndex === -1) {
|
|
177
|
+
// The call captured nothing: there is no recording to stamp or assemble.
|
|
178
|
+
res.status(200).json({ accepted: true, ignored: false });
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
const expected = lastShardIndex + 1;
|
|
182
|
+
const stamp = await ledger.StampTerminal(SessionID, expected, capturedSamples);
|
|
183
|
+
if (stamp.Outcome === 'Ignored') {
|
|
184
|
+
logIgnoredTerminal(session, expected, capturedSamples, stamp.RecordingStatus);
|
|
185
|
+
res.status(200).json({ accepted: true, ignored: true });
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
LogStatus(`RealtimeRecordingHandler: terminal for session ${SessionID}: ${expected} shards, ${capturedSamples} samples; recording ${stamp.RecordingStatus ?? 'not recorded'}`);
|
|
189
|
+
if (stamp.RecordingStatus === 'Pending') {
|
|
190
|
+
if (final) {
|
|
191
|
+
await scheduleWhenReady(deps, Caller.Provider, SessionID, expected);
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
deps.Scheduler.ScheduleAssembly(SessionID, deps.GraceMs(), true);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
res.status(200).json({ accepted: true, ignored: false });
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Loads the session through the shared ownership gate, then applies the per-session scope rule of
|
|
201
|
+
* {@link AuthorizeSessionAccess}. The gate alone checks `UserID`, which every anonymous widget guest shares
|
|
202
|
+
* (they all authenticate as the one Anonymous user); without the scope rule one guest could write shards to
|
|
203
|
+
* another guest's recording, and a different-bytes shard would mark it Failed. The owner half of the
|
|
204
|
+
* decision repeats the gate's check on purpose: the decision is one rule, applied whole. Named users carry
|
|
205
|
+
* no scope and are unaffected.
|
|
206
|
+
*/
|
|
207
|
+
async function loadAuthorizedSession(deps, sessionID, caller) {
|
|
208
|
+
const session = await deps.LoadOwnedSession(sessionID, caller.ContextUser, caller.Provider);
|
|
209
|
+
const externalID = await deps.LoadConversationExternalID(session, caller.ContextUser, caller.Provider);
|
|
210
|
+
const decision = AuthorizeSessionAccess({ SessionUserID: session.UserID, ConversationExternalID: externalID }, caller.ContextUser);
|
|
211
|
+
if (decision.Allowed === false) {
|
|
212
|
+
LogError(`RealtimeRecordingHandler: refused user ${caller.ContextUser.ID} on session ${sessionID}: ${decision.Reason}`);
|
|
213
|
+
throw new RecordingRequestError(403, 'Not authorized for this realtime session');
|
|
214
|
+
}
|
|
215
|
+
return session;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Refuses a request the session's own lifetime rules out: 410 once the session closed more than
|
|
219
|
+
* {@link LATE_SHARD_WINDOW_MS} ago (the recording is settled), and 400 when `endSample` (a shard's end,
|
|
220
|
+
* or the terminal's captured count) is more audio than the session has existed, from its server-set
|
|
221
|
+
* creation to its close (or now), plus {@link SESSION_LIFETIME_SLACK_MS}. Without the second rule one
|
|
222
|
+
* 5 s shard and a terminal claiming 3 h made the server allocate and store a ~1 GB WAV.
|
|
223
|
+
*/
|
|
224
|
+
function assertWithinSessionLifetime(session, endSample, what) {
|
|
225
|
+
const now = Date.now();
|
|
226
|
+
const closedAt = session.ClosedAt ? new Date(session.ClosedAt).getTime() : null;
|
|
227
|
+
if (closedAt !== null && now - closedAt > LATE_SHARD_WINDOW_MS) {
|
|
228
|
+
throw new RecordingRequestError(410, `Session ${session.ID} closed over 24 h ago; its recording no longer accepts audio`);
|
|
229
|
+
}
|
|
230
|
+
const lifetimeMs = (closedAt ?? now) - new Date(session.__mj_CreatedAt).getTime() + SESSION_LIFETIME_SLACK_MS;
|
|
231
|
+
const maxSamples = Math.max(0, Math.floor((lifetimeMs * RECORDING_SAMPLE_RATE) / 1000));
|
|
232
|
+
if (endSample > maxSamples) {
|
|
233
|
+
LogError(`RealtimeRecordingHandler: refused ${what} of session ${session.ID}: it reaches sample ${endSample}, past the ${maxSamples} the session's lifetime allows`);
|
|
234
|
+
throw new RecordingRequestError(400, `The ${what} reach sample ${endSample}, more audio than session ${session.ID} has existed for (${maxSamples} samples)`);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
/** The tail shard of a terminal request, or null for an empty body. */
|
|
238
|
+
function readOptionalTail(req, sessionID, lastShardIndex) {
|
|
239
|
+
if (!Buffer.isBuffer(req.body)) {
|
|
240
|
+
// express.raw leaves the body unset for an empty body or a non-octet-stream content type; only the former is a valid "no tail".
|
|
241
|
+
if (Number(req.headers['content-length'] ?? 0) > 0 || req.headers['transfer-encoding'] !== undefined) {
|
|
242
|
+
throw new RecordingRequestError(400, `The tail must be an ${OCTET_STREAM} body`);
|
|
243
|
+
}
|
|
244
|
+
return null;
|
|
245
|
+
}
|
|
246
|
+
if (req.body.length === 0) {
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
const header = parseShard(req.body, sessionID);
|
|
250
|
+
if (header.ShardIndex !== lastShardIndex) {
|
|
251
|
+
throw new RecordingRequestError(400, `Tail shard index ${header.ShardIndex} does not match lastShardIndex ${lastShardIndex}`);
|
|
252
|
+
}
|
|
253
|
+
return { Header: header, Bytes: req.body };
|
|
254
|
+
}
|
|
255
|
+
/** Validates the MJOPUS1 structure (header and packet bounds; no decoding). */
|
|
256
|
+
function parseShard(bytes, sessionID) {
|
|
257
|
+
try {
|
|
258
|
+
const { ShardIndex, StartSample, SampleCount, PacketCount } = ParseRecordingShard(bytes);
|
|
259
|
+
return { ShardIndex, StartSample, SampleCount, PacketCount };
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
if (error instanceof RecordingShardFormatError) {
|
|
263
|
+
LogStatus(`RealtimeRecordingHandler: malformed shard for session ${sessionID}: ${error.message}`);
|
|
264
|
+
throw new RecordingRequestError(400, `Malformed recording shard: ${error.message}`);
|
|
265
|
+
}
|
|
266
|
+
throw error;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
/** Records one shard; a conflict (same index, different bytes) is logged and answered 409. */
|
|
270
|
+
async function recordShard(ledger, sessionID, header, bytes) {
|
|
271
|
+
const result = await ledger.RecordShard({
|
|
272
|
+
SessionID: sessionID,
|
|
273
|
+
Index: header.ShardIndex,
|
|
274
|
+
StartSample: header.StartSample,
|
|
275
|
+
SampleCount: header.SampleCount,
|
|
276
|
+
Data: bytes,
|
|
277
|
+
Sha256: createHash('sha256').update(bytes).digest('hex'),
|
|
278
|
+
});
|
|
279
|
+
if (result.Outcome === 'Conflict') {
|
|
280
|
+
LogError(`RealtimeRecordingHandler: session ${sessionID} sent shard ${header.ShardIndex} again with different bytes; ` +
|
|
281
|
+
`the recording is marked Failed for review`);
|
|
282
|
+
throw new RecordingRequestError(409, `Shard ${header.ShardIndex} was already stored with different bytes`);
|
|
283
|
+
}
|
|
284
|
+
return result;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* After a newly inserted shard below the expected count (one that arrived after the terminal signal):
|
|
288
|
+
* - on a `Partial` recording, re-assemble now, unless the session closed more than 24 h ago;
|
|
289
|
+
* - on a `Pending` recording waiting out its grace, assemble now if this was the last missing shard,
|
|
290
|
+
* instead of waiting for the grace timer.
|
|
291
|
+
* Shards at or past the expected count need nothing here: the ledger re-opens the recording (`Pending`)
|
|
292
|
+
* and a terminal signal or the janitor follows.
|
|
293
|
+
*/
|
|
294
|
+
async function scheduleAfterLateShard(deps, provider, sessionID, index, result) {
|
|
295
|
+
const expected = result.ExpectedShards;
|
|
296
|
+
if (expected === null || index >= expected) {
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
if (result.RecordingStatus !== 'Partial' && result.RecordingStatus !== 'Pending') {
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
if (!result.ClosedAt) {
|
|
303
|
+
// The call is still open (e.g. the tab was hidden and came back): assemble after the grace period,
|
|
304
|
+
// not now. Repeated requests keep the earliest timer.
|
|
305
|
+
deps.Scheduler.ScheduleAssembly(sessionID, deps.GraceMs(), true);
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
if (result.RecordingStatus === 'Partial') {
|
|
309
|
+
// A session closed over LATE_SHARD_WINDOW_MS ago never gets here: its requests are refused (410).
|
|
310
|
+
deps.Scheduler.ScheduleAssembly(sessionID, 0, false);
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
await scheduleWhenReady(deps, provider, sessionID, expected, false);
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Schedules a `Pending` recording: now when every expected shard is stored; otherwise, after a final
|
|
317
|
+
* terminal (`recheckWhenIncomplete`), a re-check in {@link FINAL_TERMINAL_RECHECK_MS} that falls back to
|
|
318
|
+
* the forced-`Partial` grace when shards are still missing.
|
|
319
|
+
*/
|
|
320
|
+
async function scheduleWhenReady(deps, provider, sessionID, expected, recheckWhenIncomplete = true) {
|
|
321
|
+
const systemUser = deps.SystemUser();
|
|
322
|
+
if (!systemUser) {
|
|
323
|
+
LogError(`RealtimeRecordingHandler: no system user to check whether the recording of session ${sessionID} is complete; the session janitor will assemble it`);
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
const present = await deps.CreateLedger(provider, systemUser).CountShardsBelow(sessionID, expected);
|
|
327
|
+
if (present === expected) {
|
|
328
|
+
deps.Scheduler.ScheduleAssembly(sessionID, 0, false);
|
|
329
|
+
}
|
|
330
|
+
else if (recheckWhenIncomplete) {
|
|
331
|
+
deps.Scheduler.ScheduleAssembly(sessionID, FINAL_TERMINAL_RECHECK_MS, false);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
function logIgnoredTerminal(session, expected, captured, status) {
|
|
335
|
+
LogStatus(`RealtimeRecordingHandler: ignored a lower terminal for session ${session.ID}: received ${expected} shards / ${captured} samples, ` +
|
|
336
|
+
`stored ${session.RecordingExpectedShards ?? 'none'} shards / ${session.RecordingCapturedSamples ?? 'none'} samples (recording ${status ?? 'not recorded'})`);
|
|
337
|
+
}
|
|
338
|
+
/** The terminal's `final` flag: absent or `true` means the call ended; `false` means the tab was hidden. */
|
|
339
|
+
function parseFinalFlag(value) {
|
|
340
|
+
if (value === undefined || value === 'true') {
|
|
341
|
+
return true;
|
|
342
|
+
}
|
|
343
|
+
if (value === 'false') {
|
|
344
|
+
return false;
|
|
345
|
+
}
|
|
346
|
+
throw new RecordingRequestError(400, `final must be true or false, got '${String(value)}'`);
|
|
347
|
+
}
|
|
348
|
+
/** Parses a non-negative (or, with {@link INT}, signed) safe integer route or query value; 400 otherwise. */
|
|
349
|
+
function parseInteger(value, field, pattern) {
|
|
350
|
+
if (typeof value !== 'string' || !pattern.test(value)) {
|
|
351
|
+
throw new RecordingRequestError(400, `${field} must be an integer, got '${String(value ?? '')}'`);
|
|
352
|
+
}
|
|
353
|
+
const parsed = Number(value);
|
|
354
|
+
if (!Number.isSafeInteger(parsed)) {
|
|
355
|
+
throw new RecordingRequestError(400, `${field} is out of range`);
|
|
356
|
+
}
|
|
357
|
+
return parsed;
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Error middleware for failures raised before a handler runs, which are body-parsing failures: 413 for an
|
|
361
|
+
* over-cap body, 400 for any other client-side body error, 500 (logged) otherwise.
|
|
362
|
+
*/
|
|
363
|
+
function handleBodyError(error, req, res, next) {
|
|
364
|
+
if (res.headersSent) {
|
|
365
|
+
next(error);
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
const status = typeof error === 'object' && error !== null && 'status' in error ? Number(error.status) : 500;
|
|
369
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
370
|
+
if (status === 413) {
|
|
371
|
+
LogStatus(`RealtimeRecordingHandler: ${req.originalUrl} body over the cap: ${message}`);
|
|
372
|
+
res.status(413).json({ error: 'Body too large' });
|
|
373
|
+
}
|
|
374
|
+
else if (status >= 400 && status < 500) {
|
|
375
|
+
LogStatus(`RealtimeRecordingHandler: ${req.originalUrl} body could not be read: ${message}`);
|
|
376
|
+
res.status(400).json({ error: 'Body could not be read' });
|
|
377
|
+
}
|
|
378
|
+
else {
|
|
379
|
+
LogError(`RealtimeRecordingHandler: ${req.originalUrl} failed before its handler: ${message}`);
|
|
380
|
+
res.status(500).json({ error: 'Recording request failed' });
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
//# sourceMappingURL=RealtimeRecordingHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RealtimeRecordingHandler.js","sourceRoot":"","sources":["../../src/rest/RealtimeRecordingHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -53,7 +53,9 @@ export declare class ViewOperationsHandler {
|
|
|
53
53
|
error?: string;
|
|
54
54
|
}>;
|
|
55
55
|
/**
|
|
56
|
-
* Sanitize and validate RunViewParams
|
|
56
|
+
* Sanitize and validate RunViewParams. Client filter and sort text passes the same clause
|
|
57
|
+
* screen as the GraphQL RunView resolvers, parsed in the dialect of `provider`, the provider
|
|
58
|
+
* that runs the view.
|
|
57
59
|
*/
|
|
58
60
|
private static sanitizeRunViewParams;
|
|
59
61
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ViewOperationsHandler.d.ts","sourceRoot":"","sources":["../../src/rest/ViewOperationsHandler.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"ViewOperationsHandler.d.ts","sourceRoot":"","sources":["../../src/rest/ViewOperationsHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EACsC,aAAa,EACtD,aAAa,EAAE,QAAQ,EAC1B,MAAM,sBAAsB,CAAC;AAG9B;;;GAGG;AACH,qBAAa,qBAAqB;IAC9B;;OAEG;WACU,OAAO,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,aAAa,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAmClI,uCAAuC;WAC1B,OAAO,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,aAAa,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAIlI;;OAEG;WACU,QAAQ,CAAC,WAAW,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAsC7I,wCAAwC;WAC3B,QAAQ,CAAC,WAAW,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAI7I;;OAEG;WACU,YAAY,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,aAAa,CAAC;IA0BxF,4CAA4C;WAC/B,YAAY,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,aAAa,CAAC;IAIxF;;OAEG;WACU,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAqD7H,8CAA8C;WACjC,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAI7H;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,qBAAqB;CA6CvC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { LogError, Metadata, RunView } from '@memberjunction/core';
|
|
1
|
+
import { BaseEntity, LogError, Metadata, RunView } from '@memberjunction/core';
|
|
2
|
+
import { ClientClauseScreen } from '@memberjunction/generic-database-provider';
|
|
2
3
|
/**
|
|
3
4
|
* View Operations Implementation for REST endpoints
|
|
4
5
|
* These functions handle running views through the REST API
|
|
@@ -26,10 +27,10 @@ export class ViewOperationsHandler {
|
|
|
26
27
|
error: `User ${user.Name} does not have permission to read ${params.EntityName} records`
|
|
27
28
|
};
|
|
28
29
|
}
|
|
29
|
-
// Sanitize and validate parameters
|
|
30
|
-
this.sanitizeRunViewParams(params);
|
|
31
|
-
// Execute the view
|
|
30
|
+
// Sanitize and validate parameters against the provider that runs the view
|
|
32
31
|
const runView = new RunView();
|
|
32
|
+
this.sanitizeRunViewParams(params, md, runView.ProviderToUse, user);
|
|
33
|
+
// Execute the view
|
|
33
34
|
const result = await runView.RunView(params, user);
|
|
34
35
|
return { success: true, result };
|
|
35
36
|
}
|
|
@@ -47,8 +48,9 @@ export class ViewOperationsHandler {
|
|
|
47
48
|
*/
|
|
48
49
|
static async RunViews(paramsArray, user) {
|
|
49
50
|
try {
|
|
50
|
-
// Validate and sanitize each set of parameters
|
|
51
|
+
// Validate and sanitize each set of parameters against the provider that runs the views
|
|
51
52
|
const md = new Metadata(); // global-provider-ok: REST endpoint — no per-request provider injection in REST middleware yet
|
|
53
|
+
const runView = new RunView();
|
|
52
54
|
for (const params of paramsArray) {
|
|
53
55
|
// Validate entity exists
|
|
54
56
|
const entity = md.Entities.find(e => e.Name === params.EntityName);
|
|
@@ -67,10 +69,9 @@ export class ViewOperationsHandler {
|
|
|
67
69
|
};
|
|
68
70
|
}
|
|
69
71
|
// Sanitize parameters
|
|
70
|
-
this.sanitizeRunViewParams(params);
|
|
72
|
+
this.sanitizeRunViewParams(params, md, runView.ProviderToUse, user);
|
|
71
73
|
}
|
|
72
74
|
// Execute the views
|
|
73
|
-
const runView = new RunView();
|
|
74
75
|
const results = await runView.RunViews(paramsArray, user);
|
|
75
76
|
return { success: true, results };
|
|
76
77
|
}
|
|
@@ -98,10 +99,10 @@ export class ViewOperationsHandler {
|
|
|
98
99
|
if (!permissions.CanRead) {
|
|
99
100
|
throw new Error(`User ${user.Name} does not have permission to read ${params.EntityName} records`);
|
|
100
101
|
}
|
|
101
|
-
// Sanitize and validate parameters
|
|
102
|
-
this.sanitizeRunViewParams(params);
|
|
103
|
-
// Execute the view
|
|
102
|
+
// Sanitize and validate parameters against the provider that runs the view
|
|
104
103
|
const runView = new RunView();
|
|
104
|
+
this.sanitizeRunViewParams(params, md, runView.ProviderToUse, user);
|
|
105
|
+
// Execute the view
|
|
105
106
|
return await runView.RunView(params, user);
|
|
106
107
|
}
|
|
107
108
|
catch (error) {
|
|
@@ -168,13 +169,20 @@ export class ViewOperationsHandler {
|
|
|
168
169
|
return this.GetEntityViews(entityName, user);
|
|
169
170
|
}
|
|
170
171
|
/**
|
|
171
|
-
* Sanitize and validate RunViewParams
|
|
172
|
+
* Sanitize and validate RunViewParams. Client filter and sort text passes the same clause
|
|
173
|
+
* screen as the GraphQL RunView resolvers, parsed in the dialect of `provider`, the provider
|
|
174
|
+
* that runs the view.
|
|
172
175
|
*/
|
|
173
|
-
static sanitizeRunViewParams(params) {
|
|
176
|
+
static sanitizeRunViewParams(params, md, provider, user) {
|
|
174
177
|
// Ensure EntityName is provided
|
|
175
178
|
if (!params.EntityName) {
|
|
176
179
|
throw new Error('EntityName is required');
|
|
177
180
|
}
|
|
181
|
+
// A loaded view entity cannot arrive over JSON; the provider would trust a plain object's
|
|
182
|
+
// fields (its ID is spliced into view SQL). REST callers name a saved view by ViewID or ViewName.
|
|
183
|
+
if (params.ViewEntity != null && !(params.ViewEntity instanceof BaseEntity)) {
|
|
184
|
+
throw new Error('ViewEntity is not accepted over REST; use ViewID or ViewName');
|
|
185
|
+
}
|
|
178
186
|
// Convert string arrays if they came in as comma-separated strings
|
|
179
187
|
if (params.Fields && typeof params.Fields === 'string') {
|
|
180
188
|
params.Fields = params.Fields.split(',');
|
|
@@ -197,6 +205,7 @@ export class ViewOperationsHandler {
|
|
|
197
205
|
if (!params.ResultType) {
|
|
198
206
|
params.ResultType = 'simple';
|
|
199
207
|
}
|
|
208
|
+
ClientClauseScreen.ScreenViewClauses({ ExtraFilter: params.ExtraFilter, OrderBy: params.OrderBy, OverrideExcludeFilter: params.OverrideExcludeFilter }, md.Entities, ClientClauseScreen.DialectFor(provider), user);
|
|
200
209
|
}
|
|
201
210
|
}
|
|
202
211
|
//# sourceMappingURL=ViewOperationsHandler.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ViewOperationsHandler.js","sourceRoot":"","sources":["../../src/rest/ViewOperationsHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,QAAQ,EAAE,QAAQ,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"ViewOperationsHandler.js","sourceRoot":"","sources":["../../src/rest/ViewOperationsHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import express from 'express';
|
|
2
|
+
/**
|
|
3
|
+
* Known exception to the API-root rule (#5674): REST stays at the ORIGIN-absolute `/api/v1` and does NOT go
|
|
4
|
+
* through `ApiRoute()`. Prefixed deployments (CloudFront `/api/*`) already reach it at this absolute path;
|
|
5
|
+
* under `MJAPI_BASE_PATH=/api` wrapping it would make it `/api/api/v1` and break
|
|
6
|
+
* every REST client. It is passed as a constant, so `check:api-root` (which flags literals) does not trip.
|
|
7
|
+
*/
|
|
2
8
|
export declare const REST_API_BASE_PATH = "/api/v1";
|
|
3
9
|
/** @deprecated Use {@link REST_API_BASE_PATH}. */
|
|
4
10
|
export declare const ___REST_API_BASE_PATH = "/api/v1";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setupRESTEndpoints.d.ts","sourceRoot":"","sources":["../../src/rest/setupRESTEndpoints.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAK9B,eAAO,MAAM,kBAAkB,YAAY,CAAC;AAE5C,kDAAkD;AAClD,eAAO,MAAM,qBAAqB,YAAqB,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC3B;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAE3B;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAE3B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAE1B;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED;;GAEG;AACH,eAAO,MAAM,wBAAwB,EAAE,cAEtC,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAC9B,GAAG,EAAE,OAAO,CAAC,WAAW,EACxB,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,EACjC,cAAc,CAAC,EAAE,OAAO,CAAC,cAAc,GACxC,IAAI,CA8BN;AAED,kDAAkD;AAClD,wBAAgB,kBAAkB,CAC9B,GAAG,EAAE,OAAO,CAAC,WAAW,EACxB,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,EACjC,cAAc,CAAC,EAAE,OAAO,CAAC,cAAc,GACxC,IAAI,CAEN"}
|
|
1
|
+
{"version":3,"file":"setupRESTEndpoints.d.ts","sourceRoot":"","sources":["../../src/rest/setupRESTEndpoints.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAK9B;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,YAAY,CAAC;AAE5C,kDAAkD;AAClD,eAAO,MAAM,qBAAqB,YAAqB,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC3B;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAE3B;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAE3B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAE1B;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED;;GAEG;AACH,eAAO,MAAM,wBAAwB,EAAE,cAEtC,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAC9B,GAAG,EAAE,OAAO,CAAC,WAAW,EACxB,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,EACjC,cAAc,CAAC,EAAE,OAAO,CAAC,cAAc,GACxC,IAAI,CA8BN;AAED,kDAAkD;AAClD,wBAAgB,kBAAkB,CAC9B,GAAG,EAAE,OAAO,CAAC,WAAW,EACxB,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,EACjC,cAAc,CAAC,EAAE,OAAO,CAAC,cAAc,GACxC,IAAI,CAEN"}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import BodyParser from 'body-parser';
|
|
2
2
|
import { LogStatusEx } from '@memberjunction/core';
|
|
3
3
|
import { RESTEndpointHandler } from './RESTEndpointHandler.js';
|
|
4
|
+
/**
|
|
5
|
+
* Known exception to the API-root rule (#5674): REST stays at the ORIGIN-absolute `/api/v1` and does NOT go
|
|
6
|
+
* through `ApiRoute()`. Prefixed deployments (CloudFront `/api/*`) already reach it at this absolute path;
|
|
7
|
+
* under `MJAPI_BASE_PATH=/api` wrapping it would make it `/api/api/v1` and break
|
|
8
|
+
* every REST client. It is passed as a constant, so `check:api-root` (which flags literals) does not trip.
|
|
9
|
+
*/
|
|
4
10
|
export const REST_API_BASE_PATH = '/api/v1';
|
|
5
11
|
/** @deprecated Use {@link REST_API_BASE_PATH}. */
|
|
6
12
|
export const ___REST_API_BASE_PATH = REST_API_BASE_PATH;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setupRESTEndpoints.js","sourceRoot":"","sources":["../../src/rest/setupRESTEndpoints.ts"],"names":[],"mappings":"AACA,OAAO,UAAU,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,MAAM,CAAC,MAAM,kBAAkB,GAAG,SAAS,CAAC;AAE5C,kDAAkD;AAClD,MAAM,CAAC,MAAM,qBAAqB,GAAG,kBAAkB,CAAC;AAwCxD;;GAEG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAmB;IACpD,OAAO,EAAE,IAAI;CAChB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAC9B,GAAwB,EACxB,OAAiC,EACjC,cAAuC;IAEvC,6BAA6B;IAC7B,MAAM,MAAM,GAAG,EAAE,GAAG,wBAAwB,EAAE,GAAG,OAAO,EAAE,CAAC;IAE3D,mFAAmF;IACnF,yEAAyE;IACzE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QAClB,WAAW,CAAC,EAAE,OAAO,EAAE,iCAAiC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/E,OAAO;IACX,CAAC;IAED,MAAM,QAAQ,GAAG,kBAAkB,CAAC;IAEpC,8DAA8D;IAC9D,MAAM,WAAW,GAAG,IAAI,mBAAmB,CAAC;QACxC,eAAe,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS;QACtG,eAAe,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS;QACtG,cAAc,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS;QACnG,cAAc,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS;KACtG,CAAC,CAAC;IAEH,gEAAgE;IAChE,4DAA4D;IAC5D,IAAI,cAAc,EAAE,CAAC;QACjB,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,cAAc,EAAE,WAAW,CAAC,SAAS,EAAE,CAAC,CAAC;IACnG,CAAC;SAAM,CAAC;QACJ,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,CAAC,SAAS,EAAE,CAAC,CAAC;IACnF,CAAC;IAED,WAAW,CAAC,EAAE,OAAO,EAAE,0CAA0C,QAAQ,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;AACtG,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,kBAAkB,CAC9B,GAAwB,EACxB,OAAiC,EACjC,cAAuC;IAEvC,OAAO,kBAAkB,CAAC,GAAG,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;AAC5D,CAAC"}
|
|
1
|
+
{"version":3,"file":"setupRESTEndpoints.js","sourceRoot":"","sources":["../../src/rest/setupRESTEndpoints.ts"],"names":[],"mappings":"AACA,OAAO,UAAU,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,SAAS,CAAC;AAE5C,kDAAkD;AAClD,MAAM,CAAC,MAAM,qBAAqB,GAAG,kBAAkB,CAAC;AAwCxD;;GAEG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAmB;IACpD,OAAO,EAAE,IAAI;CAChB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAC9B,GAAwB,EACxB,OAAiC,EACjC,cAAuC;IAEvC,6BAA6B;IAC7B,MAAM,MAAM,GAAG,EAAE,GAAG,wBAAwB,EAAE,GAAG,OAAO,EAAE,CAAC;IAE3D,mFAAmF;IACnF,yEAAyE;IACzE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QAClB,WAAW,CAAC,EAAE,OAAO,EAAE,iCAAiC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/E,OAAO;IACX,CAAC;IAED,MAAM,QAAQ,GAAG,kBAAkB,CAAC;IAEpC,8DAA8D;IAC9D,MAAM,WAAW,GAAG,IAAI,mBAAmB,CAAC;QACxC,eAAe,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS;QACtG,eAAe,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS;QACtG,cAAc,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS;QACnG,cAAc,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS;KACtG,CAAC,CAAC;IAEH,gEAAgE;IAChE,4DAA4D;IAC5D,IAAI,cAAc,EAAE,CAAC;QACjB,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,cAAc,EAAE,WAAW,CAAC,SAAS,EAAE,CAAC,CAAC;IACnG,CAAC;SAAM,CAAC;QACJ,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,CAAC,SAAS,EAAE,CAAC,CAAC;IACnF,CAAC;IAED,WAAW,CAAC,EAAE,OAAO,EAAE,0CAA0C,QAAQ,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;AACtG,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,kBAAkB,CAC9B,GAAwB,EACxB,OAAiC,EACjC,cAAuC;IAEvC,OAAO,kBAAkB,CAAC,GAAG,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;AAC5D,CAAC"}
|