@outputai/core 0.14.0 → 0.14.1-next.2947341.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/credentials/credentials.d.ts +6 -0
- package/dist/credentials/credentials.js +87 -0
- package/dist/credentials/encrypted_yaml_provider.d.ts +2 -0
- package/dist/credentials/encrypted_yaml_provider.js +77 -0
- package/dist/credentials/encryption.d.ts +3 -0
- package/dist/credentials/encryption.js +6 -0
- package/dist/credentials/errors.d.ts +13 -0
- package/dist/credentials/errors.js +39 -0
- package/dist/credentials/index.d.ts +6 -0
- package/dist/credentials/index.js +5 -0
- package/dist/credentials/init.d.ts +1 -0
- package/dist/credentials/init.js +7 -0
- package/dist/credentials/paths.d.ts +7 -0
- package/dist/credentials/paths.js +14 -0
- package/dist/credentials/provider_registry.d.ts +3 -0
- package/dist/credentials/provider_registry.js +6 -0
- package/dist/credentials/types.d.ts +12 -0
- package/dist/credentials/types.js +1 -0
- package/package.json +25 -14
- package/src/async_storage.d.ts +4 -0
- package/src/consts.js +0 -2
- package/src/helpers/object.d.ts +2 -0
- package/src/hooks/index.d.ts +0 -8
- package/src/hooks/index.js +0 -3
- package/src/logger/index.d.ts +4 -0
- package/src/worker/index.js +3 -1
- package/bin/healthcheck.spec.js +0 -90
- package/src/bus.spec.js +0 -196
- package/src/errors.spec.js +0 -19
- package/src/helpers/activity_options.spec.js +0 -55
- package/src/helpers/component.spec.js +0 -54
- package/src/helpers/error_serializer.spec.js +0 -479
- package/src/helpers/errors.spec.js +0 -189
- package/src/helpers/fetch.spec.js +0 -292
- package/src/helpers/function.spec.js +0 -24
- package/src/helpers/object.spec.js +0 -425
- package/src/helpers/promise.spec.js +0 -62
- package/src/helpers/redact.spec.js +0 -66
- package/src/helpers/string.spec.js +0 -99
- package/src/helpers/temporal_context.spec.ts +0 -83
- package/src/helpers/trace_info.spec.js +0 -45
- package/src/helpers/workflow_context.spec.js +0 -46
- package/src/hooks/index.spec.js +0 -265
- package/src/hooks/pending_hooks.spec.js +0 -62
- package/src/interface/evaluator.spec.js +0 -685
- package/src/interface/logger.spec.js +0 -172
- package/src/interface/step.spec.js +0 -128
- package/src/interface/validations/index.spec.js +0 -197
- package/src/interface/validations/schemas.spec.js +0 -229
- package/src/interface/webhook.spec.js +0 -170
- package/src/interface/workflow.spec.js +0 -710
- package/src/interface/workflow_utils.spec.js +0 -271
- package/src/interface/zod_integration.spec.js +0 -646
- package/src/internal_activities/index.spec.js +0 -186
- package/src/logger/development.spec.js +0 -87
- package/src/logger/index.spec.js +0 -27
- package/src/logger/production.spec.js +0 -71
- package/src/sdk/helpers/component_metadata.spec.js +0 -30
- package/src/sdk/helpers/objects.spec.js +0 -16
- package/src/sdk/helpers/path.spec.js +0 -102
- package/src/sdk/runtime/context.spec.js +0 -37
- package/src/sdk/runtime/events.spec.js +0 -40
- package/src/temporal/client.spec.js +0 -124
- package/src/tracing/processors/local/index.spec.js +0 -204
- package/src/tracing/processors/s3/configs.spec.js +0 -64
- package/src/tracing/processors/s3/index.spec.js +0 -185
- package/src/tracing/processors/s3/redis_client.spec.js +0 -179
- package/src/tracing/processors/s3/s3_client.spec.js +0 -68
- package/src/tracing/tools/build_trace_tree.spec.js +0 -216
- package/src/tracing/trace_engine.spec.js +0 -299
- package/src/worker/bundle.spec.js +0 -53
- package/src/worker/bundler_options.spec.js +0 -62
- package/src/worker/catalog_workflow/catalog_publisher.spec.js +0 -317
- package/src/worker/catalog_workflow/index.spec.js +0 -222
- package/src/worker/configs.spec.js +0 -213
- package/src/worker/configs_tuner_schema.spec.js +0 -127
- package/src/worker/connection_monitor.spec.js +0 -328
- package/src/worker/global_functions.spec.js +0 -55
- package/src/worker/index.spec.js +0 -526
- package/src/worker/interceptors/activity.spec.js +0 -369
- package/src/worker/interceptors/headers.spec.js +0 -73
- package/src/worker/interceptors/workflow.spec.js +0 -357
- package/src/worker/interruption.spec.js +0 -177
- package/src/worker/loader/activities.spec.js +0 -212
- package/src/worker/loader/hooks.spec.js +0 -64
- package/src/worker/loader/matchers.spec.js +0 -140
- package/src/worker/loader/tools.spec.js +0 -595
- package/src/worker/loader/workflows.spec.js +0 -287
- package/src/worker/log_hooks.spec.js +0 -303
- package/src/worker/shutdown.spec.js +0 -197
- package/src/worker/sinks.spec.js +0 -220
- package/src/worker/telemetry.spec.js +0 -80
- package/src/worker/temporal_logger.spec.js +0 -90
- package/src/worker/webpack_loaders/tools.spec.js +0 -314
- package/src/worker/webpack_loaders/workflow_rewriter/collect_target_imports.spec.js +0 -134
- package/src/worker/webpack_loaders/workflow_rewriter/index.spec.js +0 -154
- package/src/worker/webpack_loaders/workflow_rewriter/rewrite_activity_calls.spec.js +0 -165
- package/src/worker/webpack_loaders/workflow_validator/index.spec.js +0 -202
- package/src/worker/webpack_loaders/workflow_validator/npm_workflow_export_resolve.spec.js +0 -374
- package/src/worker/worker_runner.spec.js +0 -220
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
import { EvaluationResult } from '../evaluation_result.js';
|
|
4
|
-
import {
|
|
5
|
-
evaluatorOutputSchema,
|
|
6
|
-
evaluatorSchema,
|
|
7
|
-
executeInParallelSchema,
|
|
8
|
-
httpRequestSchema,
|
|
9
|
-
isZodSchema,
|
|
10
|
-
stepSchema,
|
|
11
|
-
workflowInvocationOptionsSchema,
|
|
12
|
-
workflowSchema
|
|
13
|
-
} from './schemas.js';
|
|
14
|
-
|
|
15
|
-
const fn = () => {};
|
|
16
|
-
const validBase = {
|
|
17
|
-
name: 'valid_name',
|
|
18
|
-
description: 'Valid description',
|
|
19
|
-
inputSchema: z.object( { value: z.string() } ),
|
|
20
|
-
outputSchema: z.object( { result: z.string() } ),
|
|
21
|
-
fn,
|
|
22
|
-
options: {
|
|
23
|
-
activityOptions: {
|
|
24
|
-
startToCloseTimeout: '5m',
|
|
25
|
-
heartbeatTimeout: 1000,
|
|
26
|
-
retry: {
|
|
27
|
-
initialInterval: '10s',
|
|
28
|
-
backoffCoefficient: 2,
|
|
29
|
-
maximumInterval: '1m',
|
|
30
|
-
maximumAttempts: 3,
|
|
31
|
-
nonRetryableErrorTypes: [ 'FatalError' ]
|
|
32
|
-
},
|
|
33
|
-
priority: {
|
|
34
|
-
fairnessKey: 'tenant',
|
|
35
|
-
fairnessWeight: 1,
|
|
36
|
-
priorityKey: 2
|
|
37
|
-
},
|
|
38
|
-
summary: 'Short summary'
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
describe( 'validation schemas', () => {
|
|
44
|
-
describe( 'isZodSchema()', () => {
|
|
45
|
-
it( 'identifies Zod schemas', () => {
|
|
46
|
-
expect( isZodSchema( z.object( { name: z.string() } ) ) ).toBe( true );
|
|
47
|
-
expect( isZodSchema( z.string() ) ).toBe( true );
|
|
48
|
-
expect( isZodSchema( z.array( z.number() ) ) ).toBe( true );
|
|
49
|
-
expect( isZodSchema( z.union( [ z.string(), z.number() ] ) ) ).toBe( true );
|
|
50
|
-
} );
|
|
51
|
-
|
|
52
|
-
it( 'uses the Zod v4 runtime shape instead of instanceof', () => {
|
|
53
|
-
const schemaLikeFromAnotherPackageInstance = {
|
|
54
|
-
_zod: {
|
|
55
|
-
def: {
|
|
56
|
-
type: 'object'
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
safeParse: () => ( { success: true, data: {} } )
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
expect( isZodSchema( schemaLikeFromAnotherPackageInstance ) ).toBe( true );
|
|
63
|
-
} );
|
|
64
|
-
|
|
65
|
-
it( 'rejects non-Zod values', () => {
|
|
66
|
-
expect( isZodSchema( { type: 'object' } ) ).toBe( false );
|
|
67
|
-
expect( isZodSchema( {} ) ).toBe( false );
|
|
68
|
-
expect( isZodSchema( [] ) ).toBe( false );
|
|
69
|
-
expect( isZodSchema( null ) ).toBe( false );
|
|
70
|
-
expect( isZodSchema( undefined ) ).toBe( false );
|
|
71
|
-
expect( isZodSchema( 'string' ) ).toBe( false );
|
|
72
|
-
} );
|
|
73
|
-
|
|
74
|
-
it( 'rejects objects that only partially match the Zod shape', () => {
|
|
75
|
-
expect( isZodSchema( { safeParse: () => ( { success: true } ) } ) ).toBe( false );
|
|
76
|
-
expect( isZodSchema( { _zod: { def: { type: 'string' } } } ) ).toBe( false );
|
|
77
|
-
expect( isZodSchema( { _zod: { def: {} }, safeParse: () => ( { success: true } ) } ) ).toBe( false );
|
|
78
|
-
expect( isZodSchema( { _zod: null, safeParse: () => ( { success: true } ) } ) ).toBe( false );
|
|
79
|
-
} );
|
|
80
|
-
} );
|
|
81
|
-
|
|
82
|
-
describe( 'stepSchema', () => {
|
|
83
|
-
it( 'accepts a valid step definition', () => {
|
|
84
|
-
expect( stepSchema.safeParse( validBase ).success ).toBe( true );
|
|
85
|
-
} );
|
|
86
|
-
|
|
87
|
-
it( 'rejects invalid names, non-Zod schemas, invalid activity options, and unknown top-level keys', () => {
|
|
88
|
-
expect( stepSchema.safeParse( { ...validBase, name: 'invalid-name' } ).success ).toBe( false );
|
|
89
|
-
expect( stepSchema.safeParse( { ...validBase, inputSchema: { type: 'object' } } ).success ).toBe( false );
|
|
90
|
-
expect( stepSchema.safeParse( {
|
|
91
|
-
...validBase,
|
|
92
|
-
options: { activityOptions: { retry: { maximumAttempts: 0 } } }
|
|
93
|
-
} ).success ).toBe( false );
|
|
94
|
-
expect( stepSchema.safeParse( { ...validBase, unexpected: true } ).success ).toBe( false );
|
|
95
|
-
} );
|
|
96
|
-
} );
|
|
97
|
-
|
|
98
|
-
describe( 'workflowSchema', () => {
|
|
99
|
-
it( 'accepts workflow-specific options and aliases', () => {
|
|
100
|
-
const result = workflowSchema.safeParse( {
|
|
101
|
-
...validBase,
|
|
102
|
-
aliases: [ 'old_name' ],
|
|
103
|
-
options: {
|
|
104
|
-
...validBase.options,
|
|
105
|
-
disableTrace: true
|
|
106
|
-
}
|
|
107
|
-
} );
|
|
108
|
-
|
|
109
|
-
expect( result.success ).toBe( true );
|
|
110
|
-
} );
|
|
111
|
-
|
|
112
|
-
it( 'defaults aliases and rejects invalid workflow fields', () => {
|
|
113
|
-
const result = workflowSchema.safeParse( validBase );
|
|
114
|
-
expect( result.success && result.data.aliases ).toEqual( [] );
|
|
115
|
-
|
|
116
|
-
expect( workflowSchema.safeParse( { ...validBase, aliases: [ 'bad-alias' ] } ).success ).toBe( false );
|
|
117
|
-
expect( workflowSchema.safeParse( {
|
|
118
|
-
...validBase,
|
|
119
|
-
options: { ...validBase.options, disableTrace: 'yes' }
|
|
120
|
-
} ).success ).toBe( false );
|
|
121
|
-
} );
|
|
122
|
-
} );
|
|
123
|
-
|
|
124
|
-
describe( 'evaluatorSchema and evaluatorOutputSchema', () => {
|
|
125
|
-
it( 'accepts evaluator definitions without outputSchema', () => {
|
|
126
|
-
const { outputSchema: _outputSchema, ...validEvaluator } = validBase;
|
|
127
|
-
expect( evaluatorSchema.safeParse( validEvaluator ).success ).toBe( true );
|
|
128
|
-
} );
|
|
129
|
-
|
|
130
|
-
it( 'rejects evaluator definitions with outputSchema', () => {
|
|
131
|
-
expect( evaluatorSchema.safeParse( validBase ).success ).toBe( false );
|
|
132
|
-
} );
|
|
133
|
-
|
|
134
|
-
it( 'accepts only EvaluationResult instances as evaluator output', () => {
|
|
135
|
-
expect( evaluatorOutputSchema.safeParse( new EvaluationResult( { value: 'ok', confidence: 1 } ) ).success ).toBe( true );
|
|
136
|
-
expect( evaluatorOutputSchema.safeParse( { value: 'ok', confidence: 1 } ).success ).toBe( false );
|
|
137
|
-
} );
|
|
138
|
-
} );
|
|
139
|
-
|
|
140
|
-
describe( 'httpRequestSchema', () => {
|
|
141
|
-
it( 'accepts valid HTTP request payloads', () => {
|
|
142
|
-
expect( httpRequestSchema.safeParse( {
|
|
143
|
-
url: 'https://example.com',
|
|
144
|
-
method: 'POST',
|
|
145
|
-
payload: { ok: true },
|
|
146
|
-
headers: { authorization: 'Bearer token' },
|
|
147
|
-
responseOptions: { includeHeaders: true, includeBody: true }
|
|
148
|
-
} ).success ).toBe( true );
|
|
149
|
-
} );
|
|
150
|
-
|
|
151
|
-
it( 'defaults omitted response options to false', () => {
|
|
152
|
-
const result = httpRequestSchema.safeParse( {
|
|
153
|
-
url: 'https://example.com',
|
|
154
|
-
method: 'GET',
|
|
155
|
-
responseOptions: {}
|
|
156
|
-
} );
|
|
157
|
-
|
|
158
|
-
expect( result.success ).toBe( true );
|
|
159
|
-
expect( result.data.responseOptions ).toEqual( {
|
|
160
|
-
includeHeaders: false,
|
|
161
|
-
includeBody: false
|
|
162
|
-
} );
|
|
163
|
-
} );
|
|
164
|
-
|
|
165
|
-
it( 'rejects invalid URL protocols, methods, header values, and response options', () => {
|
|
166
|
-
expect( httpRequestSchema.safeParse( { url: 'ftp://example.com', method: 'GET' } ).success ).toBe( false );
|
|
167
|
-
expect( httpRequestSchema.safeParse( { url: 'https://example.com', method: 'OPTIONS' } ).success ).toBe( false );
|
|
168
|
-
expect( httpRequestSchema.safeParse( {
|
|
169
|
-
url: 'https://example.com',
|
|
170
|
-
method: 'GET',
|
|
171
|
-
headers: { count: 1 }
|
|
172
|
-
} ).success ).toBe( false );
|
|
173
|
-
expect( httpRequestSchema.safeParse( {
|
|
174
|
-
url: 'https://example.com',
|
|
175
|
-
method: 'GET',
|
|
176
|
-
responseOptions: { includeBody: 'yes' }
|
|
177
|
-
} ).success ).toBe( false );
|
|
178
|
-
} );
|
|
179
|
-
} );
|
|
180
|
-
|
|
181
|
-
describe( 'workflowInvocationOptionsSchema', () => {
|
|
182
|
-
it( 'accepts omitted options and valid invocation configuration', () => {
|
|
183
|
-
expect( workflowInvocationOptionsSchema.safeParse( undefined ).success ).toBe( true );
|
|
184
|
-
expect( workflowInvocationOptionsSchema.safeParse( {
|
|
185
|
-
detached: true,
|
|
186
|
-
activityOptions: { retry: { maximumAttempts: 1 } },
|
|
187
|
-
context: {
|
|
188
|
-
control: {
|
|
189
|
-
continueAsNew: fn,
|
|
190
|
-
isContinueAsNewSuggested: fn,
|
|
191
|
-
extraControl: true
|
|
192
|
-
},
|
|
193
|
-
info: {
|
|
194
|
-
workflowId: 'wf',
|
|
195
|
-
runId: 'run',
|
|
196
|
-
extraInfo: true
|
|
197
|
-
},
|
|
198
|
-
extraContext: true
|
|
199
|
-
}
|
|
200
|
-
} ).success ).toBe( true );
|
|
201
|
-
} );
|
|
202
|
-
|
|
203
|
-
it( 'rejects stale option shapes and invalid invocation values', () => {
|
|
204
|
-
expect( workflowInvocationOptionsSchema.safeParse( {
|
|
205
|
-
options: { activityOptions: { retry: { maximumAttempts: 1 } } }
|
|
206
|
-
} ).success ).toBe( false );
|
|
207
|
-
expect( workflowInvocationOptionsSchema.safeParse( { detached: 'true' } ).success ).toBe( false );
|
|
208
|
-
expect( workflowInvocationOptionsSchema.safeParse( {
|
|
209
|
-
activityOptions: { retry: { maximumAttempts: 0 } }
|
|
210
|
-
} ).success ).toBe( false );
|
|
211
|
-
expect( workflowInvocationOptionsSchema.safeParse( {
|
|
212
|
-
context: { control: { continueAsNew: 'nope' } }
|
|
213
|
-
} ).success ).toBe( false );
|
|
214
|
-
} );
|
|
215
|
-
} );
|
|
216
|
-
|
|
217
|
-
describe( 'executeInParallelSchema', () => {
|
|
218
|
-
it( 'accepts valid execution configs', () => {
|
|
219
|
-
expect( executeInParallelSchema.safeParse( { jobs: [ fn ], concurrency: 1 } ).success ).toBe( true );
|
|
220
|
-
expect( executeInParallelSchema.safeParse( { jobs: [ fn ], concurrency: Infinity, onJobCompleted: fn } ).success ).toBe( true );
|
|
221
|
-
} );
|
|
222
|
-
|
|
223
|
-
it( 'rejects invalid execution configs', () => {
|
|
224
|
-
expect( executeInParallelSchema.safeParse( { jobs: [], concurrency: 0 } ).success ).toBe( false );
|
|
225
|
-
expect( executeInParallelSchema.safeParse( { jobs: [ 'not-a-function' ], concurrency: 1 } ).success ).toBe( false );
|
|
226
|
-
expect( executeInParallelSchema.safeParse( { jobs: [ fn ], concurrency: 1, onJobCompleted: 'nope' } ).success ).toBe( false );
|
|
227
|
-
} );
|
|
228
|
-
} );
|
|
229
|
-
} );
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
-
import { ACTIVITY_SEND_HTTP_REQUEST } from '#consts';
|
|
3
|
-
|
|
4
|
-
const validateRequestPayloadMock = vi.fn();
|
|
5
|
-
vi.mock( './validations/index.js', () => ( {
|
|
6
|
-
validateRequestPayload: validateRequestPayloadMock
|
|
7
|
-
} ) );
|
|
8
|
-
|
|
9
|
-
// Minimal, legible mock of @temporalio/workflow APIs used by webhook.js
|
|
10
|
-
const activityFnMock = vi.fn();
|
|
11
|
-
const proxyActivitiesMock = vi.fn( () => ( { [ACTIVITY_SEND_HTTP_REQUEST]: activityFnMock } ) );
|
|
12
|
-
|
|
13
|
-
const storedHandlers = new Map();
|
|
14
|
-
const defineSignalMock = name => name;
|
|
15
|
-
const setHandlerMock = ( signal, fn ) => {
|
|
16
|
-
storedHandlers.set( signal, fn );
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const workflowInfoMock = vi.fn( () => ( { workflowId: 'wf-123' } ) );
|
|
20
|
-
const sinks = { trace: { start: vi.fn(), end: vi.fn() } };
|
|
21
|
-
const proxySinksMock = vi.fn( async () => sinks );
|
|
22
|
-
|
|
23
|
-
class TestTrigger {
|
|
24
|
-
constructor() {
|
|
25
|
-
this.resolved = false;
|
|
26
|
-
this._resolve = () => {};
|
|
27
|
-
this.promise = new Promise( res => {
|
|
28
|
-
this._resolve = res;
|
|
29
|
-
} );
|
|
30
|
-
}
|
|
31
|
-
resolve( value ) {
|
|
32
|
-
if ( !this.resolved ) {
|
|
33
|
-
this.resolved = true;
|
|
34
|
-
this._resolve( value );
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
then( onFulfilled, onRejected ) {
|
|
38
|
-
return this.promise.then( onFulfilled, onRejected );
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
vi.mock( '@temporalio/workflow', () => ( {
|
|
43
|
-
defineSignal: defineSignalMock,
|
|
44
|
-
setHandler: setHandlerMock,
|
|
45
|
-
proxyActivities: proxyActivitiesMock,
|
|
46
|
-
workflowInfo: workflowInfoMock,
|
|
47
|
-
proxySinks: proxySinksMock,
|
|
48
|
-
uuid4: () => 'uuid-mock',
|
|
49
|
-
Trigger: TestTrigger
|
|
50
|
-
} ) );
|
|
51
|
-
|
|
52
|
-
describe( 'interface/webhook', () => {
|
|
53
|
-
beforeEach( () => {
|
|
54
|
-
vi.clearAllMocks();
|
|
55
|
-
storedHandlers.clear();
|
|
56
|
-
} );
|
|
57
|
-
|
|
58
|
-
it( 'sendHttpRequest validates input and calls activity with correct options and args', async () => {
|
|
59
|
-
const { sendHttpRequest } = await import( './webhook.js' );
|
|
60
|
-
|
|
61
|
-
const fakeSerializedResponse = {
|
|
62
|
-
url: 'https://example.com',
|
|
63
|
-
status: 200,
|
|
64
|
-
statusText: 'OK',
|
|
65
|
-
ok: true,
|
|
66
|
-
headers: { 'content-type': 'application/json' },
|
|
67
|
-
body: { ok: true }
|
|
68
|
-
};
|
|
69
|
-
activityFnMock.mockResolvedValueOnce( fakeSerializedResponse );
|
|
70
|
-
|
|
71
|
-
const args = { url: 'https://example.com/api', method: 'GET' };
|
|
72
|
-
const res = await sendHttpRequest( args );
|
|
73
|
-
|
|
74
|
-
// validated
|
|
75
|
-
expect( validateRequestPayloadMock ).toHaveBeenCalledWith( {
|
|
76
|
-
...args,
|
|
77
|
-
payload: undefined,
|
|
78
|
-
headers: undefined,
|
|
79
|
-
responseOptions: {}
|
|
80
|
-
} );
|
|
81
|
-
|
|
82
|
-
// activity proxied with specified options
|
|
83
|
-
expect( proxyActivitiesMock ).toHaveBeenCalledTimes( 1 );
|
|
84
|
-
const optionsArg = proxyActivitiesMock.mock.calls[0][0];
|
|
85
|
-
expect( optionsArg.startToCloseTimeout ).toBe( '3m' );
|
|
86
|
-
expect( optionsArg.retry ).toEqual( expect.objectContaining( {
|
|
87
|
-
initialInterval: '15s',
|
|
88
|
-
maximumAttempts: 3,
|
|
89
|
-
nonRetryableErrorTypes: expect.arrayContaining( [ 'FatalError' ] )
|
|
90
|
-
} ) );
|
|
91
|
-
|
|
92
|
-
// activity invoked with the same args
|
|
93
|
-
expect( activityFnMock ).toHaveBeenCalledWith( {
|
|
94
|
-
...args,
|
|
95
|
-
payload: undefined,
|
|
96
|
-
headers: undefined,
|
|
97
|
-
responseOptions: {}
|
|
98
|
-
} );
|
|
99
|
-
expect( res ).toEqual( fakeSerializedResponse );
|
|
100
|
-
} );
|
|
101
|
-
|
|
102
|
-
it( 'sendHttpRequest forwards response options', async () => {
|
|
103
|
-
const { sendHttpRequest } = await import( './webhook.js' );
|
|
104
|
-
|
|
105
|
-
activityFnMock.mockResolvedValueOnce( { ok: true } );
|
|
106
|
-
|
|
107
|
-
const args = {
|
|
108
|
-
url: 'https://example.com/api',
|
|
109
|
-
method: 'GET',
|
|
110
|
-
responseOptions: { includeHeaders: true, includeBody: true }
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
await sendHttpRequest( args );
|
|
114
|
-
|
|
115
|
-
expect( validateRequestPayloadMock ).toHaveBeenCalledWith( {
|
|
116
|
-
...args,
|
|
117
|
-
payload: undefined,
|
|
118
|
-
headers: undefined
|
|
119
|
-
} );
|
|
120
|
-
expect( activityFnMock ).toHaveBeenCalledWith( {
|
|
121
|
-
...args,
|
|
122
|
-
payload: undefined,
|
|
123
|
-
headers: undefined
|
|
124
|
-
} );
|
|
125
|
-
} );
|
|
126
|
-
|
|
127
|
-
it( 'sendPostRequestAndAwaitWebhook posts wrapped payload and resolves on resume signal', async () => {
|
|
128
|
-
const { sendPostRequestAndAwaitWebhook } = await import( './webhook.js' );
|
|
129
|
-
|
|
130
|
-
activityFnMock.mockResolvedValueOnce( {
|
|
131
|
-
url: 'https://webhook.site',
|
|
132
|
-
status: 200,
|
|
133
|
-
statusText: 'OK',
|
|
134
|
-
ok: true,
|
|
135
|
-
headers: {},
|
|
136
|
-
body: null
|
|
137
|
-
} );
|
|
138
|
-
|
|
139
|
-
const url = 'https://webhook.site/ingest';
|
|
140
|
-
const promise = sendPostRequestAndAwaitWebhook( { url, payload: { x: 1 }, headers: { a: 'b' } } );
|
|
141
|
-
|
|
142
|
-
// The activity was called via sendHttpRequest with POST and wrapped payload
|
|
143
|
-
const callArgs = activityFnMock.mock.calls[0][0];
|
|
144
|
-
expect( callArgs.method ).toBe( 'POST' );
|
|
145
|
-
expect( callArgs.url ).toBe( url );
|
|
146
|
-
expect( callArgs.payload ).toEqual( { workflowId: 'wf-123', payload: { x: 1 } } );
|
|
147
|
-
expect( callArgs.headers ).toEqual( { a: 'b' } );
|
|
148
|
-
expect( callArgs.responseOptions ).toEqual( {} );
|
|
149
|
-
|
|
150
|
-
await vi.waitFor( () => expect( storedHandlers.has( 'resume' ) ).toBe( true ) );
|
|
151
|
-
|
|
152
|
-
expect( sinks.trace.start ).toHaveBeenCalledWith( {
|
|
153
|
-
id: 'wf-123-https://webhook.site/ingest-uuid-mock',
|
|
154
|
-
name: 'resume',
|
|
155
|
-
kind: 'webhook'
|
|
156
|
-
} );
|
|
157
|
-
|
|
158
|
-
const webhookPayload = { status: 'completed' };
|
|
159
|
-
storedHandlers.get( 'resume' )( webhookPayload );
|
|
160
|
-
|
|
161
|
-
await expect( promise ).resolves.toEqual( webhookPayload );
|
|
162
|
-
expect( sinks.trace.end ).toHaveBeenCalledWith( {
|
|
163
|
-
id: 'wf-123-https://webhook.site/ingest-uuid-mock',
|
|
164
|
-
details: webhookPayload
|
|
165
|
-
} );
|
|
166
|
-
|
|
167
|
-
storedHandlers.get( 'resume' )( { status: 'duplicate' } );
|
|
168
|
-
expect( sinks.trace.end ).toHaveBeenCalledTimes( 1 );
|
|
169
|
-
} );
|
|
170
|
-
} );
|