@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.
Files changed (100) hide show
  1. package/dist/credentials/credentials.d.ts +6 -0
  2. package/dist/credentials/credentials.js +87 -0
  3. package/dist/credentials/encrypted_yaml_provider.d.ts +2 -0
  4. package/dist/credentials/encrypted_yaml_provider.js +77 -0
  5. package/dist/credentials/encryption.d.ts +3 -0
  6. package/dist/credentials/encryption.js +6 -0
  7. package/dist/credentials/errors.d.ts +13 -0
  8. package/dist/credentials/errors.js +39 -0
  9. package/dist/credentials/index.d.ts +6 -0
  10. package/dist/credentials/index.js +5 -0
  11. package/dist/credentials/init.d.ts +1 -0
  12. package/dist/credentials/init.js +7 -0
  13. package/dist/credentials/paths.d.ts +7 -0
  14. package/dist/credentials/paths.js +14 -0
  15. package/dist/credentials/provider_registry.d.ts +3 -0
  16. package/dist/credentials/provider_registry.js +6 -0
  17. package/dist/credentials/types.d.ts +12 -0
  18. package/dist/credentials/types.js +1 -0
  19. package/package.json +25 -14
  20. package/src/async_storage.d.ts +4 -0
  21. package/src/consts.js +0 -2
  22. package/src/helpers/object.d.ts +2 -0
  23. package/src/hooks/index.d.ts +0 -8
  24. package/src/hooks/index.js +0 -3
  25. package/src/logger/index.d.ts +4 -0
  26. package/src/worker/index.js +3 -1
  27. package/bin/healthcheck.spec.js +0 -90
  28. package/src/bus.spec.js +0 -196
  29. package/src/errors.spec.js +0 -19
  30. package/src/helpers/activity_options.spec.js +0 -55
  31. package/src/helpers/component.spec.js +0 -54
  32. package/src/helpers/error_serializer.spec.js +0 -479
  33. package/src/helpers/errors.spec.js +0 -189
  34. package/src/helpers/fetch.spec.js +0 -292
  35. package/src/helpers/function.spec.js +0 -24
  36. package/src/helpers/object.spec.js +0 -425
  37. package/src/helpers/promise.spec.js +0 -62
  38. package/src/helpers/redact.spec.js +0 -66
  39. package/src/helpers/string.spec.js +0 -99
  40. package/src/helpers/temporal_context.spec.ts +0 -83
  41. package/src/helpers/trace_info.spec.js +0 -45
  42. package/src/helpers/workflow_context.spec.js +0 -46
  43. package/src/hooks/index.spec.js +0 -265
  44. package/src/hooks/pending_hooks.spec.js +0 -62
  45. package/src/interface/evaluator.spec.js +0 -685
  46. package/src/interface/logger.spec.js +0 -172
  47. package/src/interface/step.spec.js +0 -128
  48. package/src/interface/validations/index.spec.js +0 -197
  49. package/src/interface/validations/schemas.spec.js +0 -229
  50. package/src/interface/webhook.spec.js +0 -170
  51. package/src/interface/workflow.spec.js +0 -710
  52. package/src/interface/workflow_utils.spec.js +0 -271
  53. package/src/interface/zod_integration.spec.js +0 -646
  54. package/src/internal_activities/index.spec.js +0 -186
  55. package/src/logger/development.spec.js +0 -87
  56. package/src/logger/index.spec.js +0 -27
  57. package/src/logger/production.spec.js +0 -71
  58. package/src/sdk/helpers/component_metadata.spec.js +0 -30
  59. package/src/sdk/helpers/objects.spec.js +0 -16
  60. package/src/sdk/helpers/path.spec.js +0 -102
  61. package/src/sdk/runtime/context.spec.js +0 -37
  62. package/src/sdk/runtime/events.spec.js +0 -40
  63. package/src/temporal/client.spec.js +0 -124
  64. package/src/tracing/processors/local/index.spec.js +0 -204
  65. package/src/tracing/processors/s3/configs.spec.js +0 -64
  66. package/src/tracing/processors/s3/index.spec.js +0 -185
  67. package/src/tracing/processors/s3/redis_client.spec.js +0 -179
  68. package/src/tracing/processors/s3/s3_client.spec.js +0 -68
  69. package/src/tracing/tools/build_trace_tree.spec.js +0 -216
  70. package/src/tracing/trace_engine.spec.js +0 -299
  71. package/src/worker/bundle.spec.js +0 -53
  72. package/src/worker/bundler_options.spec.js +0 -62
  73. package/src/worker/catalog_workflow/catalog_publisher.spec.js +0 -317
  74. package/src/worker/catalog_workflow/index.spec.js +0 -222
  75. package/src/worker/configs.spec.js +0 -213
  76. package/src/worker/configs_tuner_schema.spec.js +0 -127
  77. package/src/worker/connection_monitor.spec.js +0 -328
  78. package/src/worker/global_functions.spec.js +0 -55
  79. package/src/worker/index.spec.js +0 -526
  80. package/src/worker/interceptors/activity.spec.js +0 -369
  81. package/src/worker/interceptors/headers.spec.js +0 -73
  82. package/src/worker/interceptors/workflow.spec.js +0 -357
  83. package/src/worker/interruption.spec.js +0 -177
  84. package/src/worker/loader/activities.spec.js +0 -212
  85. package/src/worker/loader/hooks.spec.js +0 -64
  86. package/src/worker/loader/matchers.spec.js +0 -140
  87. package/src/worker/loader/tools.spec.js +0 -595
  88. package/src/worker/loader/workflows.spec.js +0 -287
  89. package/src/worker/log_hooks.spec.js +0 -303
  90. package/src/worker/shutdown.spec.js +0 -197
  91. package/src/worker/sinks.spec.js +0 -220
  92. package/src/worker/telemetry.spec.js +0 -80
  93. package/src/worker/temporal_logger.spec.js +0 -90
  94. package/src/worker/webpack_loaders/tools.spec.js +0 -314
  95. package/src/worker/webpack_loaders/workflow_rewriter/collect_target_imports.spec.js +0 -134
  96. package/src/worker/webpack_loaders/workflow_rewriter/index.spec.js +0 -154
  97. package/src/worker/webpack_loaders/workflow_rewriter/rewrite_activity_calls.spec.js +0 -165
  98. package/src/worker/webpack_loaders/workflow_validator/index.spec.js +0 -202
  99. package/src/worker/webpack_loaders/workflow_validator/npm_workflow_export_resolve.spec.js +0 -374
  100. package/src/worker/worker_runner.spec.js +0 -220
