@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,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A host mj.config.cjs serverExtensions[] entry may be a partial OVERLAY of an extension an Open App
|
|
3
|
+
* package publishes: only DriverClass is required. The schema used to require RootPath and default
|
|
4
|
+
* Enabled to true, so `{ DriverClass, OwnsCORS: false }` failed config parsing at startup, and an
|
|
5
|
+
* overlay that omitted Enabled re-enabled an extension its package ships disabled. Completeness is
|
|
6
|
+
* checked after the merge instead.
|
|
7
|
+
*/
|
|
8
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
9
|
+
|
|
10
|
+
// config.ts evaluates `configInfo = LoadConfig()` at module load, and it rejects a configuration
|
|
11
|
+
// carrying no database credentials. Stubbing only the cosmiconfig search lets the module import so the
|
|
12
|
+
// REAL ServerExtensionSchema is under test (same pattern as newUserRolesDefault.test.ts).
|
|
13
|
+
vi.mock('cosmiconfig', () => ({
|
|
14
|
+
cosmiconfigSync: () => ({
|
|
15
|
+
search: () => ({
|
|
16
|
+
filepath: '/test/mj.config.cjs',
|
|
17
|
+
isEmpty: false,
|
|
18
|
+
config: { dbUsername: 'test-user', dbPassword: 'test-password', dbDatabase: 'test-db' },
|
|
19
|
+
}),
|
|
20
|
+
}),
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
import { MergeServerExtensionConfigs, PrepareServerExtensionConfigs } from '@memberjunction/server-extensions-core';
|
|
24
|
+
import type { ServerExtensionConfig } from '@memberjunction/server-extensions-core';
|
|
25
|
+
import { ServerExtensionSchema } from '../config.js';
|
|
26
|
+
|
|
27
|
+
const published: ServerExtensionConfig = {
|
|
28
|
+
Enabled: true,
|
|
29
|
+
DriverClass: 'BallotEdge',
|
|
30
|
+
RootPath: '/vote',
|
|
31
|
+
OwnsCORS: true,
|
|
32
|
+
Settings: { RateLimitMax: 20 },
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
describe('host serverExtensions[] overlay schema', () => {
|
|
36
|
+
it('accepts an overlay that names only DriverClass and the fields it overrides', () => {
|
|
37
|
+
const parsed = ServerExtensionSchema.safeParse({ DriverClass: 'BallotEdge', OwnsCORS: false });
|
|
38
|
+
expect(parsed.success).toBe(true);
|
|
39
|
+
expect(parsed.success && parsed.data.RootPath).toBeUndefined();
|
|
40
|
+
expect(parsed.success && parsed.data.Enabled).toBeUndefined();
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('merges the overlay onto the published entry without losing RootPath or Enabled', () => {
|
|
44
|
+
const overlay = ServerExtensionSchema.parse({ DriverClass: 'BallotEdge', OwnsCORS: false, Settings: { RateLimitMax: 2000 } });
|
|
45
|
+
const [merged] = MergeServerExtensionConfigs([published], [overlay as ServerExtensionConfig]);
|
|
46
|
+
expect(merged).toMatchObject({ DriverClass: 'BallotEdge', RootPath: '/vote', Enabled: true, OwnsCORS: false });
|
|
47
|
+
expect(merged.Settings).toEqual({ RateLimitMax: 2000 });
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('does not re-enable an extension the package ships disabled', () => {
|
|
51
|
+
const overlay = ServerExtensionSchema.parse({ DriverClass: 'BallotEdge', Settings: { RateLimitMax: 5 } });
|
|
52
|
+
const [merged] = MergeServerExtensionConfigs([{ ...published, Enabled: false }], [overlay as ServerExtensionConfig]);
|
|
53
|
+
expect(merged.Enabled).toBe(false);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('still rejects a host-only entry without a RootPath, after the merge', () => {
|
|
57
|
+
const overlay = ServerExtensionSchema.parse({ DriverClass: 'NotPublishedAnywhere' });
|
|
58
|
+
const problems: string[] = [];
|
|
59
|
+
const prepared = PrepareServerExtensionConfigs(
|
|
60
|
+
MergeServerExtensionConfigs([published], [overlay as ServerExtensionConfig]),
|
|
61
|
+
{ onInvalid: (message: string) => problems.push(message) },
|
|
62
|
+
);
|
|
63
|
+
expect(prepared.map(c => c.DriverClass)).toEqual(['BallotEdge']);
|
|
64
|
+
expect(problems.some(p => p.includes('NotPublishedAnywhere') && p.includes('RootPath is empty'))).toBe(true);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Pins the reserved-root set passed into prepareServerExtensionConfigs.
|
|
3
|
-
* A
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* A drifted `*_MOUNT_PATH` constant is a contract failure — this file reads those
|
|
4
|
+
* sources as text so it never loads `config.ts`. That every core mount is reserved
|
|
5
|
+
* is checked against the real mounts in apiRootBoot.test.ts.
|
|
6
6
|
*/
|
|
7
7
|
import { describe, it, expect } from 'vitest';
|
|
8
8
|
import { readFileSync } from 'node:fs';
|
|
@@ -26,11 +26,6 @@ function exportedStringConst(relativeFile: string, name: string): string {
|
|
|
26
26
|
return match[1];
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
function indexContainsLiteralPath(path: string): boolean {
|
|
30
|
-
const src = readFileSync(join(SRC, 'index.ts'), 'utf8');
|
|
31
|
-
return src.includes(`'${path}'`) || src.includes(`\`${path}\``) || src.includes(path.replace(/^\//, ''));
|
|
32
|
-
}
|
|
33
|
-
|
|
34
29
|
describe('coreReservedServerExtensionRoots', () => {
|
|
35
30
|
it('stays in lockstep with exported *_MOUNT_PATH constants', () => {
|
|
36
31
|
expect(CORE_CONSTANT_RESERVED_SERVER_EXTENSION_ROOTS).toEqual([
|
|
@@ -40,92 +35,11 @@ describe('coreReservedServerExtensionRoots', () => {
|
|
|
40
35
|
]);
|
|
41
36
|
});
|
|
42
37
|
|
|
43
|
-
it('includes
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
if (path === '/health') {
|
|
47
|
-
expect(indexSrc, `${path} missing from serve()`).toContain("'/health/extensions'");
|
|
48
|
-
} else if (path === '/realtime') {
|
|
49
|
-
expect(indexSrc, `${path} missing from serve()`).toMatch(/REALTIME_SDP_EXCHANGE_PATH|'\/realtime'/);
|
|
50
|
-
} else if (path === '/realtime-proxy') {
|
|
51
|
-
expect(indexSrc, `${path} missing from serve()`).toContain('/realtime-proxy');
|
|
52
|
-
} else {
|
|
53
|
-
expect(indexSrc, `${path} missing from serve()`).toContain(`'${path}'`);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
expect(indexContainsLiteralPath('/healthcheck')).toBe(true);
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it('structurally guarantees every pre-auth app.use / app.get / app.post mount in index.ts is reserved', () => {
|
|
60
|
-
const indexSrc = readFileSync(join(SRC, 'index.ts'), 'utf8');
|
|
61
|
-
const authMiddlewareIndex = indexSrc.indexOf('app.use(CreateUnifiedAuthMiddleware');
|
|
62
|
-
expect(authMiddlewareIndex).toBeGreaterThan(0);
|
|
63
|
-
const preAuthSrc = indexSrc.substring(0, authMiddlewareIndex);
|
|
64
|
-
|
|
65
|
-
const mountRegex = /app\.(?:use|get|post)\s*\(\s*([^,\s)]+)/g;
|
|
66
|
-
const reservedRoots = CoreReservedServerExtensionRoots('/');
|
|
67
|
-
|
|
68
|
-
// Explicit allowlist of known non-path middleware mounts (e.g. app.use(mw), app.use(cors()), app.use(compression(...)))
|
|
69
|
-
const knownNonPathTokens = [
|
|
70
|
-
'cors',
|
|
71
|
-
'express.',
|
|
72
|
-
'compression',
|
|
73
|
-
'cookieParser',
|
|
74
|
-
'CreateUnifiedAuthMiddleware',
|
|
75
|
-
'mw',
|
|
76
|
-
];
|
|
77
|
-
const isKnownNonPath = (t: string): boolean =>
|
|
78
|
-
knownNonPathTokens.some(k => t === k || t.startsWith(k));
|
|
79
|
-
|
|
80
|
-
// Strip single-line and multi-line comments so comments like `app.use(...)` are not treated as code
|
|
81
|
-
const cleanPreAuthSrc = preAuthSrc.replace(/\/\*[\s\S]*?\*\/|\/\/.*/g, '');
|
|
82
|
-
|
|
83
|
-
let match: RegExpExecArray | null;
|
|
84
|
-
const mountedTokens: string[] = [];
|
|
85
|
-
while ((match = mountRegex.exec(cleanPreAuthSrc)) !== null) {
|
|
86
|
-
mountedTokens.push(match[1].trim());
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
expect(mountedTokens.length).toBeGreaterThan(0);
|
|
90
|
-
|
|
91
|
-
const knownConstants: Record<string, string> = {
|
|
92
|
-
REALTIME_SDP_EXCHANGE_PATH: '/realtime',
|
|
93
|
-
// Public verify-link routes for realtime identity verification; under the reserved '/realtime' root.
|
|
94
|
-
REALTIME_VERIFY_MOUNT_PATH: '/realtime/verify',
|
|
95
|
-
MAGIC_LINK_MOUNT_PATH: '/magic-link',
|
|
96
|
-
WIDGET_MOUNT_PATH: '/widget',
|
|
97
|
-
AUTH_CATALOG_MOUNT_PATH: '/auth',
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
for (const token of mountedTokens) {
|
|
101
|
-
const isLiteralPath = token.startsWith("'") || token.startsWith('"') || token.startsWith('`');
|
|
102
|
-
const isPathConstant = /^[A-Z0-9_]+_PATH$/.test(token) || token in knownConstants;
|
|
103
|
-
if (!isLiteralPath && !isPathConstant) {
|
|
104
|
-
if (isKnownNonPath(token)) {
|
|
105
|
-
continue;
|
|
106
|
-
}
|
|
107
|
-
throw new Error(`Unrecognized pre-auth mount argument '${token}' in index.ts. If this is a non-path middleware, add it to knownNonPathTokens; if it is a route, reserve its prefix or map its constant.`);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
let pathPrefix: string;
|
|
111
|
-
if (isLiteralPath) {
|
|
112
|
-
pathPrefix = token.slice(1, -1);
|
|
113
|
-
} else if (token in knownConstants) {
|
|
114
|
-
pathPrefix = knownConstants[token];
|
|
115
|
-
} else {
|
|
116
|
-
throw new Error(`Unrecognized pre-auth mount constant '${token}' in index.ts. If this is a new pre-auth route, map its constant or reserve its prefix.`);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
const isCovered = reservedRoots.some(root => pathPrefix === root || pathPrefix.startsWith(`${root}/`));
|
|
120
|
-
expect(isCovered, `Pre-auth mount '${pathPrefix}' (from token '${token}') must be covered by reserved roots`).toBe(true);
|
|
121
|
-
}
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
it('includes graphqlRootPath and every core mount', () => {
|
|
125
|
-
const roots = CoreReservedServerExtensionRoots('/api');
|
|
38
|
+
it('includes every core mount, and no longer graphqlRootPath', () => {
|
|
39
|
+
const roots = CoreReservedServerExtensionRoots();
|
|
40
|
+
expect(roots).not.toContain('/api');
|
|
126
41
|
expect(roots).toEqual(
|
|
127
42
|
expect.arrayContaining([
|
|
128
|
-
'/api',
|
|
129
43
|
'/auth',
|
|
130
44
|
'/magic-link',
|
|
131
45
|
'/widget',
|
|
@@ -141,7 +55,7 @@ describe('coreReservedServerExtensionRoots', () => {
|
|
|
141
55
|
});
|
|
142
56
|
|
|
143
57
|
it('closes the F-M2 bypasses: cased /auth and sibling /healthcheck', () => {
|
|
144
|
-
const extra = CoreReservedServerExtensionRoots(
|
|
58
|
+
const extra = CoreReservedServerExtensionRoots();
|
|
145
59
|
expect(validateServerExtensionRootPath('/Auth', extra)).toMatch(/reserved prefix/);
|
|
146
60
|
expect(validateServerExtensionRootPath('/healthcheck', extra)).toMatch(/reserved prefix/);
|
|
147
61
|
expect(validateServerExtensionRootPath('/Healthcheck', extra)).toMatch(/reserved prefix/);
|
|
@@ -157,10 +71,9 @@ describe('coreReservedServerExtensionRoots', () => {
|
|
|
157
71
|
expect(validateServerExtensionRootPath('/meetings/teams', extra)).toBeNull();
|
|
158
72
|
});
|
|
159
73
|
|
|
160
|
-
it('
|
|
161
|
-
const extra = CoreReservedServerExtensionRoots(
|
|
162
|
-
expect(validateServerExtensionRootPath('/api', extra)).
|
|
163
|
-
expect(validateServerExtensionRootPath('/
|
|
164
|
-
expect(validateServerExtensionRootPath('/apiv2', extra)).toBeNull();
|
|
74
|
+
it('lets extensions sit under the GraphQL path (#5674): RootPaths are relative to MJAPI_BASE_PATH', () => {
|
|
75
|
+
const extra = CoreReservedServerExtensionRoots();
|
|
76
|
+
expect(validateServerExtensionRootPath('/api', extra)).toBeNull();
|
|
77
|
+
expect(validateServerExtensionRootPath('/forms', extra)).toBeNull();
|
|
165
78
|
});
|
|
166
79
|
});
|
|
@@ -45,7 +45,7 @@ import { RedisLocalStorageProvider } from '@memberjunction/redis-provider';
|
|
|
45
45
|
import type { CacheSettingsConfig } from '../config.js';
|
|
46
46
|
|
|
47
47
|
function settings(overrides: Partial<CacheSettingsConfig>): CacheSettingsConfig {
|
|
48
|
-
return { maxMemoryMB: 150, maxPercentOfCachePerEntity: 50, defaultTTLSeconds: 0, evictionSweepIntervalSeconds: 300, verboseLogging: false, engineSweepIntervalSeconds: 300, ...overrides };
|
|
48
|
+
return { maxMemoryMB: 150, maxPercentOfCachePerEntity: 50, maxEntryPercentOfCache: 'auto', defaultTTLSeconds: 0, evictionSweepIntervalSeconds: 300, verboseLogging: false, engineSweepIntervalSeconds: 300, ...overrides };
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
function event(overrides: Partial<CacheChangedEvent>): CacheChangedEvent {
|
|
@@ -117,9 +117,11 @@ describe('shared cache configuration', () => {
|
|
|
117
117
|
});
|
|
118
118
|
|
|
119
119
|
it('maps cacheSettings onto LocalCacheManager settings', () => {
|
|
120
|
-
expect(CacheManagerConfigFromSettings(settings({ maxMemoryMB: 10, maxPercentOfCachePerEntity: 20, defaultTTLSeconds: 5, evictionSweepIntervalSeconds: 7, verboseLogging: true })))
|
|
121
|
-
.toEqual({ maxSizeBytes: 10 * 1024 * 1024, maxPercentOfCachePerEntity: 20, defaultTTLMs: 5000, evictionSweepIntervalMs: 7000, verboseLogging: true });
|
|
120
|
+
expect(CacheManagerConfigFromSettings(settings({ maxMemoryMB: 10, maxPercentOfCachePerEntity: 20, maxEntryPercentOfCache: 40, defaultTTLSeconds: 5, evictionSweepIntervalSeconds: 7, verboseLogging: true })))
|
|
121
|
+
.toEqual({ maxSizeBytes: 10 * 1024 * 1024, maxPercentOfCachePerEntity: 20, maxEntryPercentOfCache: 40, defaultTTLMs: 5000, evictionSweepIntervalMs: 7000, verboseLogging: true });
|
|
122
122
|
expect(CacheManagerConfigFromSettings(undefined).maxSizeBytes).toBe(150 * 1024 * 1024);
|
|
123
|
+
// The per-entry ceiling reaches the cache, and an unset one is derived rather than a fixed fraction.
|
|
124
|
+
expect(CacheManagerConfigFromSettings(undefined).maxEntryPercentOfCache).toBe('auto');
|
|
123
125
|
});
|
|
124
126
|
|
|
125
127
|
it('starts the engine sweep at the configured interval, off when 0', () => {
|