diff --git a/README.md b/README.md index dbfa786..2babca5 100644 --- a/README.md +++ b/README.md @@ -162,7 +162,16 @@ Each execution is independent of all others, meaning that you can concurrently c - `waitTimeOverrides?`: An [object that overrides](/docs/feature-support.md#wait-state-duration-override) the wait duration of the specified `Wait` states. The specified override duration should be in milliseconds. - `retryIntervalOverrides?`: An [object that overrides](/docs/feature-support.md#retry-field-interval-override) the pause duration of the specified state's `Retry` field. The specified override duration should be a number in milliseconds; or an array of numbers, where each number represents milliseconds. - `noThrowOnAbort?`: If this option is set to `true`, aborting the execution will simply return `null` as result instead of throwing. - - `context?`: An object that will be used as the [Context Object](https://docs.aws.amazon.com/step-functions/latest/dg/input-output-contextobject.html) for the execution. If not passed, the Context Object will default to an empty object. This option is useful to mock the Context Object in case your definition references it in a JSONPath. + - `context?`: An object that will be used as the [Context Object](https://docs.aws.amazon.com/step-functions/latest/dg/input-output-contextobject.html) for the execution. If not passed, the Context Object will default to the following object: + ```js + { + "Execution": { + "Input": /* input passed to the execution */, + "StartTime": /* ISO 8601 timestamp of when the execution started */ + } + } + ``` + This option is useful to mock the fields of the Context Object in case your definition references it in a JSONPath. #### Return value diff --git a/examples/custom-context-object.js b/examples/custom-context-object.js index 7a33dce..106b729 100644 --- a/examples/custom-context-object.js +++ b/examples/custom-context-object.js @@ -9,6 +9,8 @@ const machineDefinition = { Parameters: { 'execId.$': '$$.Execution.Id', // JSONPaths starting with `$$` query the context object, not the input 'execName.$': '$$.Execution.Name', + 'execInput.$': '$$.Execution.Input', // '$$.Execution.Input' and '$$.Execution.StartTime' are always prepopulated, even if you don't explicitly provide them + 'execStartTime.$': '$$.Execution.StartTime', }, End: true, }, @@ -16,7 +18,7 @@ const machineDefinition = { }; const stateMachine = new StateMachine(machineDefinition); -const myInput = {}; +const myInput = { number: 10, string: 'Hello!' }; const contextObject = { Execution: { Id: 'some execution id', @@ -28,4 +30,10 @@ const execution = stateMachine.run(myInput, { }); const result = await execution.result; -console.log(result); // Logs `{ execId: 'some execution id', execName: 'execution name' }` +console.log(result); // Logs the following object: +// { +// execId: 'some execution id', +// execName: 'execution name', +// execInput: { number: 10, string: 'Hello!' }, +// execStartTime: '2023-12-13T02:10:53.153Z' +// } diff --git a/src/stateMachine/StateMachine.ts b/src/stateMachine/StateMachine.ts index a234966..637f049 100644 --- a/src/stateMachine/StateMachine.ts +++ b/src/stateMachine/StateMachine.ts @@ -144,7 +144,14 @@ export class StateMachine { private async execute(input: JSONValue, options: ExecuteOptions, cleanupFn: () => void): Promise { options.eventLogger.dispatchExecutionStartedEvent(input); - const context = options.runOptions?.context ?? {}; + const context = { + ...options.runOptions?.context, + Execution: { + ...options.runOptions?.context?.Execution, + Input: input, + StartTime: new Date().toISOString(), + }, + }; let currState = this.definition.States[this.definition.StartAt]; let currStateName = this.definition.StartAt; let currInput = cloneDeep(input); diff --git a/src/typings/Context.ts b/src/typings/Context.ts index 9a1d29a..fcd60d6 100644 --- a/src/typings/Context.ts +++ b/src/typings/Context.ts @@ -1 +1,12 @@ -export type Context = Record; +import type { JSONValue } from './JSONValue'; + +type ContextExecution = { + Input?: JSONValue; + StartTime?: string; + [other: string]: unknown; +}; + +export type Context = { + Execution?: ContextExecution; + [other: string]: unknown; +};