@usearazzo/runner 1.0.1-alpha.25 → 1.0.1-alpha.27
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/CHANGELOG.md +24 -0
- package/README.md +1 -1
- package/dist/arazzo-runner.browser.js +3390 -2932
- package/dist/arazzo-runner.browser.min.js +1 -1
- package/package.json +15 -15
- package/src/criterion/CriterionEvaluator.cjs +2 -2
- package/src/criterion/CriterionEvaluator.mjs +3 -3
- package/src/document/ArazzoDocument.cjs +3 -2
- package/src/document/ArazzoDocument.mjs +3 -2
- package/src/errors/ResolverError.cjs +7 -0
- package/src/errors/ResolverError.mjs +7 -0
- package/src/executor/StepExecutor.cjs +24 -1
- package/src/executor/StepExecutor.mjs +24 -1
- package/src/executor/StepRetryRunner.cjs +1 -1
- package/src/executor/StepRetryRunner.mjs +1 -1
- package/src/executor/WorkflowExecutor.cjs +112 -23
- package/src/executor/WorkflowExecutor.mjs +113 -24
- package/src/registry/providers/ArazzoDocumentRegistryProvider.cjs +3 -1
- package/src/registry/providers/ArazzoDocumentRegistryProvider.mjs +3 -1
- package/src/registry/providers/OpenAPIDocumentRegistryProvider.cjs +2 -0
- package/src/registry/providers/OpenAPIDocumentRegistryProvider.mjs +2 -0
- package/src/resolver/WorkflowParameterResolver.cjs +2 -1
- package/src/resolver/WorkflowParameterResolver.mjs +2 -1
- package/src/state/WorkflowExecutionState.cjs +3 -1
- package/src/state/WorkflowExecutionState.mjs +3 -1
- package/types/runner.d.ts +42 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@usearazzo/runner",
|
|
3
|
-
"version": "1.0.1-alpha.
|
|
3
|
+
"version": "1.0.1-alpha.27",
|
|
4
4
|
"description": "Runner for Arazzo Workflows.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"arazzo",
|
|
@@ -56,25 +56,25 @@
|
|
|
56
56
|
"author": "Vladimir Gorej <vladimir.gorej@gmail.com>",
|
|
57
57
|
"license": "Apache-2.0",
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@babel/runtime-corejs3": "^8.0
|
|
60
|
-
"@speclynx/apidom-core": "^
|
|
61
|
-
"@speclynx/apidom-datamodel": "^
|
|
62
|
-
"@speclynx/apidom-error": "^
|
|
63
|
-
"@speclynx/apidom-json-pointer": "^
|
|
64
|
-
"@speclynx/apidom-ns-arazzo-1": "^
|
|
65
|
-
"@speclynx/apidom-ns-openapi-2": "^
|
|
66
|
-
"@speclynx/apidom-ns-openapi-3-0": "^
|
|
67
|
-
"@speclynx/apidom-ns-openapi-3-1": "^
|
|
68
|
-
"@speclynx/apidom-reference": "^
|
|
69
|
-
"@speclynx/apidom-traverse": "^
|
|
59
|
+
"@babel/runtime-corejs3": "^8.1.0",
|
|
60
|
+
"@speclynx/apidom-core": "^7.0.1",
|
|
61
|
+
"@speclynx/apidom-datamodel": "^7.0.1",
|
|
62
|
+
"@speclynx/apidom-error": "^7.0.1",
|
|
63
|
+
"@speclynx/apidom-json-pointer": "^7.0.1",
|
|
64
|
+
"@speclynx/apidom-ns-arazzo-1": "^7.0.1",
|
|
65
|
+
"@speclynx/apidom-ns-openapi-2": "^7.0.1",
|
|
66
|
+
"@speclynx/apidom-ns-openapi-3-0": "^7.0.1",
|
|
67
|
+
"@speclynx/apidom-ns-openapi-3-1": "^7.0.1",
|
|
68
|
+
"@speclynx/apidom-reference": "^7.0.1",
|
|
69
|
+
"@speclynx/apidom-traverse": "^7.0.1",
|
|
70
70
|
"@swaggerexpert/arazzo-criterion": "^1.0.1",
|
|
71
71
|
"@swaggerexpert/arazzo-runtime-expression": "^3.3.0",
|
|
72
72
|
"@swaggerexpert/cookie": "^2.1.1",
|
|
73
73
|
"@swaggerexpert/json-pointer": "^3.0.2",
|
|
74
74
|
"@swaggerexpert/jsonpath": "^4.0.5",
|
|
75
75
|
"@swaggerexpert/media-types": "^1.0.2",
|
|
76
|
-
"@usearazzo/parser": "1.0.1-alpha.
|
|
77
|
-
"@usearazzo/resolver": "1.0.1-alpha.
|
|
76
|
+
"@usearazzo/parser": "1.0.1-alpha.27",
|
|
77
|
+
"@usearazzo/resolver": "1.0.1-alpha.27",
|
|
78
78
|
"@xmldom/xmldom": "^0.9.12",
|
|
79
79
|
"fontoxpath": "^3.34.0",
|
|
80
80
|
"ramda": "^0.32.0",
|
|
@@ -94,5 +94,5 @@
|
|
|
94
94
|
"devDependencies": {
|
|
95
95
|
"swagger-client": "^3.38.4"
|
|
96
96
|
},
|
|
97
|
-
"gitHead": "
|
|
97
|
+
"gitHead": "c2017ebba31c3a95f6f6dd0ba75058f0a19a8d0d"
|
|
98
98
|
}
|
|
@@ -167,7 +167,7 @@ class CriterionEvaluator {
|
|
|
167
167
|
#resolveType(criterion) {
|
|
168
168
|
const type = criterion.type;
|
|
169
169
|
if (type === undefined) return 'simple';
|
|
170
|
-
if ((0, _apidomNsArazzo.
|
|
170
|
+
if ((0, _apidomNsArazzo.isExpressionTypeElement)(type) && (0, _apidomDatamodel.isStringElement)(type.type)) {
|
|
171
171
|
return (0, _apidomCore.toValue)(type.type);
|
|
172
172
|
}
|
|
173
173
|
if ((0, _apidomDatamodel.isStringElement)(type)) return (0, _apidomCore.toValue)(type);
|
|
@@ -185,7 +185,7 @@ class CriterionEvaluator {
|
|
|
185
185
|
*/
|
|
186
186
|
#resolveVersion(criterion) {
|
|
187
187
|
const type = criterion.type;
|
|
188
|
-
if (!(0, _apidomNsArazzo.
|
|
188
|
+
if (!(0, _apidomNsArazzo.isExpressionTypeElement)(type) || type.version === undefined) {
|
|
189
189
|
return undefined;
|
|
190
190
|
}
|
|
191
191
|
if ((0, _apidomDatamodel.isStringElement)(type.version)) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { toValue } from '@speclynx/apidom-core';
|
|
2
2
|
import { isStringElement } from '@speclynx/apidom-datamodel';
|
|
3
|
-
import { isCriterionElement,
|
|
3
|
+
import { isCriterionElement, isExpressionTypeElement } from '@speclynx/apidom-ns-arazzo-1';
|
|
4
4
|
import { test as isRuntimeExpression } from '@swaggerexpert/arazzo-runtime-expression';
|
|
5
5
|
import CriterionError from "../errors/CriterionError.mjs";
|
|
6
6
|
import CriterionEvaluationError from "../errors/CriterionEvaluationError.mjs";
|
|
@@ -157,7 +157,7 @@ class CriterionEvaluator {
|
|
|
157
157
|
#resolveType(criterion) {
|
|
158
158
|
const type = criterion.type;
|
|
159
159
|
if (type === undefined) return 'simple';
|
|
160
|
-
if (
|
|
160
|
+
if (isExpressionTypeElement(type) && isStringElement(type.type)) {
|
|
161
161
|
return toValue(type.type);
|
|
162
162
|
}
|
|
163
163
|
if (isStringElement(type)) return toValue(type);
|
|
@@ -175,7 +175,7 @@ class CriterionEvaluator {
|
|
|
175
175
|
*/
|
|
176
176
|
#resolveVersion(criterion) {
|
|
177
177
|
const type = criterion.type;
|
|
178
|
-
if (!
|
|
178
|
+
if (!isExpressionTypeElement(type) || type.version === undefined) {
|
|
179
179
|
return undefined;
|
|
180
180
|
}
|
|
181
181
|
if (isStringElement(type.version)) {
|
|
@@ -56,8 +56,9 @@ class ArazzoDocument extends _APIDocument.default {
|
|
|
56
56
|
|
|
57
57
|
/**
|
|
58
58
|
* The workflows of this document that can be addressed by `workflowId`, in
|
|
59
|
-
* document order.
|
|
60
|
-
*
|
|
59
|
+
* document order. A duplicated `workflowId` is listed once, for its first
|
|
60
|
+
* workflow. Reads this document only: source descriptions are neither loaded
|
|
61
|
+
* nor listed.
|
|
61
62
|
*/
|
|
62
63
|
listWorkflows() {
|
|
63
64
|
return [...this.workflowIndex].map(([workflowId, jsonPointer]) => {
|
|
@@ -48,8 +48,9 @@ class ArazzoDocument extends APIDocument {
|
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
50
|
* The workflows of this document that can be addressed by `workflowId`, in
|
|
51
|
-
* document order.
|
|
52
|
-
*
|
|
51
|
+
* document order. A duplicated `workflowId` is listed once, for its first
|
|
52
|
+
* workflow. Reads this document only: source descriptions are neither loaded
|
|
53
|
+
* nor listed.
|
|
53
54
|
*/
|
|
54
55
|
listWorkflows() {
|
|
55
56
|
return [...this.workflowIndex].map(([workflowId, jsonPointer]) => {
|
|
@@ -15,6 +15,13 @@ var _ArazzoRunnerError = _interopRequireDefault(require("./ArazzoRunnerError.cjs
|
|
|
15
15
|
* @public
|
|
16
16
|
*/
|
|
17
17
|
class ResolverError extends _ArazzoRunnerError.default {
|
|
18
|
+
/**
|
|
19
|
+
* A parameter of a Success / Failure Action declares an `in` inline, which
|
|
20
|
+
* the Arazzo Specification forbids; one inherited from a
|
|
21
|
+
* `$components.parameters` Reusable Object maps by name instead. Thrown
|
|
22
|
+
* before the workflow's first request.
|
|
23
|
+
*/
|
|
24
|
+
static ActionParameterLocation = 'action-parameter-location';
|
|
18
25
|
/** A parameter cannot be delivered unambiguously at its location. */
|
|
19
26
|
static AmbiguousDelivery = 'ambiguous-delivery';
|
|
20
27
|
/** An output or a request body payload holds a value that is not a valid runtime expression. */
|
|
@@ -8,6 +8,13 @@ import ArazzoRunnerError from "./ArazzoRunnerError.mjs";
|
|
|
8
8
|
* @public
|
|
9
9
|
*/
|
|
10
10
|
class ResolverError extends ArazzoRunnerError {
|
|
11
|
+
/**
|
|
12
|
+
* A parameter of a Success / Failure Action declares an `in` inline, which
|
|
13
|
+
* the Arazzo Specification forbids; one inherited from a
|
|
14
|
+
* `$components.parameters` Reusable Object maps by name instead. Thrown
|
|
15
|
+
* before the workflow's first request.
|
|
16
|
+
*/
|
|
17
|
+
static ActionParameterLocation = 'action-parameter-location';
|
|
11
18
|
/** A parameter cannot be delivered unambiguously at its location. */
|
|
12
19
|
static AmbiguousDelivery = 'ambiguous-delivery';
|
|
13
20
|
/** An output or a request body payload holds a value that is not a valid runtime expression. */
|
|
@@ -224,7 +224,8 @@ class StepExecutor {
|
|
|
224
224
|
action: matchedActions[0],
|
|
225
225
|
matchedActions,
|
|
226
226
|
successCriteria,
|
|
227
|
-
actionCriteria
|
|
227
|
+
actionCriteria,
|
|
228
|
+
actionContext: this.actionContext(postContext, stepId, outputs)
|
|
228
229
|
};
|
|
229
230
|
}
|
|
230
231
|
|
|
@@ -366,6 +367,28 @@ class StepExecutor {
|
|
|
366
367
|
};
|
|
367
368
|
}
|
|
368
369
|
|
|
370
|
+
/**
|
|
371
|
+
* The context a step's actions are taken in — see
|
|
372
|
+
* {@link StepExecutionResult.actionContext}: `context` with
|
|
373
|
+
* `$steps.{stepId}.outputs` replaced by the outputs the attempt just
|
|
374
|
+
* resolved, as a fresh object, so run state is never written.
|
|
375
|
+
*
|
|
376
|
+
* Public for the same reason as {@link StepExecutor.selectActions}: the
|
|
377
|
+
* workflow executor builds this context for a step targeting a
|
|
378
|
+
* `workflowId`, which never reaches {@link StepExecutor.execute}.
|
|
379
|
+
*/
|
|
380
|
+
actionContext(context, stepId, outputs) {
|
|
381
|
+
return {
|
|
382
|
+
...context,
|
|
383
|
+
steps: {
|
|
384
|
+
...context.steps,
|
|
385
|
+
[stepId]: {
|
|
386
|
+
outputs
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
|
|
369
392
|
/**
|
|
370
393
|
* Evaluates one criterion into a {@link CriterionEvaluationRecord}. A
|
|
371
394
|
* condition that cannot be evaluated is unmet and records why; any other
|
|
@@ -217,7 +217,8 @@ class StepExecutor {
|
|
|
217
217
|
action: matchedActions[0],
|
|
218
218
|
matchedActions,
|
|
219
219
|
successCriteria,
|
|
220
|
-
actionCriteria
|
|
220
|
+
actionCriteria,
|
|
221
|
+
actionContext: this.actionContext(postContext, stepId, outputs)
|
|
221
222
|
};
|
|
222
223
|
}
|
|
223
224
|
|
|
@@ -359,6 +360,28 @@ class StepExecutor {
|
|
|
359
360
|
};
|
|
360
361
|
}
|
|
361
362
|
|
|
363
|
+
/**
|
|
364
|
+
* The context a step's actions are taken in — see
|
|
365
|
+
* {@link StepExecutionResult.actionContext}: `context` with
|
|
366
|
+
* `$steps.{stepId}.outputs` replaced by the outputs the attempt just
|
|
367
|
+
* resolved, as a fresh object, so run state is never written.
|
|
368
|
+
*
|
|
369
|
+
* Public for the same reason as {@link StepExecutor.selectActions}: the
|
|
370
|
+
* workflow executor builds this context for a step targeting a
|
|
371
|
+
* `workflowId`, which never reaches {@link StepExecutor.execute}.
|
|
372
|
+
*/
|
|
373
|
+
actionContext(context, stepId, outputs) {
|
|
374
|
+
return {
|
|
375
|
+
...context,
|
|
376
|
+
steps: {
|
|
377
|
+
...context.steps,
|
|
378
|
+
[stepId]: {
|
|
379
|
+
outputs
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
|
|
362
385
|
/**
|
|
363
386
|
* Evaluates one criterion into a {@link CriterionEvaluationRecord}. A
|
|
364
387
|
* condition that cannot be evaluated is unmet and records why; any other
|
|
@@ -149,7 +149,7 @@ class StepRetryRunner {
|
|
|
149
149
|
// zero/negative/NaN value.
|
|
150
150
|
const delayMs = this.#retryAfterMs(action);
|
|
151
151
|
if (delayMs > 0) await this.#sleep(delayMs, context.signal);
|
|
152
|
-
if (runReference !== undefined) await runReference(action);
|
|
152
|
+
if (runReference !== undefined) await runReference(action, outcome);
|
|
153
153
|
fired = true;
|
|
154
154
|
break;
|
|
155
155
|
}
|
|
@@ -139,7 +139,7 @@ class StepRetryRunner {
|
|
|
139
139
|
// zero/negative/NaN value.
|
|
140
140
|
const delayMs = this.#retryAfterMs(action);
|
|
141
141
|
if (delayMs > 0) await this.#sleep(delayMs, context.signal);
|
|
142
|
-
if (runReference !== undefined) await runReference(action);
|
|
142
|
+
if (runReference !== undefined) await runReference(action, outcome);
|
|
143
143
|
fired = true;
|
|
144
144
|
break;
|
|
145
145
|
}
|
|
@@ -301,6 +301,16 @@ class WorkflowExecutor {
|
|
|
301
301
|
// included: an unreadable assertion found at step three must not cost the
|
|
302
302
|
// run the requests of steps one and two.
|
|
303
303
|
for (const step of steps) this.#stepExecutor.assertSuccessCriteria(step, workflowId);
|
|
304
|
+
// and to every action's `parameters`, for the same reason: an `in` the
|
|
305
|
+
// specification forbids must not cost the run the requests before the
|
|
306
|
+
// step whose action carries it.
|
|
307
|
+
// the workflow's own default actions too: one every step overrides by
|
|
308
|
+
// name never reaches a step's list, yet the validator still reports it.
|
|
309
|
+
this.#assertActionParameters([workflow.successActions, workflow.failureActions], workflowId);
|
|
310
|
+
for (const step of steps) {
|
|
311
|
+
const stepId = (0, _apidomCore.toValue)(step.stepId);
|
|
312
|
+
this.#assertActionParameters([step.onSuccess, step.onFailure], workflowId, stepId);
|
|
313
|
+
}
|
|
304
314
|
const dependencies = await this.#runDependencies(workflow, invocation, scope);
|
|
305
315
|
if (dependencies.some(dependency => this.#settledFailed(dependency))) {
|
|
306
316
|
// a declared prerequisite did not complete, so this workflow cannot be
|
|
@@ -396,7 +406,7 @@ class WorkflowExecutor {
|
|
|
396
406
|
stepId,
|
|
397
407
|
callStack: nested
|
|
398
408
|
});
|
|
399
|
-
const transferredTo = await this.#runReferencedWorkflow(transition.workflowId, stepId, invocation, scope, 'goto');
|
|
409
|
+
const transferredTo = await this.#runReferencedWorkflow(transition.workflowId, stepId, invocation, scope, 'goto', this.#actionInputs(action?.parameters, outcome, invocation, stepId));
|
|
400
410
|
runOutcome = {
|
|
401
411
|
kind: 'transferred',
|
|
402
412
|
transferredTo
|
|
@@ -572,16 +582,16 @@ class WorkflowExecutor {
|
|
|
572
582
|
* for entering the reference itself, matching the "1 for the step itself
|
|
573
583
|
* plus whatever its sub-run spends" convention a sub-workflow step
|
|
574
584
|
* already follows (without it, a reference to a workflow with few or no
|
|
575
|
-
* steps of its own would cost nothing to fire).
|
|
576
|
-
*
|
|
577
|
-
*
|
|
578
|
-
*
|
|
579
|
-
*
|
|
580
|
-
* `
|
|
581
|
-
*
|
|
582
|
-
* or sub-workflow step sharing
|
|
583
|
-
* inputs value must not erase one
|
|
584
|
-
* already gave.
|
|
585
|
+
* steps of its own would cost nothing to fire). Its inputs are the
|
|
586
|
+
* action's `parameters` (`#115`), resolved again on every firing
|
|
587
|
+
* against the attempt that fired it — `{}` without them. Its outputs are
|
|
588
|
+
* recorded via `state.setWorkflow`, which *is* "context transfers back",
|
|
589
|
+
* together with the inputs it ran with when the action carries
|
|
590
|
+
* `parameters`. Without them, the recorded `inputs` are preserved rather
|
|
591
|
+
* than overwritten with `{}` when this workflowId was already recorded
|
|
592
|
+
* (by an earlier `dependsOn` prerequisite or sub-workflow step sharing
|
|
593
|
+
* the id): this call's own lack of a real inputs value must not erase one
|
|
594
|
+
* a different, better-informed caller already gave.
|
|
585
595
|
* - a `stepId` reference must name a step of the current workflow (checked
|
|
586
596
|
* lazily, at fire time, via the same lookup a `goto` target uses) and
|
|
587
597
|
* runs as one more attempt at that step, through
|
|
@@ -604,7 +614,7 @@ class WorkflowExecutor {
|
|
|
604
614
|
state,
|
|
605
615
|
callStack
|
|
606
616
|
} = invocation;
|
|
607
|
-
return async action => {
|
|
617
|
+
return async (action, outcome) => {
|
|
608
618
|
(0, _abort.throwIfAborted)(scope.signal, {
|
|
609
619
|
workflowId,
|
|
610
620
|
stepId,
|
|
@@ -623,13 +633,16 @@ class WorkflowExecutor {
|
|
|
623
633
|
}
|
|
624
634
|
if (hasWorkflowId) {
|
|
625
635
|
const reference = (0, _apidomCore.toValue)(action.workflowId);
|
|
636
|
+
// resolved before the budget is charged, so an authoring error in them
|
|
637
|
+
// costs no budget unit.
|
|
638
|
+
const inputs = this.#actionInputs(action.parameters, outcome, invocation, stepId);
|
|
626
639
|
this.#chargeBudget(scope, invocation, stepId);
|
|
627
|
-
const result = await this.#runReferencedWorkflow(reference, stepId, invocation, scope, 'retry');
|
|
640
|
+
const result = await this.#runReferencedWorkflow(reference, stepId, invocation, scope, 'retry', inputs);
|
|
628
641
|
// the result's workflowId is the bare id the reference resolved to —
|
|
629
642
|
// the key run state is recorded under, whichever document owns it.
|
|
630
643
|
const refId = result.workflowId;
|
|
631
644
|
state.setWorkflow(refId, {
|
|
632
|
-
inputs: state.getWorkflow(refId)?.inputs ?? {},
|
|
645
|
+
inputs: action.hasKey('parameters') ? inputs : state.getWorkflow(refId)?.inputs ?? {},
|
|
633
646
|
outputs: result.outputs
|
|
634
647
|
});
|
|
635
648
|
retryReferences.push({
|
|
@@ -647,12 +660,12 @@ class WorkflowExecutor {
|
|
|
647
660
|
});
|
|
648
661
|
const refStep = steps[refIndex];
|
|
649
662
|
const refSubWorkflows = [];
|
|
650
|
-
const
|
|
651
|
-
state.setStepOutputs(
|
|
663
|
+
const refOutcome = await this.#chargedAttempt(this.#stepAttempt(refStep, refStepId, invocation, scope, refSubWorkflows), invocation, scope, refStepId)();
|
|
664
|
+
state.setStepOutputs(refOutcome.stepId, refOutcome.outputs);
|
|
652
665
|
retryReferences.push({
|
|
653
666
|
kind: 'step',
|
|
654
667
|
id: refStepId,
|
|
655
|
-
successful:
|
|
668
|
+
successful: refOutcome.successful,
|
|
656
669
|
...(refSubWorkflows.length > 0 ? {
|
|
657
670
|
subWorkflow: refSubWorkflows[0]
|
|
658
671
|
} : {})
|
|
@@ -905,7 +918,8 @@ class WorkflowExecutor {
|
|
|
905
918
|
action: matchedActions[0],
|
|
906
919
|
matchedActions,
|
|
907
920
|
successCriteria,
|
|
908
|
-
actionCriteria
|
|
921
|
+
actionCriteria,
|
|
922
|
+
actionContext: stepExecutor.actionContext(context, stepId, outputs)
|
|
909
923
|
};
|
|
910
924
|
};
|
|
911
925
|
}
|
|
@@ -962,20 +976,95 @@ class WorkflowExecutor {
|
|
|
962
976
|
/**
|
|
963
977
|
* Runs a workflow an action references directly — a retry's `workflowId`
|
|
964
978
|
* reference or a goto's transfer, plain id or cross-document expression —
|
|
965
|
-
* with
|
|
966
|
-
*
|
|
979
|
+
* with the inputs its action's `parameters` resolved to (`#115`), `{}`
|
|
980
|
+
* without them.
|
|
967
981
|
*
|
|
968
982
|
* Shared rather than duplicated by its two callers, which otherwise repeat
|
|
969
|
-
* the identical "resolve the reference, then run
|
|
983
|
+
* the identical "resolve the reference, then run it" sequence.
|
|
970
984
|
* A target its document does not define is rejected by the normalizer,
|
|
971
985
|
* attributed to the calling workflow and `stepId`.
|
|
972
986
|
*/
|
|
973
|
-
async #runReferencedWorkflow(reference, stepId, invocation, scope, via) {
|
|
987
|
+
async #runReferencedWorkflow(reference, stepId, invocation, scope, via, inputs) {
|
|
974
988
|
const locator = await this.#workflowLocatorNormalizer.normalize(reference, invocation.document, {
|
|
975
989
|
workflowId: invocation.workflowId,
|
|
976
990
|
stepId
|
|
977
991
|
});
|
|
978
|
-
return this.#run(locator,
|
|
992
|
+
return this.#run(locator, inputs, scope, invocation.callStack, via);
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
/**
|
|
996
|
+
* The inputs a `goto` / `retry` action naming a `workflowId` passes its
|
|
997
|
+
* target: the action's own `parameters`, mapped by name and resolved against
|
|
998
|
+
* the context of the attempt that fired it — `$statusCode`, `$response.*`
|
|
999
|
+
* and the rest of that step outcome, plus the outputs it just produced.
|
|
1000
|
+
* Resolved against the calling invocation's document, so its `$components`
|
|
1001
|
+
* apply, never the target's. No `parameters` gives `{}`. Their shape was
|
|
1002
|
+
* checked before the workflow's first request, by
|
|
1003
|
+
* {@link WorkflowExecutor.#assertActionParameters}.
|
|
1004
|
+
*/
|
|
1005
|
+
#actionInputs(parameters, outcome, invocation, stepId) {
|
|
1006
|
+
const {
|
|
1007
|
+
workflowId,
|
|
1008
|
+
document
|
|
1009
|
+
} = invocation;
|
|
1010
|
+
return this.#parameterResolver.resolve(parameters, expression => this.#evaluate(outcome.actionContext, expression, document), {
|
|
1011
|
+
workflowId,
|
|
1012
|
+
stepId
|
|
1013
|
+
});
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
/**
|
|
1017
|
+
* Throws {@link ResolverError} unless every action in `lists` — a step's
|
|
1018
|
+
* `onSuccess` / `onFailure`, or the workflow's own `successActions` /
|
|
1019
|
+
* `failureActions` — has an absent `parameters` or a list free of inline `in`:
|
|
1020
|
+
* `malformed-parameters` for one that is present but not a list,
|
|
1021
|
+
* `action-parameter-location` for a Parameter Object that declares `in`. The
|
|
1022
|
+
* specification says outright that "The `in` field MUST NOT be used" on
|
|
1023
|
+
* them. An `in` arriving through a `$components.parameters` Reusable Object
|
|
1024
|
+
* is not inline — a shared component carries `in` for the operation steps
|
|
1025
|
+
* that use it — and the dereferencer marks the transcluded copy with
|
|
1026
|
+
* `ref-fields`.
|
|
1027
|
+
*
|
|
1028
|
+
* Checked for every action, `workflowId` or not, before any step of the
|
|
1029
|
+
* workflow runs: both are authoring errors the validator reports, so a run
|
|
1030
|
+
* must not make requests on the way to discovering them. Valid `parameters`
|
|
1031
|
+
* on an action naming no `workflowId` are still ignored, as the validator
|
|
1032
|
+
* only warns about them. A list that is not an array is skipped here and left
|
|
1033
|
+
* for the code that reads it to report. `stepId` is absent for the
|
|
1034
|
+
* workflow's own lists, and the error then names the workflow alone.
|
|
1035
|
+
*/
|
|
1036
|
+
#assertActionParameters(lists, workflowId, stepId) {
|
|
1037
|
+
const owner = stepId === undefined ? `workflow "${workflowId}"` : `step "${stepId}" in workflow "${workflowId}"`;
|
|
1038
|
+
for (const actions of lists) {
|
|
1039
|
+
if (!(0, _apidomDatamodel.isArrayElement)(actions)) continue;
|
|
1040
|
+
for (const action of actions) {
|
|
1041
|
+
if (!(0, _apidomNsArazzo.isSuccessActionElement)(action) && !(0, _apidomNsArazzo.isFailureActionElement)(action)) continue;
|
|
1042
|
+
if (!action.hasKey('parameters')) continue;
|
|
1043
|
+
const scope = {
|
|
1044
|
+
workflowId,
|
|
1045
|
+
...(stepId === undefined ? {} : {
|
|
1046
|
+
stepId
|
|
1047
|
+
}),
|
|
1048
|
+
target: 'parameters'
|
|
1049
|
+
};
|
|
1050
|
+
const {
|
|
1051
|
+
parameters
|
|
1052
|
+
} = action;
|
|
1053
|
+
if (!(0, _apidomDatamodel.isArrayElement)(parameters)) {
|
|
1054
|
+
throw new _ResolverError.default('`parameters` is present but is not a list', {
|
|
1055
|
+
...scope,
|
|
1056
|
+
reason: _ResolverError.default.MalformedParameters
|
|
1057
|
+
});
|
|
1058
|
+
}
|
|
1059
|
+
const inline = [...parameters].some(parameter => (0, _apidomNsArazzo.isParameterElement)(parameter) && parameter.hasKey('in') && !parameter.meta.hasKey('ref-fields'));
|
|
1060
|
+
if (inline) {
|
|
1061
|
+
throw new _ResolverError.default(`An action parameter of ${owner} declares an \`in\`; action parameters map to the target workflow's inputs by name`, {
|
|
1062
|
+
...scope,
|
|
1063
|
+
reason: _ResolverError.default.ActionParameterLocation
|
|
1064
|
+
});
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
979
1068
|
}
|
|
980
1069
|
|
|
981
1070
|
/**
|