@trayio/cdk-runtime 5.24.0 → 5.25.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.
|
@@ -15,11 +15,15 @@ const fakePollingContext = () => ({
|
|
|
15
15
|
connectorName: 'salesforce',
|
|
16
16
|
connectorVersion: '7.2.0',
|
|
17
17
|
executionToken: 'exec-jwt',
|
|
18
|
-
publicUrl: 'https://trigger.example.test/tab-123',
|
|
19
18
|
organizationId: 'org-uuid',
|
|
20
19
|
workspaceId: 'ws-uuid',
|
|
21
20
|
projectId: '7fa00000-1111-2222-3333-444455556666',
|
|
22
21
|
});
|
|
22
|
+
const PUBLIC_URL = 'https://trigger.example.test/tab-123';
|
|
23
|
+
const fakePollingInput = (overrides = {}) => ({
|
|
24
|
+
publicUrl: PUBLIC_URL,
|
|
25
|
+
...overrides,
|
|
26
|
+
});
|
|
23
27
|
const createFakePollingServiceClient = () => {
|
|
24
28
|
const registerCalls = [];
|
|
25
29
|
const deregisterCalls = [];
|
|
@@ -42,13 +46,12 @@ describe('CompositeOperationExecution polling lifecycle branch', () => {
|
|
|
42
46
|
const handler = new CompositeOperationHandler_1.CompositeOperationHandler(handlerFunction);
|
|
43
47
|
const execution = new CompositeOperationExecution_1.CompositeOperationExecution(noopHandlerInvocationFactory, handler, OperationHandler_1.OperationHandlerType.TriggerPollCreate, 'new_records', client);
|
|
44
48
|
const input = {
|
|
49
|
+
publicUrl: PUBLIC_URL,
|
|
45
50
|
pollingInterval: { value: 15, unit: PollingTypes_1.PollingIntervalUnit.Minutes },
|
|
46
51
|
maxFailureCount: 50,
|
|
47
52
|
initialCursor: { since: 't0' },
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
objectType: 'Account',
|
|
51
|
-
},
|
|
53
|
+
soqlQuery: 'SELECT Id, Name FROM Account',
|
|
54
|
+
objectType: 'Account',
|
|
52
55
|
};
|
|
53
56
|
const result = await execution.execute(fakePollingContext(), input);
|
|
54
57
|
expect(result.isSuccess).toBe(true);
|
|
@@ -63,7 +66,7 @@ describe('CompositeOperationExecution polling lifecycle branch', () => {
|
|
|
63
66
|
organizationId: 'org-uuid',
|
|
64
67
|
workspaceId: 'ws-uuid',
|
|
65
68
|
projectId: '7fa00000-1111-2222-3333-444455556666',
|
|
66
|
-
publicUrl:
|
|
69
|
+
publicUrl: PUBLIC_URL,
|
|
67
70
|
pollingInterval: {
|
|
68
71
|
value: 15,
|
|
69
72
|
unit: PollingTypes_1.PollingIntervalUnit.Minutes,
|
|
@@ -82,7 +85,7 @@ describe('CompositeOperationExecution polling lifecycle branch', () => {
|
|
|
82
85
|
const handlerFunction = jest.fn();
|
|
83
86
|
const handler = new CompositeOperationHandler_1.CompositeOperationHandler(handlerFunction);
|
|
84
87
|
const execution = new CompositeOperationExecution_1.CompositeOperationExecution(noopHandlerInvocationFactory, handler, OperationHandler_1.OperationHandlerType.TriggerPollDestroy, 'new_records_destroy', client);
|
|
85
|
-
const result = await execution.execute(fakePollingContext(),
|
|
88
|
+
const result = await execution.execute(fakePollingContext(), fakePollingInput());
|
|
86
89
|
expect(result.isSuccess).toBe(true);
|
|
87
90
|
expect(handlerFunction).not.toHaveBeenCalled();
|
|
88
91
|
expect(deregisterCalls).toHaveLength(1);
|
|
@@ -91,7 +94,7 @@ describe('CompositeOperationExecution polling lifecycle branch', () => {
|
|
|
91
94
|
connectorName: 'salesforce',
|
|
92
95
|
connectorVersion: '7.2.0',
|
|
93
96
|
registeredHandlerName: 'new_records_destroy',
|
|
94
|
-
publicUrl:
|
|
97
|
+
publicUrl: PUBLIC_URL,
|
|
95
98
|
preserveCursor: true,
|
|
96
99
|
});
|
|
97
100
|
expect(token).toBe('exec-jwt');
|
|
@@ -107,7 +110,6 @@ describe('CompositeOperationExecution polling lifecycle branch', () => {
|
|
|
107
110
|
expect(error).toMatch(/ctx\.connectorName/);
|
|
108
111
|
expect(error).toMatch(/ctx\.connectorVersion/);
|
|
109
112
|
expect(error).toMatch(/ctx\.executionToken/);
|
|
110
|
-
expect(error).toMatch(/ctx\.publicUrl/);
|
|
111
113
|
});
|
|
112
114
|
it('fails register when org/workspace/project ctx fields are missing (auth is optional)', async () => {
|
|
113
115
|
const { client, registerCalls } = createFakePollingServiceClient();
|
|
@@ -120,7 +122,6 @@ describe('CompositeOperationExecution polling lifecycle branch', () => {
|
|
|
120
122
|
connectorName: 'x',
|
|
121
123
|
connectorVersion: '1',
|
|
122
124
|
executionToken: 'tok',
|
|
123
|
-
publicUrl: 'u',
|
|
124
125
|
};
|
|
125
126
|
const result = await execution.execute(incompleteCtx, {});
|
|
126
127
|
expect(registerCalls).toHaveLength(0);
|
|
@@ -135,17 +136,59 @@ describe('CompositeOperationExecution polling lifecycle branch', () => {
|
|
|
135
136
|
const { client, deregisterCalls } = createFakePollingServiceClient();
|
|
136
137
|
const handler = new CompositeOperationHandler_1.CompositeOperationHandler(jest.fn());
|
|
137
138
|
const execution = new CompositeOperationExecution_1.CompositeOperationExecution(noopHandlerInvocationFactory, handler, OperationHandler_1.OperationHandlerType.TriggerPollDestroy, 'new_records_destroy', client);
|
|
138
|
-
// Only the base
|
|
139
|
+
// Only the base three ctx fields; auth / org / workspace / project absent.
|
|
139
140
|
const destroyOnlyCtx = {
|
|
140
141
|
connectorName: 'x',
|
|
141
142
|
connectorVersion: '1',
|
|
142
143
|
executionToken: 'tok',
|
|
143
|
-
publicUrl: 'u',
|
|
144
144
|
};
|
|
145
|
-
const result = await execution.execute(destroyOnlyCtx,
|
|
145
|
+
const result = await execution.execute(destroyOnlyCtx, fakePollingInput());
|
|
146
146
|
expect(result.isSuccess).toBe(true);
|
|
147
147
|
expect(deregisterCalls).toHaveLength(1);
|
|
148
148
|
});
|
|
149
|
+
it('passes connector-defined input fields through to PS as operationInput, stripping platform fields', async () => {
|
|
150
|
+
const { client, registerCalls } = createFakePollingServiceClient();
|
|
151
|
+
const handler = new CompositeOperationHandler_1.CompositeOperationHandler(jest.fn());
|
|
152
|
+
const execution = new CompositeOperationExecution_1.CompositeOperationExecution(noopHandlerInvocationFactory, handler, OperationHandler_1.OperationHandlerType.TriggerPollCreate, 'new_records', client);
|
|
153
|
+
const input = {
|
|
154
|
+
publicUrl: PUBLIC_URL,
|
|
155
|
+
pollingInterval: { value: 5, unit: PollingTypes_1.PollingIntervalUnit.Minutes },
|
|
156
|
+
maxFailureCount: 10,
|
|
157
|
+
initialCursor: 'cur-1',
|
|
158
|
+
soqlQuery: 'SELECT Id FROM Account',
|
|
159
|
+
objectType: 'Account',
|
|
160
|
+
nested: { folderId: 'fld_1', tags: ['a', 'b'] },
|
|
161
|
+
};
|
|
162
|
+
const result = await execution.execute(fakePollingContext(), input);
|
|
163
|
+
expect(result.isSuccess).toBe(true);
|
|
164
|
+
expect(registerCalls).toHaveLength(1);
|
|
165
|
+
const [payload] = registerCalls[0];
|
|
166
|
+
expect(payload.operationInput).toEqual({
|
|
167
|
+
soqlQuery: 'SELECT Id FROM Account',
|
|
168
|
+
objectType: 'Account',
|
|
169
|
+
nested: { folderId: 'fld_1', tags: ['a', 'b'] },
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
it('fails register when input.publicUrl is missing', async () => {
|
|
173
|
+
const { client, registerCalls } = createFakePollingServiceClient();
|
|
174
|
+
const handler = new CompositeOperationHandler_1.CompositeOperationHandler(jest.fn());
|
|
175
|
+
const execution = new CompositeOperationExecution_1.CompositeOperationExecution(noopHandlerInvocationFactory, handler, OperationHandler_1.OperationHandlerType.TriggerPollCreate, 'new_records', client);
|
|
176
|
+
const result = await execution.execute(fakePollingContext(), {});
|
|
177
|
+
expect(registerCalls).toHaveLength(0);
|
|
178
|
+
expect(result.isFailure).toBe(true);
|
|
179
|
+
const error = result._tag === 'Failure' ? result.error.message : '';
|
|
180
|
+
expect(error).toMatch(/input\.publicUrl/);
|
|
181
|
+
});
|
|
182
|
+
it('fails deregister when input.publicUrl is missing', async () => {
|
|
183
|
+
const { client, deregisterCalls } = createFakePollingServiceClient();
|
|
184
|
+
const handler = new CompositeOperationHandler_1.CompositeOperationHandler(jest.fn());
|
|
185
|
+
const execution = new CompositeOperationExecution_1.CompositeOperationExecution(noopHandlerInvocationFactory, handler, OperationHandler_1.OperationHandlerType.TriggerPollDestroy, 'new_records_destroy', client);
|
|
186
|
+
const result = await execution.execute(fakePollingContext(), {});
|
|
187
|
+
expect(deregisterCalls).toHaveLength(0);
|
|
188
|
+
expect(result.isFailure).toBe(true);
|
|
189
|
+
const error = result._tag === 'Failure' ? result.error.message : '';
|
|
190
|
+
expect(error).toMatch(/input\.publicUrl/);
|
|
191
|
+
});
|
|
149
192
|
it('maps a PollingServiceClient error into an OperationHandlerResult failure', async () => {
|
|
150
193
|
const client = {
|
|
151
194
|
register: jest.fn(() => Promise.reject(new Error('boom'))),
|
|
@@ -153,7 +196,7 @@ describe('CompositeOperationExecution polling lifecycle branch', () => {
|
|
|
153
196
|
};
|
|
154
197
|
const handler = new CompositeOperationHandler_1.CompositeOperationHandler(jest.fn());
|
|
155
198
|
const execution = new CompositeOperationExecution_1.CompositeOperationExecution(noopHandlerInvocationFactory, handler, OperationHandler_1.OperationHandlerType.TriggerPollCreate, 'new_records', client);
|
|
156
|
-
const result = await execution.execute(fakePollingContext(),
|
|
199
|
+
const result = await execution.execute(fakePollingContext(), fakePollingInput());
|
|
157
200
|
expect(result.isFailure).toBe(true);
|
|
158
201
|
const message = result._tag === 'Failure' ? result.error.message : '';
|
|
159
202
|
expect(message).toBe('boom');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CompositeOperationExecutionPolling.d.ts","sourceRoot":"","sources":["../../../src/connector/operation/CompositeOperationExecutionPolling.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,oBAAoB,EACpB,uBAAuB,EAEvB,sBAAsB,EAEtB,oBAAoB,EAEpB,MAAM,sDAAsD,CAAC;AAC9D,OAAO,EAAE,yBAAyB,EAAE,MAAM,+DAA+D,CAAC;AAC1G,OAAO,
|
|
1
|
+
{"version":3,"file":"CompositeOperationExecutionPolling.d.ts","sourceRoot":"","sources":["../../../src/connector/operation/CompositeOperationExecutionPolling.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,oBAAoB,EACpB,uBAAuB,EAEvB,sBAAsB,EAEtB,oBAAoB,EAEpB,MAAM,sDAAsD,CAAC;AAC9D,OAAO,EAAE,yBAAyB,EAAE,MAAM,+DAA+D,CAAC;AAC1G,OAAO,EAEN,mBAAmB,EACnB,MAAM,kDAAkD,CAAC;AAE1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,iCAAiC,EAAE,MAAM,qCAAqC,CAAC;AAExF,MAAM,MAAM,6BAA6B,GAAG,mBAAmB,GAAG;IACjE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,CAAC;AA4GF,eAAO,MAAM,kBAAkB,gBACjB,oBAAoB,KAC/B,OAEqD,CAAC;AAoCzD;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACxC,IAAI,SAAS,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,EACnD,EAAE,EACF,GAAG,EACF,IAAI,EAAE;IACP,GAAG,EAAE,uBAAuB,CAAC,IAAI,CAAC,CAAC;IACnC,KAAK,EAAE,EAAE,CAAC;IACV,OAAO,EAAE,yBAAyB,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;IAClD,wBAAwB,EAAE,iCAAiC,CAAC;IAC5D,yBAAyB,EAAE,CAAC,CAAC,EAAE,sBAAsB,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;IACpE,cAAc,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,sBAAsB,CAAC,GAAG,CAAC,CAAC;CAC5D,GAAG,OAAO,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC,CAiCvC;AAED,wBAAgB,8BAA8B,CAC7C,IAAI,SAAS,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,EAClD,IAAI,EAAE;IACP,GAAG,EAAE,uBAAuB,CAAC,IAAI,CAAC,CAAC;IACnC,WAAW,EACR,oBAAoB,CAAC,iBAAiB,GACtC,oBAAoB,CAAC,kBAAkB,CAAC;IAC3C,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,6BAA6B,CAAC;IAC5C,oBAAoB,EAAE,oBAAoB,CAAC;CAC3C,GAAG,OAAO,CAAC,IAAI,CAAC,CAoDhB"}
|
|
@@ -2,6 +2,33 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.runPollingRegisterOrDeregister = exports.runTriggerPollDedup = exports.isPollingLifecycle = void 0;
|
|
4
4
|
const OperationHandler_1 = require("@trayio/cdk-dsl/connector/operation/OperationHandler");
|
|
5
|
+
const PollingTypes_1 = require("@trayio/cdk-dsl/connector/operation/PollingTypes");
|
|
6
|
+
/**
|
|
7
|
+
* Field names on a polling trigger input that the runtime owns and must not
|
|
8
|
+
* leak into the `operationInput` blob forwarded to the Polling Service.
|
|
9
|
+
* Mirrors `PLATFORM_POLLING_INPUT_KEYS` from cdk-dsl plus the runtime-only
|
|
10
|
+
* `initialCursor` field that lives on `PollingTriggerInvocationInput`.
|
|
11
|
+
*/
|
|
12
|
+
const RUNTIME_POLLING_INPUT_KEYS = new Set([
|
|
13
|
+
...PollingTypes_1.PLATFORM_POLLING_INPUT_KEYS,
|
|
14
|
+
'initialCursor',
|
|
15
|
+
]);
|
|
16
|
+
/**
|
|
17
|
+
* Computes the `operationInput` blob the Polling Service persists for a poll
|
|
18
|
+
* subscription. Connector-specific config (e.g. SOQL query, object type) is
|
|
19
|
+
* authored as top-level fields on the connector's `IN extends
|
|
20
|
+
* PollingTriggerInput`; this strips the platform-managed keys so PS only
|
|
21
|
+
* sees the connector's own config.
|
|
22
|
+
*/
|
|
23
|
+
const extractOperationInput = (pollingInput) => {
|
|
24
|
+
const result = {};
|
|
25
|
+
for (const [key, value] of Object.entries(pollingInput)) {
|
|
26
|
+
if (!RUNTIME_POLLING_INPUT_KEYS.has(key)) {
|
|
27
|
+
result[key] = value;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return result;
|
|
31
|
+
};
|
|
5
32
|
const requirePollingCtxFields = (ctx) => {
|
|
6
33
|
const missing = [];
|
|
7
34
|
if (!ctx.connectorName)
|
|
@@ -10,8 +37,6 @@ const requirePollingCtxFields = (ctx) => {
|
|
|
10
37
|
missing.push('ctx.connectorVersion');
|
|
11
38
|
if (!ctx.executionToken)
|
|
12
39
|
missing.push('ctx.executionToken');
|
|
13
|
-
if (!ctx.publicUrl)
|
|
14
|
-
missing.push('ctx.publicUrl');
|
|
15
40
|
if (missing.length > 0) {
|
|
16
41
|
throw new Error(`polling lifecycle is missing required context fields: ${missing.join(', ')}`);
|
|
17
42
|
}
|
|
@@ -19,7 +44,6 @@ const requirePollingCtxFields = (ctx) => {
|
|
|
19
44
|
connectorName: ctx.connectorName,
|
|
20
45
|
connectorVersion: ctx.connectorVersion,
|
|
21
46
|
executionToken: ctx.executionToken,
|
|
22
|
-
publicUrl: ctx.publicUrl,
|
|
23
47
|
};
|
|
24
48
|
};
|
|
25
49
|
const requirePollingRegisterCtxFields = (ctx) => {
|
|
@@ -42,6 +66,12 @@ const requirePollingRegisterCtxFields = (ctx) => {
|
|
|
42
66
|
projectId: ctx.projectId,
|
|
43
67
|
};
|
|
44
68
|
};
|
|
69
|
+
const requirePollingPublicUrl = (pollingInput) => {
|
|
70
|
+
if (!pollingInput.publicUrl) {
|
|
71
|
+
throw new Error('polling lifecycle is missing required input field: input.publicUrl');
|
|
72
|
+
}
|
|
73
|
+
return pollingInput.publicUrl;
|
|
74
|
+
};
|
|
45
75
|
const isPollingLifecycle = (handlerType) => handlerType === OperationHandler_1.OperationHandlerType.TriggerPollCreate ||
|
|
46
76
|
handlerType === OperationHandler_1.OperationHandlerType.TriggerPollDestroy;
|
|
47
77
|
exports.isPollingLifecycle = isPollingLifecycle;
|
|
@@ -109,6 +139,7 @@ function runPollingRegisterOrDeregister(args) {
|
|
|
109
139
|
switch (handlerType) {
|
|
110
140
|
case OperationHandler_1.OperationHandlerType.TriggerPollCreate: {
|
|
111
141
|
const registerCtx = requirePollingRegisterCtxFields(ctx);
|
|
142
|
+
const publicUrl = requirePollingPublicUrl(pollingInput);
|
|
112
143
|
return pollingServiceClient.register({
|
|
113
144
|
connectorName: registerCtx.connectorName,
|
|
114
145
|
connectorVersion: registerCtx.connectorVersion,
|
|
@@ -117,20 +148,21 @@ function runPollingRegisterOrDeregister(args) {
|
|
|
117
148
|
organizationId: registerCtx.organizationId,
|
|
118
149
|
workspaceId: registerCtx.workspaceId,
|
|
119
150
|
projectId: registerCtx.projectId,
|
|
120
|
-
publicUrl
|
|
151
|
+
publicUrl,
|
|
121
152
|
pollingInterval: pollingInput.pollingInterval,
|
|
122
153
|
maxFailureCount: pollingInput.maxFailureCount,
|
|
123
154
|
initialCursor: pollingInput.initialCursor,
|
|
124
|
-
operationInput: pollingInput
|
|
155
|
+
operationInput: extractOperationInput(pollingInput),
|
|
125
156
|
}, registerCtx.executionToken);
|
|
126
157
|
}
|
|
127
158
|
case OperationHandler_1.OperationHandlerType.TriggerPollDestroy: {
|
|
128
159
|
const destroyCtx = requirePollingCtxFields(ctx);
|
|
160
|
+
const publicUrl = requirePollingPublicUrl(pollingInput);
|
|
129
161
|
return pollingServiceClient.deregister({
|
|
130
162
|
connectorName: destroyCtx.connectorName,
|
|
131
163
|
connectorVersion: destroyCtx.connectorVersion,
|
|
132
164
|
registeredHandlerName,
|
|
133
|
-
publicUrl
|
|
165
|
+
publicUrl,
|
|
134
166
|
preserveCursor: true,
|
|
135
167
|
}, destroyCtx.executionToken);
|
|
136
168
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trayio/cdk-runtime",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.25.0",
|
|
4
4
|
"description": "A Runtime that executes connector operations defined using the CDK DSL",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./*": "./dist/*.js"
|
|
@@ -14,10 +14,10 @@
|
|
|
14
14
|
"node": ">=18.x"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@trayio/axios": "5.
|
|
18
|
-
"@trayio/cdk-dsl": "5.
|
|
19
|
-
"@trayio/express": "5.
|
|
20
|
-
"@trayio/winston": "5.
|
|
17
|
+
"@trayio/axios": "5.25.0",
|
|
18
|
+
"@trayio/cdk-dsl": "5.25.0",
|
|
19
|
+
"@trayio/express": "5.25.0",
|
|
20
|
+
"@trayio/winston": "5.25.0",
|
|
21
21
|
"mime": "3.0.0",
|
|
22
22
|
"uuid": "9.0.0"
|
|
23
23
|
},
|