@@ -1,287 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from 'vitest';
2
-
3
- vi.mock( '#consts', () => ( {
4
- ACTIVITY_SEND_HTTP_REQUEST: '__internal#sendHttpRequest',
5
- ACTIVITY_GET_TRACE_DESTINATIONS: '__internal#getTraceDestinations',
6
- WORKFLOWS_INDEX_FILENAME: '__workflows_entrypoint.js',
7
- WORKFLOW_CATALOG: 'catalog',
8
- ACTIVITY_OPTIONS_FILENAME: '__activity_options.js',
9
- WORKFLOW_OPTIONS_FILENAME: '__workflow_options.js'
10
- } ) );
11
-
12
- const { importComponentsMock, findWorkflowsInNodeModulesMock, matchFilesMock, writeFileInTempDirMock } = vi.hoisted( () => ( {
13
- importComponentsMock: vi.fn(),
14
- findWorkflowsInNodeModulesMock: vi.fn(),
15
- matchFilesMock: vi.fn(),
16
- writeFileInTempDirMock: vi.fn()
17
- } ) );
18
-
19
- const { workflowFileMatcherMock, workflowPathHasSharedMock } = vi.hoisted( () => ( {
20
- workflowFileMatcherMock: vi.fn(),
21
- workflowPathHasSharedMock: vi.fn()
22
- } ) );
23
-
24
- vi.mock( './tools.js', () => ( {
25
- importComponents: importComponentsMock,
26
- findWorkflowsInNodeModules: findWorkflowsInNodeModulesMock,
27
- matchFiles: matchFilesMock,
28
- writeFileInTempDir: writeFileInTempDirMock
29
- } ) );
30
-
31
- vi.mock( './matchers.js', () => ( {
32
- staticMatchers: {
33
- workflowFile: workflowFileMatcherMock,
34
- workflowPathHasShared: workflowPathHasSharedMock
35
- }
36
- } ) );
37
-
38
- describe( 'loadWorkflows', () => {
39
- beforeEach( () => {
40
- vi.clearAllMocks();
41
- importComponentsMock.mockReset();
42
- importComponentsMock.mockImplementation( async function *() {} );
43
- findWorkflowsInNodeModulesMock.mockReset();
44
- findWorkflowsInNodeModulesMock.mockReturnValue( [] );
45
- matchFilesMock.mockReset();
46
- matchFilesMock.mockReturnValue( [] );
47
- writeFileInTempDirMock.mockReset();
48
- writeFileInTempDirMock.mockImplementation( ( _, filename ) => `/tmp/${filename}` );
49
- workflowPathHasSharedMock.mockReset();
50
- workflowPathHasSharedMock.mockReturnValue( false );
51
- } );
52
-
53
- it( 'returns local workflows from importComponents with metadata spread onto each entry', async () => {
54
- const { loadWorkflows } = await import( './workflows.js' );
55
- const localFiles = [ { path: '/b/workflow.js', url: 'file:///b/workflow.js' } ];
56
- matchFilesMock.mockReturnValueOnce( localFiles );
57
-
58
- importComponentsMock.mockImplementationOnce( async function *() {
59
- yield { metadata: { name: 'Flow1', description: 'd' }, path: '/b/workflow.js' };
60
- } );
61
-
62
- const { workflows, entrypoint, optionsFile } = await loadWorkflows( '/root' );
63
- expect( workflows ).toEqual( [ { name: 'Flow1', description: 'd', path: '/b/workflow.js', external: false } ] );
64
- expect( entrypoint ).toBe( '/tmp/__workflows_entrypoint.js' );
65
- expect( optionsFile ).toBe( '/tmp/__workflow_options.js' );
66
- expect( importComponentsMock ).toHaveBeenNthCalledWith( 1, localFiles );
67
- expect( findWorkflowsInNodeModulesMock ).toHaveBeenCalledOnce();
68
- expect( findWorkflowsInNodeModulesMock ).toHaveBeenCalledWith( '/root' );
69
- } );
70
-
71
- it( 'calls matchFiles with rootDir and workflowFile matcher', async () => {
72
- const { loadWorkflows } = await import( './workflows.js' );
73
- const localFiles = [ { path: '/my/app/workflow.js', url: 'file:///my/app/workflow.js' } ];
74
- const externalFiles = [ { path: '/my/app/node_modules/pkg/workflow.js', url: 'file:///my/app/node_modules/pkg/workflow.js' } ];
75
- matchFilesMock.mockReturnValueOnce( localFiles );
76
- findWorkflowsInNodeModulesMock.mockReturnValue( externalFiles );
77
-
78
- await loadWorkflows( '/my/app' );
79
-
80
- expect( matchFilesMock ).toHaveBeenCalledOnce();
81
- expect( matchFilesMock ).toHaveBeenCalledWith( '/my/app', [ workflowFileMatcherMock ] );
82
- expect( importComponentsMock ).toHaveBeenCalledTimes( 1 );
83
- expect( importComponentsMock ).toHaveBeenNthCalledWith( 1, [ ...localFiles, ...externalFiles ] );
84
- expect( findWorkflowsInNodeModulesMock ).toHaveBeenCalledOnce();
85
- expect( findWorkflowsInNodeModulesMock ).toHaveBeenCalledWith( '/my/app' );
86
- } );
87
-
88
- it( 'appends node_modules workflows after local ones and sets external: true', async () => {
89
- const { loadWorkflows } = await import( './workflows.js' );
90
-
91
- importComponentsMock.mockImplementationOnce( async function *() {
92
- yield { metadata: { name: 'LocalFlow', description: 'local' }, path: '/my/app/workflows/wf/workflow.js' };
93
- yield {
94
- metadata: { name: '__sum_numbers', description: 'from catalog' },
95
- path: '/my/app/node_modules/catalog_pkg/src/w/workflow.js'
96
- };
97
- } );
98
- findWorkflowsInNodeModulesMock.mockReturnValue( [ { path: '/my/app/node_modules/catalog_pkg/src/w/workflow.js' } ] );
99
-
100
- const { workflows } = await loadWorkflows( '/my/app' );
101
- expect( workflows ).toEqual( [
102
- { name: 'LocalFlow', description: 'local', path: '/my/app/workflows/wf/workflow.js', external: false },
103
- {
104
- name: '__sum_numbers',
105
- description: 'from catalog',
106
- path: '/my/app/node_modules/catalog_pkg/src/w/workflow.js',
107
- external: true
108
- }
109
- ] );
110
-
111
- } );
112
-
113
- it( 'returns only external workflows when the project root has none', async () => {
114
- const { loadWorkflows } = await import( './workflows.js' );
115
-
116
- importComponentsMock.mockImplementationOnce( async function *() {
117
- yield { metadata: { name: 'PkgFlow', description: 'pkg' }, path: '/proj/node_modules/a/w/workflow.js' };
118
- } );
119
- findWorkflowsInNodeModulesMock.mockReturnValue( [ { path: '/proj/node_modules/a/w/workflow.js' } ] );
120
-
121
- const { workflows } = await loadWorkflows( '/proj' );
122
- expect( workflows ).toEqual( [
123
- {
124
- name: 'PkgFlow',
125
- description: 'pkg',
126
- path: '/proj/node_modules/a/w/workflow.js',
127
- external: true
128
- }
129
- ] );
130
- } );
131
-
132
- it( 'throws when a local workflow path is under a shared directory', async () => {
133
- const { loadWorkflows } = await import( './workflows.js' );
134
- importComponentsMock.mockImplementationOnce( async function *() {
135
- yield { metadata: { name: 'Invalid' }, path: '/root/shared/workflow.js' };
136
- } );
137
- workflowPathHasSharedMock.mockReturnValueOnce( true );
138
-
139
- await expect( loadWorkflows( '/root' ) ).rejects.toThrow( 'Workflow directory can\'t be named "shared"' );
140
- expect( findWorkflowsInNodeModulesMock ).toHaveBeenCalledOnce();
141
- expect( workflowPathHasSharedMock ).toHaveBeenCalledWith( '/root/shared/workflow.js' );
142
- } );
143
-
144
- it( 'throws when a workflow name conflicts with an earlier workflow name', async () => {
145
- const { loadWorkflows } = await import( './workflows.js' );
146
- importComponentsMock.mockImplementationOnce( async function *() {
147
- yield { metadata: { name: 'duplicate' }, path: '/root/a/workflow.js' };
148
- yield { metadata: { name: 'duplicate' }, path: '/root/b/workflow.js' };
149
- } );
150
-
151
- await expect( loadWorkflows( '/root' ) ).rejects.toThrow(
152
- 'Workflow name "duplicate" conflicts with another workflow or alias. Workflow names and aliases must be unique.'
153
- );
154
- } );
155
-
156
- it( 'throws when a workflow name conflicts with an earlier alias', async () => {
157
- const { loadWorkflows } = await import( './workflows.js' );
158
- importComponentsMock.mockImplementationOnce( async function *() {
159
- yield { metadata: { name: 'alpha', aliases: [ 'legacy' ] }, path: '/root/a/workflow.js' };
160
- yield { metadata: { name: 'legacy' }, path: '/root/b/workflow.js' };
161
- } );
162
-
163
- await expect( loadWorkflows( '/root' ) ).rejects.toThrow(
164
- 'Workflow name "legacy" conflicts with another workflow or alias. Workflow names and aliases must be unique.'
165
- );
166
- } );
167
-
168
- it( 'throws when an alias conflicts with an earlier workflow name', async () => {
169
- const { loadWorkflows } = await import( './workflows.js' );
170
- importComponentsMock.mockImplementationOnce( async function *() {
171
- yield { metadata: { name: 'alpha' }, path: '/root/a/workflow.js' };
172
- yield { metadata: { name: 'beta', aliases: [ 'alpha' ] }, path: '/root/b/workflow.js' };
173
- } );
174
-
175
- await expect( loadWorkflows( '/root' ) ).rejects.toThrow(
176
- 'Workflow "beta" alias "alpha" conflicts with another workflow or alias. Workflow names and aliases must be unique.'
177
- );
178
- } );
179
-
180
- it( 'throws when an alias conflicts with an earlier alias', async () => {
181
- const { loadWorkflows } = await import( './workflows.js' );
182
- importComponentsMock.mockImplementationOnce( async function *() {
183
- yield { metadata: { name: 'alpha', aliases: [ 'shared_alias' ] }, path: '/root/a/workflow.js' };
184
- yield { metadata: { name: 'beta', aliases: [ 'shared_alias' ] }, path: '/root/b/workflow.js' };
185
- } );
186
-
187
- await expect( loadWorkflows( '/root' ) ).rejects.toThrow(
188
- 'Workflow "beta" alias "shared_alias" conflicts with another workflow or alias. Workflow names and aliases must be unique.'
189
- );
190
- } );
191
-
192
- it( 'throws when an alias is identical to its workflow name', async () => {
193
- const { loadWorkflows } = await import( './workflows.js' );
194
- importComponentsMock.mockImplementationOnce( async function *() {
195
- yield { metadata: { name: 'alpha', aliases: [ 'alpha' ] }, path: '/root/a/workflow.js' };
196
- } );
197
-
198
- await expect( loadWorkflows( '/root' ) ).rejects.toThrow(
199
- 'Workflow "alpha" alias "alpha" conflicts with another workflow or alias. Workflow names and aliases must be unique.'
200
- );
201
- } );
202
-
203
- it( 'allows workflow names and aliases that only differ by case', async () => {
204
- const { loadWorkflows } = await import( './workflows.js' );
205
- importComponentsMock.mockImplementationOnce( async function *() {
206
- yield { metadata: { name: 'Alpha', aliases: [ 'Legacy' ] }, path: '/root/a/workflow.js' };
207
- yield { metadata: { name: 'alpha', aliases: [ 'legacy' ] }, path: '/root/b/workflow.js' };
208
- } );
209
-
210
- await expect( loadWorkflows( '/root' ) ).resolves.toMatchObject( {
211
- workflows: [
212
- { name: 'Alpha', aliases: [ 'Legacy' ], path: '/root/a/workflow.js', external: false },
213
- { name: 'alpha', aliases: [ 'legacy' ], path: '/root/b/workflow.js', external: false }
214
- ]
215
- } );
216
- } );
217
-
218
- it( 'throws when a workflow name is reserved for the internal catalog', async () => {
219
- const { loadWorkflows } = await import( './workflows.js' );
220
- importComponentsMock.mockImplementationOnce( async function *() {
221
- yield { metadata: { name: 'catalog' }, path: '/root/catalog/workflow.js' };
222
- } );
223
-
224
- await expect( loadWorkflows( '/root' ) ).rejects.toThrow(
225
- 'Workflow name "catalog" is reserved for the internal catalog workflow.'
226
- );
227
- } );
228
-
229
- it( 'throws when a workflow alias is reserved for the internal catalog', async () => {
230
- const { loadWorkflows } = await import( './workflows.js' );
231
- importComponentsMock.mockImplementationOnce( async function *() {
232
- yield { metadata: { name: 'alpha', aliases: [ 'catalog' ] }, path: '/root/a/workflow.js' };
233
- } );
234
-
235
- await expect( loadWorkflows( '/root' ) ).rejects.toThrow(
236
- 'Workflow "alpha" alias "catalog" is reserved for the internal catalog workflow.'
237
- );
238
- } );
239
-
240
- it( 'writes an entrypoint with workflows, aliases, and the catalog workflow', async () => {
241
- const { loadWorkflows } = await import( './workflows.js' );
242
- importComponentsMock.mockImplementationOnce( async function *() {
243
- yield { metadata: { name: 'W', aliases: [ 'W_old', 'W_legacy' ] }, path: '/abs/wf.js' };
244
- } );
245
-
246
- const { entrypoint } = await loadWorkflows( '/root' );
247
-
248
- expect( entrypoint ).toBe( '/tmp/__workflows_entrypoint.js' );
249
- expect( writeFileInTempDirMock ).toHaveBeenCalledTimes( 2 );
250
- const [ contents, filename ] = writeFileInTempDirMock.mock.calls.find( ( [ , calledFilename ] ) =>
251
- calledFilename === '__workflows_entrypoint.js'
252
- );
253
- expect( filename ).toBe( '__workflows_entrypoint.js' );
254
- expect( contents ).toContain( 'export { default as W } from \'/abs/wf.js\';' );
255
- expect( contents ).toContain( 'export { default as W_old } from \'/abs/wf.js\';' );
256
- expect( contents ).toContain( 'export { default as W_legacy } from \'/abs/wf.js\';' );
257
- expect( contents ).toContain( 'export { default as catalog }' );
258
- } );
259
-
260
- it( 'writes trace options for workflow names, aliases, and the catalog workflow', async () => {
261
- const { loadWorkflows } = await import( './workflows.js' );
262
- importComponentsMock.mockImplementationOnce( async function *() {
263
- yield {
264
- metadata: { name: 'Traced', aliases: [ 'Traced_old' ] },
265
- path: '/abs/traced.js'
266
- };
267
- yield {
268
- metadata: { name: 'Untraced', aliases: [ 'Untraced_old' ], options: { disableTrace: true } },
269
- path: '/abs/untraced.js'
270
- };
271
- } );
272
-
273
- await loadWorkflows( '/root' );
274
-
275
- const [ contents, filename ] = writeFileInTempDirMock.mock.calls.find( ( [ , calledFilename ] ) =>
276
- calledFilename === '__workflow_options.js'
277
- );
278
- expect( filename ).toBe( '__workflow_options.js' );
279
- expect( contents ).toBe( `export default ${JSON.stringify( {
280
- Traced: { disableTrace: false },
281
- Traced_old: { disableTrace: false },
282
- Untraced: { disableTrace: true },
283
- Untraced_old: { disableTrace: true },
284
- catalog: { disableTrace: true }
285
- }, undefined, 2 )};` );
286
- } );
287
- } );
@@ -1,303 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from 'vitest';
2
- import {
3
- ACTIVITY_GET_TRACE_DESTINATIONS,
4
- BusEventType,
5
- LifecycleEvent,
6
- WORKFLOW_CATALOG
7
- } from '#consts';
8
-
9
- const createLoggerMock = vi.hoisted( () => () => ( {
10
- error: vi.fn(),
11
- warn: vi.fn(),
12
- info: vi.fn(),
13
- http: vi.fn(),
14
- verbose: vi.fn(),
15
- debug: vi.fn(),
16
- silly: vi.fn()
17
- } ) );
18
- const activityLogMock = vi.hoisted( () => createLoggerMock() );
19
- const workflowLogMock = vi.hoisted( () => createLoggerMock() );
20
- const createChildLoggerMock = vi.hoisted( () =>
21
- vi.fn( name => ( name === 'Activity' ? activityLogMock : workflowLogMock ) )
22
- );
23
-
24
- const onHandlers = vi.hoisted( () => ( {} ) );
25
- const mainEventBusMock = vi.hoisted( () => ( {
26
- on: vi.fn( ( eventType, handler ) => {
27
- onHandlers[eventType] = handler;
28
- } )
29
- } ) );
30
- const serializeErrorMock = vi.hoisted( () => vi.fn( error => ( {
31
- name: error.name,
32
- message: error.message
33
- } ) ) );
34
-
35
- vi.mock( '#logger', () => ( { createChildLogger: createChildLoggerMock } ) );
36
- vi.mock( '#bus', () => ( { mainEventBus: mainEventBusMock } ) );
37
- vi.mock( '#helpers/error_serializer', () => ( { serializeError: serializeErrorMock } ) );
38
-
39
- import './log_hooks.js';
40
-
41
- describe( 'log_hooks', () => {
42
- beforeEach( () => {
43
- vi.clearAllMocks();
44
- } );
45
-
46
- describe( 'activity events', () => {
47
- const activityInfo = {
48
- activityId: 'act-1',
49
- activityType: 'myWorkflow#myStep',
50
- workflowExecution: { workflowId: 'wf-1', runId: 'run-1' },
51
- workflowType: 'myWorkflow'
52
- };
53
- const basePayload = {
54
- activityInfo,
55
- outputActivityKind: 'step'
56
- };
57
-
58
- it( 'ACTIVITY_START logs full message and second arg', () => {
59
- onHandlers[BusEventType.ACTIVITY_START]( basePayload );
60
-
61
- expect( activityLogMock.info ).toHaveBeenCalledTimes( 1 );
62
- expect( activityLogMock.info ).toHaveBeenCalledWith(
63
- 'Started myWorkflow#myStep step',
64
- {
65
- event: LifecycleEvent.START,
66
- activityId: 'act-1',
67
- activityType: 'myWorkflow#myStep',
68
- workflowId: 'wf-1',
69
- workflowType: 'myWorkflow',
70
- runId: 'run-1'
71
- }
72
- );
73
- } );
74
-
75
- it( 'ACTIVITY_START does not log trace destination activity', () => {
76
- onHandlers[BusEventType.ACTIVITY_START]( {
77
- ...basePayload,
78
- activityInfo: { ...activityInfo, activityType: ACTIVITY_GET_TRACE_DESTINATIONS }
79
- } );
80
-
81
- expect( activityLogMock.info ).not.toHaveBeenCalled();
82
- } );
83
-
84
- it( 'ACTIVITY_END logs full message and second arg', () => {
85
- onHandlers[BusEventType.ACTIVITY_END]( { ...basePayload, duration: 42 } );
86
-
87
- expect( activityLogMock.info ).toHaveBeenCalledTimes( 1 );
88
- expect( activityLogMock.info ).toHaveBeenCalledWith(
89
- 'Ended myWorkflow#myStep step',
90
- {
91
- event: LifecycleEvent.END,
92
- activityId: 'act-1',
93
- activityType: 'myWorkflow#myStep',
94
- workflowId: 'wf-1',
95
- workflowType: 'myWorkflow',
96
- runId: 'run-1'
97
- }
98
- );
99
- } );
100
-
101
- it( 'ACTIVITY_END does not log trace destination activity', () => {
102
- onHandlers[BusEventType.ACTIVITY_END]( {
103
- ...basePayload,
104
- activityInfo: { ...activityInfo, activityType: ACTIVITY_GET_TRACE_DESTINATIONS }
105
- } );
106
-
107
- expect( activityLogMock.info ).not.toHaveBeenCalled();
108
- } );
109
-
110
- it( 'ACTIVITY_ERROR logs full message and second arg', () => {
111
- const err = new Error( 'step failed' );
112
- err.name = 'ProviderError';
113
- onHandlers[BusEventType.ACTIVITY_ERROR]( {
114
- ...basePayload,
115
- duration: 100,
116
- error: err
117
- } );
118
-
119
- expect( activityLogMock.error ).toHaveBeenCalledTimes( 1 );
120
- expect( activityLogMock.error ).toHaveBeenCalledWith(
121
- 'Error myWorkflow#myStep step: ProviderError',
122
- {
123
- event: LifecycleEvent.ERROR,
124
- activityId: 'act-1',
125
- activityType: 'myWorkflow#myStep',
126
- workflowId: 'wf-1',
127
- workflowType: 'myWorkflow',
128
- runId: 'run-1',
129
- error: { name: 'ProviderError', message: 'step failed' }
130
- }
131
- );
132
- expect( serializeErrorMock ).toHaveBeenCalledWith( err, { dropKeys: [ 'stack' ] } );
133
- } );
134
-
135
- it( 'ACTIVITY_ERROR does not log trace destination activity', () => {
136
- onHandlers[BusEventType.ACTIVITY_ERROR]( {
137
- ...basePayload,
138
- activityInfo: { ...activityInfo, activityType: ACTIVITY_GET_TRACE_DESTINATIONS },
139
- error: new Error( 'x' )
140
- } );
141
-
142
- expect( activityLogMock.error ).not.toHaveBeenCalled();
143
- } );
144
-
145
- it( 'ACTIVITY_LOG logs dynamic levels with metadata and serialized activity fields', () => {
146
- onHandlers[BusEventType.ACTIVITY_LOG]( {
147
- activityInfo,
148
- level: 'debug',
149
- message: 'activity detail',
150
- metadata: {
151
- custom: 'value',
152
- workflowId: 'metadata-workflow-id'
153
- }
154
- } );
155
-
156
- expect( activityLogMock.debug ).toHaveBeenCalledTimes( 1 );
157
- expect( activityLogMock.debug ).toHaveBeenCalledWith( 'activity detail', {
158
- custom: 'value',
159
- activityId: 'act-1',
160
- activityType: 'myWorkflow#myStep',
161
- workflowId: 'wf-1',
162
- workflowType: 'myWorkflow',
163
- runId: 'run-1'
164
- } );
165
- } );
166
-
167
- it( 'ACTIVITY_LOG accepts omitted metadata', () => {
168
- onHandlers[BusEventType.ACTIVITY_LOG]( {
169
- activityInfo,
170
- level: 'info',
171
- message: 'activity detail'
172
- } );
173
-
174
- expect( activityLogMock.info ).toHaveBeenCalledWith( 'activity detail', {
175
- activityId: 'act-1',
176
- activityType: 'myWorkflow#myStep',
177
- workflowId: 'wf-1',
178
- workflowType: 'myWorkflow',
179
- runId: 'run-1'
180
- } );
181
- } );
182
- } );
183
-
184
- describe( 'workflow events', () => {
185
- const workflowDetails = {
186
- workflowId: 'wf-1',
187
- workflowType: 'myWorkflow',
188
- runId: 'run-1'
189
- };
190
- const basePayload = { workflowDetails };
191
-
192
- it( 'WORKFLOW_START logs full message and second arg', () => {
193
- onHandlers[BusEventType.WORKFLOW_START]( basePayload );
194
-
195
- expect( workflowLogMock.info ).toHaveBeenCalledTimes( 1 );
196
- expect( workflowLogMock.info ).toHaveBeenCalledWith(
197
- 'Started myWorkflow workflow',
198
- {
199
- event: LifecycleEvent.START,
200
- workflowId: 'wf-1',
201
- workflowType: 'myWorkflow',
202
- runId: 'run-1'
203
- }
204
- );
205
- } );
206
-
207
- it( 'WORKFLOW_START does not log when workflowType is WORKFLOW_CATALOG', () => {
208
- onHandlers[BusEventType.WORKFLOW_START]( {
209
- workflowDetails: { ...workflowDetails, workflowType: WORKFLOW_CATALOG }
210
- } );
211
-
212
- expect( workflowLogMock.info ).not.toHaveBeenCalled();
213
- } );
214
-
215
- it( 'WORKFLOW_END logs full message and second arg', () => {
216
- onHandlers[BusEventType.WORKFLOW_END]( basePayload );
217
-
218
- expect( workflowLogMock.info ).toHaveBeenCalledTimes( 1 );
219
- expect( workflowLogMock.info ).toHaveBeenCalledWith(
220
- 'Ended myWorkflow workflow',
221
- {
222
- event: LifecycleEvent.END,
223
- workflowId: 'wf-1',
224
- workflowType: 'myWorkflow',
225
- runId: 'run-1'
226
- }
227
- );
228
- } );
229
-
230
- it( 'WORKFLOW_END does not log when workflowType is WORKFLOW_CATALOG', () => {
231
- onHandlers[BusEventType.WORKFLOW_END]( {
232
- workflowDetails: { ...workflowDetails, workflowType: WORKFLOW_CATALOG }
233
- } );
234
-
235
- expect( workflowLogMock.info ).not.toHaveBeenCalled();
236
- } );
237
-
238
- it( 'WORKFLOW_ERROR logs full message and second arg', () => {
239
- const err = { name: 'TypeError', message: 'workflow boom' };
240
- onHandlers[BusEventType.WORKFLOW_ERROR]( {
241
- ...basePayload,
242
- duration: 150,
243
- error: err
244
- } );
245
-
246
- expect( workflowLogMock.error ).toHaveBeenCalledTimes( 1 );
247
- expect( workflowLogMock.error ).toHaveBeenCalledWith(
248
- 'Error myWorkflow workflow: TypeError',
249
- {
250
- event: LifecycleEvent.ERROR,
251
- workflowId: 'wf-1',
252
- workflowType: 'myWorkflow',
253
- runId: 'run-1',
254
- error: { name: 'TypeError', message: 'workflow boom' }
255
- }
256
- );
257
- expect( serializeErrorMock ).toHaveBeenCalledWith( err, { dropKeys: [ 'stack' ] } );
258
- } );
259
-
260
- it( 'WORKFLOW_ERROR does not log when workflowType is WORKFLOW_CATALOG', () => {
261
- onHandlers[BusEventType.WORKFLOW_ERROR]( {
262
- workflowDetails: { ...workflowDetails, workflowType: WORKFLOW_CATALOG },
263
- error: new Error( 'x' )
264
- } );
265
-
266
- expect( workflowLogMock.error ).not.toHaveBeenCalled();
267
- } );
268
-
269
- it( 'WORKFLOW_LOG logs dynamic levels with metadata and serialized workflow fields', () => {
270
- onHandlers[BusEventType.WORKFLOW_LOG]( {
271
- workflowDetails,
272
- level: 'warn',
273
- message: 'workflow detail',
274
- metadata: {
275
- custom: 'value',
276
- runId: 'metadata-run-id'
277
- }
278
- } );
279
-
280
- expect( workflowLogMock.warn ).toHaveBeenCalledTimes( 1 );
281
- expect( workflowLogMock.warn ).toHaveBeenCalledWith( 'workflow detail', {
282
- custom: 'value',
283
- workflowId: 'wf-1',
284
- workflowType: 'myWorkflow',
285
- runId: 'run-1'
286
- } );
287
- } );
288
-
289
- it( 'WORKFLOW_LOG accepts omitted metadata', () => {
290
- onHandlers[BusEventType.WORKFLOW_LOG]( {
291
- workflowDetails,
292
- level: 'info',
293
- message: 'workflow detail'
294
- } );
295
-
296
- expect( workflowLogMock.info ).toHaveBeenCalledWith( 'workflow detail', {
297
- workflowId: 'wf-1',
298
- workflowType: 'myWorkflow',
299
- runId: 'run-1'
300
- } );
301
- } );
302
- } );
303
- } );