@memberjunction/server 5.40.2 → 5.42.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agentSessions/HostInstance.d.ts +19 -0
- package/dist/agentSessions/HostInstance.d.ts.map +1 -0
- package/dist/agentSessions/HostInstance.js +48 -0
- package/dist/agentSessions/HostInstance.js.map +1 -0
- package/dist/agentSessions/SessionJanitor.d.ts +97 -0
- package/dist/agentSessions/SessionJanitor.d.ts.map +1 -0
- package/dist/agentSessions/SessionJanitor.js +222 -0
- package/dist/agentSessions/SessionJanitor.js.map +1 -0
- package/dist/agentSessions/SessionManager.d.ts +142 -0
- package/dist/agentSessions/SessionManager.d.ts.map +1 -0
- package/dist/agentSessions/SessionManager.js +308 -0
- package/dist/agentSessions/SessionManager.js.map +1 -0
- package/dist/agentSessions/index.d.ts +5 -0
- package/dist/agentSessions/index.d.ts.map +1 -0
- package/dist/agentSessions/index.js +31 -0
- package/dist/agentSessions/index.js.map +1 -0
- package/dist/agentSessions/remoteBrowserGoalEngine.d.ts +102 -0
- package/dist/agentSessions/remoteBrowserGoalEngine.d.ts.map +1 -0
- package/dist/agentSessions/remoteBrowserGoalEngine.js +164 -0
- package/dist/agentSessions/remoteBrowserGoalEngine.js.map +1 -0
- package/dist/agentSessions/remoteBrowserGoalRegistry.d.ts +66 -0
- package/dist/agentSessions/remoteBrowserGoalRegistry.d.ts.map +1 -0
- package/dist/agentSessions/remoteBrowserGoalRegistry.js +86 -0
- package/dist/agentSessions/remoteBrowserGoalRegistry.js.map +1 -0
- package/dist/auth/initializeProviders.d.ts.map +1 -1
- package/dist/auth/initializeProviders.js +4 -2
- package/dist/auth/initializeProviders.js.map +1 -1
- package/dist/config.d.ts +7 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +12 -2
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +41 -7
- package/dist/context.js.map +1 -1
- package/dist/generated/generated.d.ts +1296 -49
- package/dist/generated/generated.d.ts.map +1 -1
- package/dist/generated/generated.js +50343 -43421
- package/dist/generated/generated.js.map +1 -1
- package/dist/generic/ResolverBase.js +1 -1
- package/dist/generic/ResolverBase.js.map +1 -1
- package/dist/generic/RunViewResolver.js +9 -10
- package/dist/generic/RunViewResolver.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +127 -54
- package/dist/index.js.map +1 -1
- package/dist/integration/CustomColumnPromoter.d.ts +108 -0
- package/dist/integration/CustomColumnPromoter.d.ts.map +1 -0
- package/dist/integration/CustomColumnPromoter.js +508 -0
- package/dist/integration/CustomColumnPromoter.js.map +1 -0
- package/dist/logging/StartupLogger.d.ts +177 -0
- package/dist/logging/StartupLogger.d.ts.map +1 -0
- package/dist/logging/StartupLogger.js +354 -0
- package/dist/logging/StartupLogger.js.map +1 -0
- package/dist/logging/variablesLoggingMiddleware.d.ts.map +1 -1
- package/dist/logging/variablesLoggingMiddleware.js +21 -2
- package/dist/logging/variablesLoggingMiddleware.js.map +1 -1
- package/dist/resolvers/AgentSessionResolver.d.ts +42 -0
- package/dist/resolvers/AgentSessionResolver.d.ts.map +1 -0
- package/dist/resolvers/AgentSessionResolver.js +152 -0
- package/dist/resolvers/AgentSessionResolver.js.map +1 -0
- package/dist/resolvers/EntityPermissionResolver.d.ts +16 -0
- package/dist/resolvers/EntityPermissionResolver.d.ts.map +1 -0
- package/dist/resolvers/EntityPermissionResolver.js +95 -0
- package/dist/resolvers/EntityPermissionResolver.js.map +1 -0
- package/dist/resolvers/ExecuteRemoteOperationResolver.d.ts +27 -0
- package/dist/resolvers/ExecuteRemoteOperationResolver.d.ts.map +1 -0
- package/dist/resolvers/ExecuteRemoteOperationResolver.js +136 -0
- package/dist/resolvers/ExecuteRemoteOperationResolver.js.map +1 -0
- package/dist/resolvers/IntegrationDiscoveryResolver.d.ts +101 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.js +544 -42
- package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
- package/dist/resolvers/RealtimeBridgeResolver.d.ts +121 -0
- package/dist/resolvers/RealtimeBridgeResolver.d.ts.map +1 -0
- package/dist/resolvers/RealtimeBridgeResolver.js +533 -0
- package/dist/resolvers/RealtimeBridgeResolver.js.map +1 -0
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts +688 -0
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -0
- package/dist/resolvers/RealtimeClientSessionResolver.js +1774 -0
- package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -0
- package/dist/resolvers/RemoteBrowserActionResolver.d.ts +432 -0
- package/dist/resolvers/RemoteBrowserActionResolver.d.ts.map +1 -0
- package/dist/resolvers/RemoteBrowserActionResolver.js +1108 -0
- package/dist/resolvers/RemoteBrowserActionResolver.js.map +1 -0
- package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.js +0 -7
- package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
- package/dist/rest/setupRESTEndpoints.d.ts.map +1 -1
- package/dist/rest/setupRESTEndpoints.js +5 -3
- package/dist/rest/setupRESTEndpoints.js.map +1 -1
- package/dist/services/ScheduledJobsService.d.ts.map +1 -1
- package/dist/services/ScheduledJobsService.js +6 -5
- package/dist/services/ScheduledJobsService.js.map +1 -1
- package/package.json +83 -74
- package/src/__tests__/RealtimeBridgeResolver.test.ts +100 -0
- package/src/__tests__/RealtimeClientSessionResolver.test.ts +2605 -0
- package/src/__tests__/RemoteBrowserAudioStream.test.ts +181 -0
- package/src/__tests__/RemoteBrowserGoalEngine.test.ts +144 -0
- package/src/__tests__/SessionJanitor.test.ts +234 -0
- package/src/__tests__/SessionManager.test.ts +465 -0
- package/src/__tests__/remoteBrowserGoalRegistry.test.ts +81 -0
- package/src/__tests__/subscriptionRedaction.test.ts +5 -0
- package/src/agentSessions/HostInstance.ts +53 -0
- package/src/agentSessions/SessionJanitor.ts +267 -0
- package/src/agentSessions/SessionManager.ts +446 -0
- package/src/agentSessions/index.ts +32 -0
- package/src/agentSessions/remoteBrowserGoalEngine.ts +191 -0
- package/src/agentSessions/remoteBrowserGoalRegistry.ts +122 -0
- package/src/auth/initializeProviders.ts +4 -2
- package/src/config.ts +13 -2
- package/src/context.ts +42 -7
- package/src/generated/generated.ts +33808 -29025
- package/src/generic/ResolverBase.ts +1 -1
- package/src/generic/RunViewResolver.ts +9 -9
- package/src/index.ts +128 -54
- package/src/integration/CustomColumnPromoter.ts +597 -0
- package/src/logging/StartupLogger.ts +441 -0
- package/src/logging/variablesLoggingMiddleware.ts +25 -5
- package/src/resolvers/AgentSessionResolver.ts +138 -0
- package/src/resolvers/EntityPermissionResolver.ts +73 -0
- package/src/resolvers/ExecuteRemoteOperationResolver.ts +108 -0
- package/src/resolvers/IntegrationDiscoveryResolver.ts +396 -37
- package/src/resolvers/RealtimeBridgeResolver.ts +450 -0
- package/src/resolvers/RealtimeClientSessionResolver.ts +2162 -0
- package/src/resolvers/RemoteBrowserActionResolver.ts +1122 -0
- package/src/resolvers/RunAIAgentResolver.ts +1 -9
- package/src/rest/setupRESTEndpoints.ts +5 -3
- package/src/services/ScheduledJobsService.ts +6 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AgentSessionResolver.d.ts","sourceRoot":"","sources":["../../src/resolvers/AgentSessionResolver.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAIzC,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAI1D,gEAAgE;AAChE,qBACa,uBAAuB;IAChC,uCAAuC;IAEvC,cAAc,EAAE,MAAM,CAAC;IAEvB,+EAA+E;IAE/E,MAAM,EAAE,MAAM,CAAC;IAEf,uFAAuF;IAEvF,cAAc,EAAE,MAAM,CAAC;CAC1B;AAED;;;;GAIG;AACH,qBACa,oBAAqB,SAAQ,YAAY;IAClD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAwB;IAEvD;;;OAGG;IAEG,iBAAiB,CACH,OAAO,EAAE,MAAM,EACxB,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE,UAAU,EACF,cAAc,CAAC,EAAE,MAAM,EACxB,aAAa,CAAC,EAAE,MAAM,EACzB,UAAU,CAAC,EAAE,MAAM,GAC3D,OAAO,CAAC,uBAAuB,CAAC;IAkBnC;;;OAGG;IAEG,iBAAiB,CACI,cAAc,EAAE,MAAM,EACtC,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE,UAAU,GAC9C,OAAO,CAAC,OAAO,CAAC;IAMnB;;;OAGG;IAEG,qBAAqB,CACA,cAAc,EAAE,MAAM,EACtC,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE,UAAU,GAC9C,OAAO,CAAC,OAAO,CAAC;IAQnB,iGAAiG;IACjG,OAAO,CAAC,sBAAsB;IAW9B;;;OAGG;YACW,eAAe;CAehC"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* @fileoverview GraphQL resolver for the AI Agent Session record lifecycle.
|
|
15
|
+
*
|
|
16
|
+
* Exposes start / close / heartbeat mutations over {@link SessionManager}, each running under the
|
|
17
|
+
* request's `contextUser` + request-scoped `IMetadataProvider`. Enforces two authorization gates:
|
|
18
|
+
* - **Open**: `CanRun` on the target agent (delegated to {@link SessionManager.CreateSession}).
|
|
19
|
+
* - **Close / Heartbeat**: inbound ownership — the session's `UserID` must equal `contextUser.ID`.
|
|
20
|
+
*
|
|
21
|
+
* The audio/media transport and the long-lived realtime run are out of scope here (P5); this
|
|
22
|
+
* resolver only manipulates the durable session record.
|
|
23
|
+
*
|
|
24
|
+
* @module @memberjunction/server
|
|
25
|
+
*/
|
|
26
|
+
import { Resolver, Mutation, Arg, Ctx, ObjectType, Field } from 'type-graphql';
|
|
27
|
+
import { LogError } from '@memberjunction/core';
|
|
28
|
+
import { UUIDsEqual } from '@memberjunction/global';
|
|
29
|
+
import { ResolverBase } from '../generic/ResolverBase.js';
|
|
30
|
+
import { GetReadWriteProvider } from '../util.js';
|
|
31
|
+
import { SessionManager, SessionAuthorizationError } from '../agentSessions/index.js';
|
|
32
|
+
/** Result of {@link AgentSessionResolver.StartAgentSession}. */
|
|
33
|
+
let StartAgentSessionResult = class StartAgentSessionResult {
|
|
34
|
+
};
|
|
35
|
+
__decorate([
|
|
36
|
+
Field(),
|
|
37
|
+
__metadata("design:type", String)
|
|
38
|
+
], StartAgentSessionResult.prototype, "agentSessionId", void 0);
|
|
39
|
+
__decorate([
|
|
40
|
+
Field(),
|
|
41
|
+
__metadata("design:type", String)
|
|
42
|
+
], StartAgentSessionResult.prototype, "status", void 0);
|
|
43
|
+
__decorate([
|
|
44
|
+
Field(),
|
|
45
|
+
__metadata("design:type", String)
|
|
46
|
+
], StartAgentSessionResult.prototype, "conversationId", void 0);
|
|
47
|
+
StartAgentSessionResult = __decorate([
|
|
48
|
+
ObjectType()
|
|
49
|
+
], StartAgentSessionResult);
|
|
50
|
+
export { StartAgentSessionResult };
|
|
51
|
+
/**
|
|
52
|
+
* Resolver for the AI Agent Session record lifecycle. A single {@link SessionManager} instance is
|
|
53
|
+
* shared across requests — it holds no per-user/provider state (only heartbeat-coalescing
|
|
54
|
+
* timestamps), and every method is passed the request `contextUser` + provider explicitly.
|
|
55
|
+
*/
|
|
56
|
+
let AgentSessionResolver = class AgentSessionResolver extends ResolverBase {
|
|
57
|
+
constructor() {
|
|
58
|
+
super(...arguments);
|
|
59
|
+
this.sessionManager = new SessionManager();
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Open a new session for an agent. Authorization (`CanRun`) is enforced inside
|
|
63
|
+
* {@link SessionManager.CreateSession}; a denial surfaces as a thrown error and no row is written.
|
|
64
|
+
*/
|
|
65
|
+
async StartAgentSession(agentId, { userPayload, providers }, conversationId, lastSessionId, configJson) {
|
|
66
|
+
const { contextUser, provider } = this.requireUserAndProvider(userPayload, providers);
|
|
67
|
+
try {
|
|
68
|
+
const session = await this.sessionManager.CreateSession({ agentID: agentId, userID: contextUser.ID, conversationID: conversationId, lastSessionID: lastSessionId, config: configJson }, contextUser, provider);
|
|
69
|
+
return { agentSessionId: session.ID, status: session.Status, conversationId: session.ConversationID ?? '' };
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
if (err instanceof SessionAuthorizationError) {
|
|
73
|
+
throw new Error(err.message); // authorization denial — no session created
|
|
74
|
+
}
|
|
75
|
+
throw err;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Close a session. Rejects unless the caller owns it. Returns `true` on a successful (or
|
|
80
|
+
* idempotent) close, `false` if the session can't be loaded.
|
|
81
|
+
*/
|
|
82
|
+
async CloseAgentSession(agentSessionId, { userPayload, providers }) {
|
|
83
|
+
const { contextUser, provider } = this.requireUserAndProvider(userPayload, providers);
|
|
84
|
+
await this.assertOwnership(agentSessionId, contextUser, provider);
|
|
85
|
+
return this.sessionManager.CloseSession(agentSessionId, contextUser, provider);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Record activity on a session (coalesced). Rejects unless the caller owns it. Returns `true`
|
|
89
|
+
* when the heartbeat was accepted (written or coalesced), `false` if the session is gone/closed.
|
|
90
|
+
*/
|
|
91
|
+
async AgentSessionHeartbeat(agentSessionId, { userPayload, providers }) {
|
|
92
|
+
const { contextUser, provider } = this.requireUserAndProvider(userPayload, providers);
|
|
93
|
+
await this.assertOwnership(agentSessionId, contextUser, provider);
|
|
94
|
+
return this.sessionManager.Heartbeat(agentSessionId, contextUser, provider);
|
|
95
|
+
}
|
|
96
|
+
// ----- internals -------------------------------------------------------------------------
|
|
97
|
+
/** Resolve the request user + read-write provider, throwing a clear error if unauthenticated. */
|
|
98
|
+
requireUserAndProvider(userPayload, providers) {
|
|
99
|
+
const contextUser = this.GetUserFromPayload(userPayload);
|
|
100
|
+
if (!contextUser) {
|
|
101
|
+
throw new Error('Not authenticated: no user context for agent session operation');
|
|
102
|
+
}
|
|
103
|
+
return { contextUser, provider: GetReadWriteProvider(providers) };
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Inbound ownership gate (the one genuinely new session-authz primitive): the session's `UserID`
|
|
107
|
+
* must equal the caller's. Throws on mismatch or when the session can't be loaded.
|
|
108
|
+
*/
|
|
109
|
+
async assertOwnership(agentSessionId, contextUser, provider) {
|
|
110
|
+
const session = await provider.GetEntityObject('MJ: AI Agent Sessions', contextUser);
|
|
111
|
+
const loaded = await session.Load(agentSessionId);
|
|
112
|
+
if (!loaded) {
|
|
113
|
+
throw new Error(`Agent session ${agentSessionId} not found`);
|
|
114
|
+
}
|
|
115
|
+
if (!UUIDsEqual(session.UserID, contextUser.ID)) {
|
|
116
|
+
LogError(`AgentSessionResolver: ownership check failed — user ${contextUser.ID} attempted to operate on session ${agentSessionId} owned by ${session.UserID}`);
|
|
117
|
+
throw new Error('Not authorized: you do not own this agent session');
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
__decorate([
|
|
122
|
+
Mutation(() => StartAgentSessionResult),
|
|
123
|
+
__param(0, Arg('agentId')),
|
|
124
|
+
__param(1, Ctx()),
|
|
125
|
+
__param(2, Arg('conversationId', { nullable: true })),
|
|
126
|
+
__param(3, Arg('lastSessionId', { nullable: true })),
|
|
127
|
+
__param(4, Arg('configJson', { nullable: true })),
|
|
128
|
+
__metadata("design:type", Function),
|
|
129
|
+
__metadata("design:paramtypes", [String, Object, String, String, String]),
|
|
130
|
+
__metadata("design:returntype", Promise)
|
|
131
|
+
], AgentSessionResolver.prototype, "StartAgentSession", null);
|
|
132
|
+
__decorate([
|
|
133
|
+
Mutation(() => Boolean),
|
|
134
|
+
__param(0, Arg('agentSessionId')),
|
|
135
|
+
__param(1, Ctx()),
|
|
136
|
+
__metadata("design:type", Function),
|
|
137
|
+
__metadata("design:paramtypes", [String, Object]),
|
|
138
|
+
__metadata("design:returntype", Promise)
|
|
139
|
+
], AgentSessionResolver.prototype, "CloseAgentSession", null);
|
|
140
|
+
__decorate([
|
|
141
|
+
Mutation(() => Boolean),
|
|
142
|
+
__param(0, Arg('agentSessionId')),
|
|
143
|
+
__param(1, Ctx()),
|
|
144
|
+
__metadata("design:type", Function),
|
|
145
|
+
__metadata("design:paramtypes", [String, Object]),
|
|
146
|
+
__metadata("design:returntype", Promise)
|
|
147
|
+
], AgentSessionResolver.prototype, "AgentSessionHeartbeat", null);
|
|
148
|
+
AgentSessionResolver = __decorate([
|
|
149
|
+
Resolver()
|
|
150
|
+
], AgentSessionResolver);
|
|
151
|
+
export { AgentSessionResolver };
|
|
152
|
+
//# sourceMappingURL=AgentSessionResolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AgentSessionResolver.js","sourceRoot":"","sources":["../../src/resolvers/AgentSessionResolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { AppContext } from '../types.js';
|
|
2
|
+
import { ResolverBase } from '../generic/ResolverBase.js';
|
|
3
|
+
declare class EntityPermissionResult {
|
|
4
|
+
EntityName: string;
|
|
5
|
+
CanRead: boolean;
|
|
6
|
+
}
|
|
7
|
+
declare class CheckEntityPermissionsResult {
|
|
8
|
+
Success: boolean;
|
|
9
|
+
Results: EntityPermissionResult[];
|
|
10
|
+
ErrorMessage?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare class EntityPermissionResolver extends ResolverBase {
|
|
13
|
+
CheckEntityPermissionsSystemUser(entityNames: string[], userEmail: string, context: AppContext): Promise<CheckEntityPermissionsResult>;
|
|
14
|
+
}
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=EntityPermissionResolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EntityPermissionResolver.d.ts","sourceRoot":"","sources":["../../src/resolvers/EntityPermissionResolver.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAK1D,cACM,sBAAsB;IAEhB,UAAU,EAAE,MAAM,CAAC;IAGnB,OAAO,EAAE,OAAO,CAAC;CAC5B;AAED,cACM,4BAA4B;IAEtB,OAAO,EAAE,OAAO,CAAC;IAGjB,OAAO,EAAE,sBAAsB,EAAE,CAAC;IAG1C,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qBACa,wBAAyB,SAAQ,YAAY;IAIhD,gCAAgC,CACE,WAAW,EAAE,MAAM,EAAE,EACzB,SAAS,EAAE,MAAM,EAC1C,OAAO,EAAE,UAAU,GAC3B,OAAO,CAAC,4BAA4B,CAAC;CAkC3C"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
import { Arg, Ctx, Field, ObjectType, Query, Resolver } from 'type-graphql';
|
|
14
|
+
import { LogError } from '@memberjunction/core';
|
|
15
|
+
import { ResolverBase } from '../generic/ResolverBase.js';
|
|
16
|
+
import { RequireSystemUser } from '../directives/RequireSystemUser.js';
|
|
17
|
+
import { GetReadOnlyProvider } from '../util.js';
|
|
18
|
+
import { UserCache } from '@memberjunction/sqlserver-dataprovider';
|
|
19
|
+
let EntityPermissionResult = class EntityPermissionResult {
|
|
20
|
+
};
|
|
21
|
+
__decorate([
|
|
22
|
+
Field(() => String),
|
|
23
|
+
__metadata("design:type", String)
|
|
24
|
+
], EntityPermissionResult.prototype, "EntityName", void 0);
|
|
25
|
+
__decorate([
|
|
26
|
+
Field(() => Boolean),
|
|
27
|
+
__metadata("design:type", Boolean)
|
|
28
|
+
], EntityPermissionResult.prototype, "CanRead", void 0);
|
|
29
|
+
EntityPermissionResult = __decorate([
|
|
30
|
+
ObjectType()
|
|
31
|
+
], EntityPermissionResult);
|
|
32
|
+
let CheckEntityPermissionsResult = class CheckEntityPermissionsResult {
|
|
33
|
+
};
|
|
34
|
+
__decorate([
|
|
35
|
+
Field(() => Boolean),
|
|
36
|
+
__metadata("design:type", Boolean)
|
|
37
|
+
], CheckEntityPermissionsResult.prototype, "Success", void 0);
|
|
38
|
+
__decorate([
|
|
39
|
+
Field(() => [EntityPermissionResult]),
|
|
40
|
+
__metadata("design:type", Array)
|
|
41
|
+
], CheckEntityPermissionsResult.prototype, "Results", void 0);
|
|
42
|
+
__decorate([
|
|
43
|
+
Field(() => String, { nullable: true }),
|
|
44
|
+
__metadata("design:type", String)
|
|
45
|
+
], CheckEntityPermissionsResult.prototype, "ErrorMessage", void 0);
|
|
46
|
+
CheckEntityPermissionsResult = __decorate([
|
|
47
|
+
ObjectType()
|
|
48
|
+
], CheckEntityPermissionsResult);
|
|
49
|
+
let EntityPermissionResolver = class EntityPermissionResolver extends ResolverBase {
|
|
50
|
+
async CheckEntityPermissionsSystemUser(entityNames, userEmail, context) {
|
|
51
|
+
try {
|
|
52
|
+
const user = UserCache.Instance.Users.find(u => u.Email.toLowerCase().trim() === userEmail.toLowerCase().trim());
|
|
53
|
+
if (!user) {
|
|
54
|
+
return { Success: false, Results: [], ErrorMessage: `User not found: ${userEmail}` };
|
|
55
|
+
}
|
|
56
|
+
// Use the per-request provider (not the global default) so entity metadata + permission
|
|
57
|
+
// evaluation resolve against the connection servicing THIS request.
|
|
58
|
+
const md = GetReadOnlyProvider(context.providers, { allowFallbackToReadWrite: true });
|
|
59
|
+
const results = [];
|
|
60
|
+
for (const name of entityNames) {
|
|
61
|
+
const entityInfo = md.EntityByName(name);
|
|
62
|
+
if (!entityInfo) {
|
|
63
|
+
results.push({ EntityName: name, CanRead: false });
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const perms = entityInfo.GetUserPermisions(user);
|
|
67
|
+
results.push({ EntityName: name, CanRead: perms?.CanRead ?? false });
|
|
68
|
+
}
|
|
69
|
+
return { Success: true, Results: results };
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
LogError(err);
|
|
73
|
+
return {
|
|
74
|
+
Success: false,
|
|
75
|
+
Results: [],
|
|
76
|
+
ErrorMessage: `EntityPermissionResolver::CheckEntityPermissionsSystemUser --- ${err instanceof Error ? err.message : String(err)}`
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
__decorate([
|
|
82
|
+
RequireSystemUser(),
|
|
83
|
+
Query(() => CheckEntityPermissionsResult),
|
|
84
|
+
__param(0, Arg('EntityNames', () => [String])),
|
|
85
|
+
__param(1, Arg('UserEmail', () => String)),
|
|
86
|
+
__param(2, Ctx()),
|
|
87
|
+
__metadata("design:type", Function),
|
|
88
|
+
__metadata("design:paramtypes", [Array, String, Object]),
|
|
89
|
+
__metadata("design:returntype", Promise)
|
|
90
|
+
], EntityPermissionResolver.prototype, "CheckEntityPermissionsSystemUser", null);
|
|
91
|
+
EntityPermissionResolver = __decorate([
|
|
92
|
+
Resolver()
|
|
93
|
+
], EntityPermissionResolver);
|
|
94
|
+
export { EntityPermissionResolver };
|
|
95
|
+
//# sourceMappingURL=EntityPermissionResolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EntityPermissionResolver.js","sourceRoot":"","sources":["../../src/resolvers/EntityPermissionResolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ResolverBase } from '../generic/ResolverBase.js';
|
|
2
|
+
import { AppContext } from '../types.js';
|
|
3
|
+
/** Input for the generic Remote Operation transport mutation. */
|
|
4
|
+
export declare class ExecuteRemoteOperationInput {
|
|
5
|
+
operationKey: string;
|
|
6
|
+
inputJSON: string;
|
|
7
|
+
invokeMode: string;
|
|
8
|
+
}
|
|
9
|
+
/** Result of the generic Remote Operation transport mutation. */
|
|
10
|
+
export declare class ExecuteRemoteOperationResultType {
|
|
11
|
+
success: boolean;
|
|
12
|
+
resultCode?: string;
|
|
13
|
+
outputJSON?: string;
|
|
14
|
+
handle?: string;
|
|
15
|
+
errorMessage?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The single generic server entry point for Remote Operations. Resolves the operation by key,
|
|
19
|
+
* applies the framework authorization gates (API-key scope, system-user, then the operation's own
|
|
20
|
+
* `Authorize`), and routes the operation through the per-request provider — which executes it
|
|
21
|
+
* in-process. Only registered, active operations are reachable, so the public `RouteOperation`
|
|
22
|
+
* power-tool is safe by construction.
|
|
23
|
+
*/
|
|
24
|
+
export declare class ExecuteRemoteOperationResolver extends ResolverBase {
|
|
25
|
+
ExecuteRemoteOperation(input: ExecuteRemoteOperationInput, ctx: AppContext): Promise<ExecuteRemoteOperationResultType>;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=ExecuteRemoteOperationResolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExecuteRemoteOperationResolver.d.ts","sourceRoot":"","sources":["../../src/resolvers/ExecuteRemoteOperationResolver.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,iEAAiE;AACjE,qBACa,2BAA2B;IAEpC,YAAY,EAAE,MAAM,CAAC;IAGrB,SAAS,EAAE,MAAM,CAAC;IAGlB,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,iEAAiE;AACjE,qBACa,gCAAgC;IAEzC,OAAO,EAAE,OAAO,CAAC;IAGjB,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAGhB,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;GAMG;AACH,qBACa,8BAA+B,SAAQ,YAAY;IAEtD,sBAAsB,CACV,KAAK,EAAE,2BAA2B,EACzC,GAAG,EAAE,UAAU,GACvB,OAAO,CAAC,gCAAgC,CAAC;CAkD/C"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
import { Arg, Ctx, Field, InputType, Mutation, ObjectType, Resolver } from 'type-graphql';
|
|
14
|
+
import { MJGlobal } from '@memberjunction/global';
|
|
15
|
+
import { BaseRemotableOperation } from '@memberjunction/core';
|
|
16
|
+
import { ResolverBase } from '../generic/ResolverBase.js';
|
|
17
|
+
import { GetReadWriteProvider } from '../util.js';
|
|
18
|
+
/** Input for the generic Remote Operation transport mutation. */
|
|
19
|
+
let ExecuteRemoteOperationInput = class ExecuteRemoteOperationInput {
|
|
20
|
+
};
|
|
21
|
+
__decorate([
|
|
22
|
+
Field(),
|
|
23
|
+
__metadata("design:type", String)
|
|
24
|
+
], ExecuteRemoteOperationInput.prototype, "operationKey", void 0);
|
|
25
|
+
__decorate([
|
|
26
|
+
Field(),
|
|
27
|
+
__metadata("design:type", String)
|
|
28
|
+
], ExecuteRemoteOperationInput.prototype, "inputJSON", void 0);
|
|
29
|
+
__decorate([
|
|
30
|
+
Field(),
|
|
31
|
+
__metadata("design:type", String)
|
|
32
|
+
], ExecuteRemoteOperationInput.prototype, "invokeMode", void 0);
|
|
33
|
+
ExecuteRemoteOperationInput = __decorate([
|
|
34
|
+
InputType()
|
|
35
|
+
], ExecuteRemoteOperationInput);
|
|
36
|
+
export { ExecuteRemoteOperationInput };
|
|
37
|
+
/** Result of the generic Remote Operation transport mutation. */
|
|
38
|
+
let ExecuteRemoteOperationResultType = class ExecuteRemoteOperationResultType {
|
|
39
|
+
};
|
|
40
|
+
__decorate([
|
|
41
|
+
Field(() => Boolean),
|
|
42
|
+
__metadata("design:type", Boolean)
|
|
43
|
+
], ExecuteRemoteOperationResultType.prototype, "success", void 0);
|
|
44
|
+
__decorate([
|
|
45
|
+
Field(() => String, { nullable: true }),
|
|
46
|
+
__metadata("design:type", String)
|
|
47
|
+
], ExecuteRemoteOperationResultType.prototype, "resultCode", void 0);
|
|
48
|
+
__decorate([
|
|
49
|
+
Field(() => String, { nullable: true }),
|
|
50
|
+
__metadata("design:type", String)
|
|
51
|
+
], ExecuteRemoteOperationResultType.prototype, "outputJSON", void 0);
|
|
52
|
+
__decorate([
|
|
53
|
+
Field(() => String, { nullable: true }),
|
|
54
|
+
__metadata("design:type", String)
|
|
55
|
+
], ExecuteRemoteOperationResultType.prototype, "handle", void 0);
|
|
56
|
+
__decorate([
|
|
57
|
+
Field(() => String, { nullable: true }),
|
|
58
|
+
__metadata("design:type", String)
|
|
59
|
+
], ExecuteRemoteOperationResultType.prototype, "errorMessage", void 0);
|
|
60
|
+
ExecuteRemoteOperationResultType = __decorate([
|
|
61
|
+
ObjectType()
|
|
62
|
+
], ExecuteRemoteOperationResultType);
|
|
63
|
+
export { ExecuteRemoteOperationResultType };
|
|
64
|
+
/**
|
|
65
|
+
* The single generic server entry point for Remote Operations. Resolves the operation by key,
|
|
66
|
+
* applies the framework authorization gates (API-key scope, system-user, then the operation's own
|
|
67
|
+
* `Authorize`), and routes the operation through the per-request provider — which executes it
|
|
68
|
+
* in-process. Only registered, active operations are reachable, so the public `RouteOperation`
|
|
69
|
+
* power-tool is safe by construction.
|
|
70
|
+
*/
|
|
71
|
+
let ExecuteRemoteOperationResolver = class ExecuteRemoteOperationResolver extends ResolverBase {
|
|
72
|
+
async ExecuteRemoteOperation(input, ctx) {
|
|
73
|
+
try {
|
|
74
|
+
const key = input.operationKey?.trim();
|
|
75
|
+
if (!key) {
|
|
76
|
+
return fail('INVALID_OPERATION_KEY', 'operationKey is required');
|
|
77
|
+
}
|
|
78
|
+
// Resolve the operation's declaration so we can apply its scope / system-user gates.
|
|
79
|
+
const registration = MJGlobal.Instance.ClassFactory.GetRegistration(BaseRemotableOperation, key);
|
|
80
|
+
if (!registration) {
|
|
81
|
+
return fail('UNKNOWN_OPERATION', `Remote operation '${key}' is not registered`);
|
|
82
|
+
}
|
|
83
|
+
const opDecl = MJGlobal.Instance.ClassFactory.CreateInstance(BaseRemotableOperation, key);
|
|
84
|
+
// (1) API-key scope gate — a no-op for interactive OAuth/JWT users.
|
|
85
|
+
if (opDecl?.RequiredScope) {
|
|
86
|
+
await this.CheckAPIKeyScopeAuthorization(opDecl.RequiredScope, key, ctx.userPayload);
|
|
87
|
+
}
|
|
88
|
+
// (2) System-user gate.
|
|
89
|
+
if (opDecl?.RequiresSystemUser && !ctx.userPayload.isSystemUser) {
|
|
90
|
+
return fail('FORBIDDEN', `Operation '${key}' may only be invoked by the system user`);
|
|
91
|
+
}
|
|
92
|
+
// (3) Resolve the acting user (works for OAuth/JWT and API-key sessions alike).
|
|
93
|
+
const user = this.GetUserFromPayload(ctx.userPayload);
|
|
94
|
+
if (!user) {
|
|
95
|
+
return fail('NO_USER', 'Not authenticated');
|
|
96
|
+
}
|
|
97
|
+
let parsedInput;
|
|
98
|
+
try {
|
|
99
|
+
parsedInput = input.inputJSON ? JSON.parse(input.inputJSON) : {};
|
|
100
|
+
}
|
|
101
|
+
catch (e) {
|
|
102
|
+
return fail('INVALID_INPUT_JSON', `Invalid input JSON: ${e instanceof Error ? e.message : String(e)}`);
|
|
103
|
+
}
|
|
104
|
+
// Route through the per-request provider (server in-process path; runs the op's Authorize + InternalExecute).
|
|
105
|
+
const provider = GetReadWriteProvider(ctx.providers);
|
|
106
|
+
const result = await provider.RouteOperation(key, parsedInput, { user, mode: input.invokeMode });
|
|
107
|
+
return {
|
|
108
|
+
success: result.Success,
|
|
109
|
+
resultCode: result.ResultCode,
|
|
110
|
+
outputJSON: result.Output !== undefined ? JSON.stringify(result.Output) : undefined,
|
|
111
|
+
handle: result.Handle,
|
|
112
|
+
errorMessage: result.ErrorMessage,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
catch (e) {
|
|
116
|
+
return fail('ERROR', e instanceof Error ? e.message : String(e));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
__decorate([
|
|
121
|
+
Mutation(() => ExecuteRemoteOperationResultType),
|
|
122
|
+
__param(0, Arg('input')),
|
|
123
|
+
__param(1, Ctx()),
|
|
124
|
+
__metadata("design:type", Function),
|
|
125
|
+
__metadata("design:paramtypes", [ExecuteRemoteOperationInput, Object]),
|
|
126
|
+
__metadata("design:returntype", Promise)
|
|
127
|
+
], ExecuteRemoteOperationResolver.prototype, "ExecuteRemoteOperation", null);
|
|
128
|
+
ExecuteRemoteOperationResolver = __decorate([
|
|
129
|
+
Resolver()
|
|
130
|
+
], ExecuteRemoteOperationResolver);
|
|
131
|
+
export { ExecuteRemoteOperationResolver };
|
|
132
|
+
/** Builds a failed result. */
|
|
133
|
+
function fail(resultCode, errorMessage) {
|
|
134
|
+
return { success: false, resultCode, errorMessage };
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=ExecuteRemoteOperationResolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExecuteRemoteOperationResolver.js","sourceRoot":"","sources":["../../src/resolvers/ExecuteRemoteOperationResolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -300,6 +300,60 @@ declare class MutationResultOutput {
|
|
|
300
300
|
Success: boolean;
|
|
301
301
|
Message: string;
|
|
302
302
|
}
|
|
303
|
+
declare class IntegrationSyncConfigInput {
|
|
304
|
+
SyncConcurrency?: number;
|
|
305
|
+
MaxConcurrency?: number;
|
|
306
|
+
RateLimitTokensPerSec?: number;
|
|
307
|
+
RateLimitBurst?: number;
|
|
308
|
+
CrossLayerPipeline?: boolean;
|
|
309
|
+
PartitionReconcile?: boolean;
|
|
310
|
+
DiscoveryTimeBudgetMs?: number;
|
|
311
|
+
DiscoveryBatchSize?: number;
|
|
312
|
+
DiscoveryMaxRecords?: number;
|
|
313
|
+
DeactivateAbsent?: boolean;
|
|
314
|
+
}
|
|
315
|
+
declare class IntegrationSyncConfigOutput {
|
|
316
|
+
Success: boolean;
|
|
317
|
+
Message: string;
|
|
318
|
+
SyncConcurrency?: number;
|
|
319
|
+
MaxConcurrency?: number;
|
|
320
|
+
RateLimitTokensPerSec?: number;
|
|
321
|
+
RateLimitBurst?: number;
|
|
322
|
+
CrossLayerPipeline?: boolean;
|
|
323
|
+
PartitionReconcile?: boolean;
|
|
324
|
+
DiscoveryTimeBudgetMs?: number;
|
|
325
|
+
DiscoveryBatchSize?: number;
|
|
326
|
+
DiscoveryMaxRecords?: number;
|
|
327
|
+
DeactivateAbsent?: boolean;
|
|
328
|
+
}
|
|
329
|
+
declare class CustomColumnCandidate {
|
|
330
|
+
EntityName: string;
|
|
331
|
+
/** The source field key as captured in the overflow column. */
|
|
332
|
+
SourceKey: string;
|
|
333
|
+
/** The sanitized, collision-resolved column name that would be created. */
|
|
334
|
+
ColumnName: string;
|
|
335
|
+
/** Inferred schema-field type family ('string' | 'number' | 'boolean' | 'datetime'). */
|
|
336
|
+
InferredType: string;
|
|
337
|
+
/** true = the real column does not exist yet (ADD COLUMN); false = recovery (column exists, mapping missing). */
|
|
338
|
+
NeedsColumn: boolean;
|
|
339
|
+
}
|
|
340
|
+
declare class CustomColumnCandidatesOutput {
|
|
341
|
+
Success: boolean;
|
|
342
|
+
Message: string;
|
|
343
|
+
Candidates: CustomColumnCandidate[];
|
|
344
|
+
}
|
|
345
|
+
declare class PromotedColumn {
|
|
346
|
+
EntityName: string;
|
|
347
|
+
ColumnName: string;
|
|
348
|
+
}
|
|
349
|
+
declare class PromoteCustomColumnsOutput {
|
|
350
|
+
Success: boolean;
|
|
351
|
+
Message: string;
|
|
352
|
+
Promoted: boolean;
|
|
353
|
+
ColumnsAdded: PromotedColumn[];
|
|
354
|
+
/** true when an RSU schema change ran (a server restart may be pending to expose the new columns). */
|
|
355
|
+
SchemaUpdatePending: boolean;
|
|
356
|
+
}
|
|
303
357
|
declare class FieldMapInput {
|
|
304
358
|
SourceFieldName: string;
|
|
305
359
|
DestinationFieldName: string;
|
|
@@ -345,6 +399,10 @@ declare class CreateScheduleInput {
|
|
|
345
399
|
Description?: string;
|
|
346
400
|
SyncDirection?: string;
|
|
347
401
|
FullSync?: boolean;
|
|
402
|
+
/** §13 — 'sync' (default; moves data via RunSync) or 'discovery' (schema-only RefreshConnectorSchema on cron, evolving the IO/IOF catalog — no RSU, no data sync). */
|
|
403
|
+
JobKind?: string;
|
|
404
|
+
/** Discovery-job only: deactivate objects/fields absent from an authoritative refresh (reversible). Default true. */
|
|
405
|
+
DeactivateAbsent?: boolean;
|
|
348
406
|
}
|
|
349
407
|
declare class CreateScheduleOutput {
|
|
350
408
|
Success: boolean;
|
|
@@ -598,7 +656,7 @@ export declare class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
598
656
|
* both on stdout (visible in the MJAPI log file) and in a per-run
|
|
599
657
|
* `<cwd>/logs/integration-runs/<runID>/progress.jsonl` artifact.
|
|
600
658
|
*/
|
|
601
|
-
IntegrationRefreshConnectorSchema(companyIntegrationID: string, universalPKConvention: string | undefined, ctx: AppContext): Promise<RefreshConnectorSchemaOutput>;
|
|
659
|
+
IntegrationRefreshConnectorSchema(companyIntegrationID: string, universalPKConvention: string | undefined, deactivateAbsent: boolean | undefined, ctx: AppContext): Promise<RefreshConnectorSchemaOutput>;
|
|
602
660
|
/**
|
|
603
661
|
* Generates + persists strongly-typed Action metadata on demand for an
|
|
604
662
|
* integration object. When `verb` is supplied, a single Action is generated
|
|
@@ -838,6 +896,37 @@ export declare class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
838
896
|
* Updates credential values and/or configuration on an existing CompanyIntegration.
|
|
839
897
|
*/
|
|
840
898
|
IntegrationUpdateConnection(companyIntegrationID: string, credentialValues: string, configuration: string, externalSystemID: string, testConnection: boolean, runSchemaRefresh: boolean, universalPKConvention: string | undefined, ctx: AppContext): Promise<MutationResultOutput>;
|
|
899
|
+
/**
|
|
900
|
+
* Sets the per-connection sync tuning (rate limit, concurrency, time budget, pipeline flags) as
|
|
901
|
+
* STRUCTURED typed fields, merged into CompanyIntegration.Configuration (other keys preserved).
|
|
902
|
+
* These are the exact keys the IntegrationEngine reads at runtime, so they become customizable
|
|
903
|
+
* via the API instead of hidden code constants. Returns the merged config typed.
|
|
904
|
+
*/
|
|
905
|
+
IntegrationSetSyncConfig(companyIntegrationID: string, config: IntegrationSyncConfigInput, ctx: AppContext): Promise<IntegrationSyncConfigOutput>;
|
|
906
|
+
/** Reads the per-connection sync tuning back as STRUCTURED typed fields. */
|
|
907
|
+
IntegrationGetSyncConfig(companyIntegrationID: string, ctx: AppContext): Promise<IntegrationSyncConfigOutput>;
|
|
908
|
+
/** Reads a single boolean key from a CompanyIntegration.Configuration JSON string (undefined if absent/malformed). */
|
|
909
|
+
private readConfigBool;
|
|
910
|
+
/** Extracts the typed sync-config fields from a parsed Configuration object (type-guarded). */
|
|
911
|
+
private readSyncConfig;
|
|
912
|
+
/** The MJ entity names this connection has entity maps for (for whole-connection scope). */
|
|
913
|
+
private getMappedEntityNames;
|
|
914
|
+
/**
|
|
915
|
+
* Lists the custom-column CANDIDATES captured in the overflow column awaiting promotion — the "new
|
|
916
|
+
* columns found" for a connection. READ-ONLY (no schema change, no RSU). Scope to one entity via
|
|
917
|
+
* entityName, or omit to list across all the connection's mapped entities. Computed live (overflow keys
|
|
918
|
+
* minus already-mapped/already-a-column), so it is inherently deduped against anything a concurrent
|
|
919
|
+
* discovery already promoted.
|
|
920
|
+
*/
|
|
921
|
+
IntegrationListCustomColumnCandidates(companyIntegrationID: string, entityName: string | undefined, ctx: AppContext): Promise<CustomColumnCandidatesOutput>;
|
|
922
|
+
/**
|
|
923
|
+
* On-demand promotion of captured custom columns: runs RSU (ADD COLUMN + register EntityField + field map),
|
|
924
|
+
* which may require a server restart to expose them over GraphQL. This is the USER-ACCEPTED trigger — by
|
|
925
|
+
* default a sync only CAPTURES to the overflow column (auto-promote is opt-in per connection via
|
|
926
|
+
* Configuration.autoPromoteCustomColumns). Scope via entityNames, or omit to promote across all mapped
|
|
927
|
+
* entities. Idempotent: already-promoted/mapped keys are skipped (safe to re-run / run alongside discovery).
|
|
928
|
+
*/
|
|
929
|
+
IntegrationPromoteCustomColumns(companyIntegrationID: string, entityNames: string[] | undefined, ctx: AppContext): Promise<PromoteCustomColumnsOutput>;
|
|
841
930
|
/**
|
|
842
931
|
* Soft-deletes a CompanyIntegration by setting IsActive=false.
|
|
843
932
|
*/
|
|
@@ -895,6 +984,17 @@ export declare class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
895
984
|
* Build schema artifacts for a single connector's objects.
|
|
896
985
|
* Shared by IntegrationApplySchema (single) and IntegrationApplySchemaBatch (batch).
|
|
897
986
|
*/
|
|
987
|
+
/**
|
|
988
|
+
* §B — enforce OPTIONAL table/column caps at the create-tables (RSU) gate. These are OPERATOR
|
|
989
|
+
* (deployment) guardrails read from ENV — `MJ_INTEGRATION_MAX_TABLES` / `MJ_INTEGRATION_MAX_COLUMNS_PER_TABLE`
|
|
990
|
+
* (absent or ≤0 = unbounded, the common case). They are DELIBERATELY env-only, NOT per-connection
|
|
991
|
+
* `Configuration`/GraphQL: a guardrail a user can raise via the same API they apply with is toothless.
|
|
992
|
+
* THROWS a clear error when the selection exceeds a cap so NOTHING partial is created — the caller surfaces
|
|
993
|
+
* it and the user narrows the selection (the cap itself is an operator concern). NEVER truncates. Discovery
|
|
994
|
+
* still surfaces every object/field; only materialization is capped. Per-table column count = the selected
|
|
995
|
+
* field subset, or the object's full discovered field count when all fields are selected.
|
|
996
|
+
*/
|
|
997
|
+
private enforceSchemaLimits;
|
|
898
998
|
private buildSchemaForConnector;
|
|
899
999
|
/**
|
|
900
1000
|
* Starts an async integration sync. Returns immediately with the run ID.
|