@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
- operationInput: {
49
- soqlQuery: 'SELECT Id, Name FROM Account',
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: 'https://trigger.example.test/tab-123',
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: 'https://trigger.example.test/tab-123',
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 four ctx fields; auth / org / workspace / project absent.
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,EAAE,mBAAmB,EAAE,MAAM,kDAAkD,CAAC;AAEvF,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;AAsEF,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,CAkDhB"}
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: registerCtx.publicUrl,
151
+ publicUrl,
121
152
  pollingInterval: pollingInput.pollingInterval,
122
153
  maxFailureCount: pollingInput.maxFailureCount,
123
154
  initialCursor: pollingInput.initialCursor,
124
- operationInput: pollingInput.operationInput,
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: destroyCtx.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.24.0",
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.24.0",
18
- "@trayio/cdk-dsl": "5.24.0",
19
- "@trayio/express": "5.24.0",
20
- "@trayio/winston": "5.24.0",
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
  },