Skip to content

Commit b64cfec

Browse files
committed
follow requestFn
1 parent 514947e commit b64cfec

File tree

5 files changed

+135
-50
lines changed

5 files changed

+135
-50
lines changed

packages/core/src/destination-kit/__tests__/multi-async-action.test.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Action } from '../action'
2-
import { MultiAsyncOperationResponse, MultiPollResponse, MultiPollInput } from '../types'
2+
import { MultiAsyncOperationResponse, MultiPollResponse, MultiPollInput, ExecuteInput } from '../types'
33

44
describe('Multi Async Actions', () => {
55
it('should support multi async operations with performBatch returning MultiAsyncOperationResponse', async () => {
@@ -33,11 +33,14 @@ describe('Multi Async Actions', () => {
3333
message: 'Multiple async operations initiated'
3434
} as MultiAsyncOperationResponse
3535
},
36-
async pollMultiple(_request: any, data: MultiPollInput<unknown, unknown>) {
36+
async pollMultiple(
37+
_request: any,
38+
{ payload, stateContext }: ExecuteInput<unknown, MultiPollInput<unknown, unknown>>
39+
) {
3740
// Simulate polling multiple operations using context data
38-
const results = data.operationIds.map((operationId, index) => {
41+
const results = payload.operationIds.map((operationId: string, index: number) => {
3942
// Get context from stateContext instead of a non-existent contexts property
40-
const contextData = data.stateContext?.getRequestContext(`operation_${operationId}`)
43+
const contextData = stateContext?.getRequestContext(`operation_${operationId}`)
4144
const context = contextData && typeof contextData === 'string' ? JSON.parse(contextData) : {}
4245
const priority = context?.priority
4346
return {
@@ -54,7 +57,7 @@ describe('Multi Async Actions', () => {
5457
return {
5558
overallStatus: 'completed',
5659
results,
57-
payloadResults: results.map((r) => r.result)
60+
payloadResults: results.map((r: any) => r.result)
5861
} as MultiPollResponse
5962
}
6063
} as any)
@@ -116,15 +119,15 @@ describe('Multi Async Actions', () => {
116119
]
117120
} as MultiAsyncOperationResponse
118121
},
119-
async pollMultiple(_request: any, data: MultiPollInput<unknown, unknown>) {
122+
async pollMultiple(_request: any, { payload }: ExecuteInput<unknown, MultiPollInput<unknown, unknown>>) {
120123
return {
121124
overallStatus: 'completed',
122-
results: data.operationIds.map((id) => ({
125+
results: payload.operationIds.map((id: string) => ({
123126
operationId: id,
124127
status: 'completed' as const,
125128
result: { processed: true, operationId: id }
126129
})),
127-
payloadResults: data.operationIds.map((id) => ({ processed: true, operationId: id }))
130+
payloadResults: payload.operationIds.map((id: string) => ({ processed: true, operationId: id }))
128131
} as MultiPollResponse
129132
}
130133
} as any)

packages/core/src/destination-kit/action.ts

Lines changed: 24 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -153,31 +153,13 @@ export interface ActionDefinition<
153153
* The operation to poll for the status of an async operation initiated by performBatch.
154154
* This method is only required if performBatch returns AsyncOperationResponse.
155155
*/
156-
poll?: (
157-
request: RequestClient,
158-
data: PollInput<Settings, AudienceSettings>,
159-
context: {
160-
stateContext?: StateContext
161-
logger?: Logger
162-
features?: Features
163-
statsContext?: StatsContext
164-
}
165-
) => MaybePromise<PollResponse>
156+
poll?: RequestFn<Settings, PollInput<Settings, AudienceSettings>, PollResponse, AudienceSettings>
166157

167158
/**
168159
* The operation to poll for the status of multiple async operations initiated by performBatch.
169160
* This method is only required if performBatch returns MultiAsyncOperationResponse.
170161
*/
171-
pollMultiple?: (
172-
request: RequestClient,
173-
data: MultiPollInput<Settings, AudienceSettings>,
174-
context: {
175-
stateContext?: StateContext
176-
logger?: Logger
177-
features?: Features
178-
statsContext?: StatsContext
179-
}
180-
) => MaybePromise<PollResponse[]>
162+
pollMultiple?: RequestFn<Settings, MultiPollInput<Settings, AudienceSettings>, PollResponse[], AudienceSettings>
181163

182164
/** Hooks are triggered at some point in a mappings lifecycle. They may perform a request with the
183165
* destination using the provided inputs and return a response. The response may then optionally be stored
@@ -772,16 +754,21 @@ export class Action<Settings, Payload extends JSONLikeObject, AudienceSettings =
772754
// Create request client for the poll operation
773755
const requestClient = this.createPollRequestClient(pollInput)
774756

775-
// Extract context for poll method
776-
const context = {
777-
stateContext: pollInput.stateContext,
778-
logger: pollInput.logger,
757+
// Create ExecuteInput object matching RequestFn signature - payload is the poll input
758+
const data: ExecuteInput<Settings, PollInput<Settings, AudienceSettings>, AudienceSettings> = {
759+
mapping: {},
760+
settings: pollInput.settings,
761+
audienceSettings: pollInput.audienceSettings,
762+
payload: pollInput,
763+
auth: pollInput.auth,
779764
features: pollInput.features,
780-
statsContext: pollInput.statsContext
765+
statsContext: pollInput.statsContext,
766+
logger: pollInput.logger,
767+
stateContext: pollInput.stateContext
781768
}
782769

783770
// Execute the poll function
784-
const response = await this.definition.poll(requestClient, pollInput, context)
771+
const response = await this.definition.poll(requestClient, data)
785772
return response
786773
}
787774

@@ -800,16 +787,21 @@ export class Action<Settings, Payload extends JSONLikeObject, AudienceSettings =
800787
// Create request client for the poll operation
801788
const requestClient = this.createPollRequestClient(pollInput)
802789

803-
// Extract context for poll method
804-
const context = {
805-
stateContext: pollInput.stateContext,
806-
logger: pollInput.logger,
790+
// Create ExecuteInput object matching RequestFn signature - payload is the poll input
791+
const data: ExecuteInput<Settings, MultiPollInput<Settings, AudienceSettings>, AudienceSettings> = {
792+
mapping: {},
793+
settings: pollInput.settings,
794+
audienceSettings: pollInput.audienceSettings,
795+
payload: pollInput,
796+
auth: pollInput.auth,
807797
features: pollInput.features,
808-
statsContext: pollInput.statsContext
798+
statsContext: pollInput.statsContext,
799+
logger: pollInput.logger,
800+
stateContext: pollInput.stateContext
809801
}
810802

811803
// Execute the pollMultiple function
812-
const responses = await this.definition.pollMultiple(requestClient, pollInput, context)
804+
const responses = await this.definition.pollMultiple(requestClient, data)
813805

814806
// Transform array of PollResponse to MultiPollResponse
815807
const results = responses.map((response, index) => ({

packages/core/src/destination-kit/examples/async-action-example.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*/
77

88
import { ActionDefinition } from '../action'
9-
import { AsyncOperationResponse, PollResponse, PollInput } from '../types'
9+
import { AsyncOperationResponse, PollResponse } from '../types'
1010
import { RequestClient } from '../../create-request-client'
1111

1212
// Example destination settings
@@ -125,10 +125,10 @@ const exampleAsyncAction: ActionDefinition<ExampleSettings, ExamplePayload> = {
125125
* Poll method to check the status of an async operation
126126
* This method is called periodically to check if the operation is complete
127127
*/
128-
poll: async (request: RequestClient, data: PollInput<ExampleSettings>) => {
129-
const response = await request(`${data.settings.endpoint}/batch/status/${data.operationId}`, {
128+
poll: async (request: RequestClient, { settings, payload }) => {
129+
const response = await request(`${settings.endpoint}/batch/status/${payload.operationId}`, {
130130
method: 'GET',
131-
timeout: data.settings.timeout || 10000
131+
timeout: settings.timeout || 10000
132132
})
133133

134134
const statusData = response.data as {

packages/core/src/destination-kit/examples/context-passing-test.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,8 @@ const testAction: ActionDefinition<Settings, Payload> = {
9494
}
9595
},
9696

97-
async poll(request: RequestClient, data, context) {
98-
const { operationId, settings } = data
99-
const { stateContext } = context
97+
async poll(request: RequestClient, { payload, settings, stateContext }) {
98+
const { operationId } = payload
10099

101100
// Retrieve context set by performBatch method
102101
const batchMetadataStr = stateContext?.getRequestContext('batchMetadata')
@@ -125,9 +124,8 @@ const testAction: ActionDefinition<Settings, Payload> = {
125124
}
126125
},
127126

128-
async pollMultiple(request: RequestClient, data, context) {
129-
const { operationIds, settings } = data
130-
const { stateContext } = context
127+
async pollMultiple(request: RequestClient, { payload, settings, stateContext }) {
128+
const { operationIds } = payload
131129

132130
// Retrieve context set by performBatch method
133131
const batchMetadataStr = stateContext?.getRequestContext('batchMetadata')
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/**
2+
* Simple verification script to test the new poll method signatures
3+
*/
4+
5+
import { ActionDefinition } from '../action'
6+
import type { RequestClient } from '../../create-request-client'
7+
8+
interface TestSettings {
9+
apiKey: string
10+
}
11+
12+
interface TestPayload {
13+
id: string
14+
name: string
15+
}
16+
17+
// This should compile without errors with the new signature
18+
const testAction: ActionDefinition<TestSettings, TestPayload> = {
19+
title: 'Test Action',
20+
description: 'Test action for poll signature verification',
21+
fields: {
22+
id: {
23+
label: 'ID',
24+
description: 'Unique identifier',
25+
type: 'string',
26+
required: true
27+
},
28+
name: {
29+
label: 'Name',
30+
description: 'Name field',
31+
type: 'string',
32+
required: true
33+
}
34+
},
35+
36+
async perform(_request: RequestClient, { settings: _settings, payload }) {
37+
// Simple perform implementation
38+
return { success: true, id: payload.id }
39+
},
40+
41+
async performBatch(_request: RequestClient, { settings: _settings, payload, stateContext }) {
42+
// Store context for polling
43+
stateContext?.setResponseContext(
44+
'batchInfo',
45+
JSON.stringify({
46+
batchSize: payload.length,
47+
submittedAt: new Date().toISOString()
48+
}),
49+
{}
50+
)
51+
52+
return {
53+
operationId: 'test-op-123',
54+
status: 'pending' as const,
55+
message: `Processing ${payload.length} items`
56+
}
57+
},
58+
59+
// New poll signature following Braze cohorts pattern
60+
async poll(_request: RequestClient, { settings: _settings, payload, stateContext }) {
61+
// In real implementation, this would check actual operation status
62+
// Here we just simulate a successful completion
63+
const operationId = stateContext?.getRequestContext('operationId')
64+
65+
// Return completion result
66+
return {
67+
status: 'completed',
68+
result: {
69+
operationId: operationId || payload.operationId,
70+
processedAt: new Date().toISOString(),
71+
records: 1
72+
}
73+
}
74+
},
75+
76+
async pollMultiple(_request: RequestClient, { settings: _settings, payload, stateContext: _stateContext }) {
77+
// In real implementation, this would check actual operation status for each operation
78+
// Here we just simulate successful completion for all operations
79+
80+
return payload.operationIds.map((operationId: string) => ({
81+
operationId,
82+
status: 'completed' as const,
83+
result: {
84+
operationId,
85+
processedAt: new Date().toISOString(),
86+
records: 1
87+
}
88+
}))
89+
}
90+
}
91+
92+
export default testAction

0 commit comments

Comments
 (0)