@usearazzo/runner 0.0.0-stage → 1.0.1-alpha.11

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 (154) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +20 -0
  4. package/README.md +163 -2
  5. package/dist/arazzo-runner.browser.js +113245 -0
  6. package/dist/arazzo-runner.browser.min.js +1 -0
  7. package/package.json +95 -4
  8. package/src/ArazzoRunner.cjs +122 -0
  9. package/src/ArazzoRunner.mjs +113 -0
  10. package/src/action/ActionResolver.cjs +160 -0
  11. package/src/action/ActionResolver.mjs +150 -0
  12. package/src/assembler/OpenAPI2DocumentAssembler.cjs +111 -0
  13. package/src/assembler/OpenAPI2DocumentAssembler.mjs +104 -0
  14. package/src/assembler/OpenAPI30DocumentAssembler.cjs +110 -0
  15. package/src/assembler/OpenAPI30DocumentAssembler.mjs +103 -0
  16. package/src/assembler/OpenAPI31DocumentAssembler.cjs +111 -0
  17. package/src/assembler/OpenAPI31DocumentAssembler.mjs +104 -0
  18. package/src/assembler/OpenAPIDocumentAssembler.cjs +58 -0
  19. package/src/assembler/OpenAPIDocumentAssembler.mjs +50 -0
  20. package/src/client/HTTPClient.cjs +5 -0
  21. package/src/client/HTTPClient.mjs +1 -0
  22. package/src/client/HTTPClientFetch.cjs +16 -0
  23. package/src/client/HTTPClientFetch.mjs +10 -0
  24. package/src/client/OpenAPIOperationRequest.cjs +5 -0
  25. package/src/client/OpenAPIOperationRequest.mjs +1 -0
  26. package/src/client/OpenAPIOperationResponse.cjs +42 -0
  27. package/src/client/OpenAPIOperationResponse.mjs +36 -0
  28. package/src/client/OpenAPIOperationResponseNormalizer.cjs +48 -0
  29. package/src/client/OpenAPIOperationResponseNormalizer.mjs +40 -0
  30. package/src/client/ParameterDelivery.cjs +119 -0
  31. package/src/client/ParameterDelivery.mjs +113 -0
  32. package/src/constants.cjs +9 -0
  33. package/src/constants.mjs +3 -0
  34. package/src/criterion/CriterionEvaluator.cjs +205 -0
  35. package/src/criterion/CriterionEvaluator.mjs +196 -0
  36. package/src/criterion/JSONPathCriterionEvaluator.cjs +47 -0
  37. package/src/criterion/JSONPathCriterionEvaluator.mjs +40 -0
  38. package/src/criterion/RegexCriterionEvaluator.cjs +67 -0
  39. package/src/criterion/RegexCriterionEvaluator.mjs +60 -0
  40. package/src/criterion/SimpleCriterionEvaluator.cjs +50 -0
  41. package/src/criterion/SimpleCriterionEvaluator.mjs +43 -0
  42. package/src/criterion/XPathCriterionEvaluator.cjs +117 -0
  43. package/src/criterion/XPathCriterionEvaluator.mjs +109 -0
  44. package/src/document/APIDocument.cjs +35 -0
  45. package/src/document/APIDocument.mjs +30 -0
  46. package/src/document/ArazzoDocument.cjs +81 -0
  47. package/src/document/ArazzoDocument.mjs +74 -0
  48. package/src/document/ArazzoSourceDescriptionIndex.cjs +26 -0
  49. package/src/document/ArazzoSourceDescriptionIndex.mjs +20 -0
  50. package/src/document/ArazzoStepIndex.cjs +25 -0
  51. package/src/document/ArazzoStepIndex.mjs +19 -0
  52. package/src/document/ArazzoWorkflowIndex.cjs +17 -0
  53. package/src/document/ArazzoWorkflowIndex.mjs +11 -0
  54. package/src/document/OpenAPIDocument.cjs +28 -0
  55. package/src/document/OpenAPIDocument.mjs +21 -0
  56. package/src/document/OpenAPIOperationIndex.cjs +24 -0
  57. package/src/document/OpenAPIOperationIndex.mjs +18 -0
  58. package/src/document/ParameterIdentity.cjs +93 -0
  59. package/src/document/ParameterIdentity.mjs +88 -0
  60. package/src/document/openapi-types.cjs +5 -0
  61. package/src/document/openapi-types.mjs +1 -0
  62. package/src/errors/ArazzoRunnerError.cjs +10 -0
  63. package/src/errors/ArazzoRunnerError.mjs +5 -0
  64. package/src/errors/AssemblerError.cjs +11 -0
  65. package/src/errors/AssemblerError.mjs +4 -0
  66. package/src/errors/ClientError.cjs +11 -0
  67. package/src/errors/ClientError.mjs +4 -0
  68. package/src/errors/CriterionError.cjs +11 -0
  69. package/src/errors/CriterionError.mjs +4 -0
  70. package/src/errors/ExecutionError.cjs +11 -0
  71. package/src/errors/ExecutionError.mjs +4 -0
  72. package/src/errors/ExtractionError.cjs +11 -0
  73. package/src/errors/ExtractionError.mjs +4 -0
  74. package/src/errors/InvalidEntryDocumentError.cjs +11 -0
  75. package/src/errors/InvalidEntryDocumentError.mjs +4 -0
  76. package/src/errors/NormalizationError.cjs +11 -0
  77. package/src/errors/NormalizationError.mjs +4 -0
  78. package/src/errors/ResolverError.cjs +11 -0
  79. package/src/errors/ResolverError.mjs +4 -0
  80. package/src/errors/RuntimeExpressionError.cjs +11 -0
  81. package/src/errors/RuntimeExpressionError.mjs +4 -0
  82. package/src/errors/UnmatchedProviderError.cjs +11 -0
  83. package/src/errors/UnmatchedProviderError.mjs +4 -0
  84. package/src/executor/ArazzoWorkflowLocatorNormalizer.cjs +147 -0
  85. package/src/executor/ArazzoWorkflowLocatorNormalizer.mjs +137 -0
  86. package/src/executor/OpenAPIOperationExecutor.cjs +458 -0
  87. package/src/executor/OpenAPIOperationExecutor.mjs +447 -0
  88. package/src/executor/OpenAPIOperationLocatorNormalizer.cjs +197 -0
  89. package/src/executor/OpenAPIOperationLocatorNormalizer.mjs +189 -0
  90. package/src/executor/SourceDescriptionsLocatorNormalizer.cjs +44 -0
  91. package/src/executor/SourceDescriptionsLocatorNormalizer.mjs +38 -0
  92. package/src/executor/StepExecutor.cjs +333 -0
  93. package/src/executor/StepExecutor.mjs +326 -0
  94. package/src/executor/StepRetryRunner.cjs +226 -0
  95. package/src/executor/StepRetryRunner.mjs +215 -0
  96. package/src/executor/StepTransitionInterpreter.cjs +159 -0
  97. package/src/executor/StepTransitionInterpreter.mjs +151 -0
  98. package/src/executor/WorkflowCallStack.cjs +116 -0
  99. package/src/executor/WorkflowCallStack.mjs +106 -0
  100. package/src/executor/WorkflowExecutor.cjs +1091 -0
  101. package/src/executor/WorkflowExecutor.mjs +1077 -0
  102. package/src/executor/abort.cjs +70 -0
  103. package/src/executor/abort.mjs +60 -0
  104. package/src/expression/RuntimeExpressionContext.cjs +5 -0
  105. package/src/expression/RuntimeExpressionContext.mjs +1 -0
  106. package/src/expression/RuntimeExpressionEvaluator.cjs +337 -0
  107. package/src/expression/RuntimeExpressionEvaluator.mjs +328 -0
  108. package/src/extractor/ArazzoStepExtractor.cjs +48 -0
  109. package/src/extractor/ArazzoStepExtractor.mjs +41 -0
  110. package/src/extractor/ArazzoWorkflowExtractor.cjs +50 -0
  111. package/src/extractor/ArazzoWorkflowExtractor.mjs +43 -0
  112. package/src/extractor/OpenAPIOperationExtractor.cjs +84 -0
  113. package/src/extractor/OpenAPIOperationExtractor.mjs +77 -0
  114. package/src/index.cjs +426 -0
  115. package/src/index.mjs +75 -0
  116. package/src/normalizer/ArazzoStepNormalizer.cjs +23 -0
  117. package/src/normalizer/ArazzoStepNormalizer.mjs +17 -0
  118. package/src/normalizer/ArazzoWorkflowNormalizer.cjs +214 -0
  119. package/src/normalizer/ArazzoWorkflowNormalizer.mjs +206 -0
  120. package/src/normalizer/OpenAPI2OperationNormalizer.cjs +128 -0
  121. package/src/normalizer/OpenAPI2OperationNormalizer.mjs +120 -0
  122. package/src/normalizer/OpenAPI30OperationNormalizer.cjs +129 -0
  123. package/src/normalizer/OpenAPI30OperationNormalizer.mjs +121 -0
  124. package/src/normalizer/OpenAPI31OperationNormalizer.cjs +131 -0
  125. package/src/normalizer/OpenAPI31OperationNormalizer.mjs +123 -0
  126. package/src/normalizer/OpenAPIOperationNormalizer.cjs +58 -0
  127. package/src/normalizer/OpenAPIOperationNormalizer.mjs +50 -0
  128. package/src/registry/DocumentRegistry.cjs +160 -0
  129. package/src/registry/DocumentRegistry.mjs +151 -0
  130. package/src/registry/providers/ArazzoDocumentRegistryProvider.cjs +154 -0
  131. package/src/registry/providers/ArazzoDocumentRegistryProvider.mjs +146 -0
  132. package/src/registry/providers/DocumentRegistryProvider.cjs +31 -0
  133. package/src/registry/providers/DocumentRegistryProvider.mjs +25 -0
  134. package/src/registry/providers/OpenAPIDocumentRegistryProvider.cjs +122 -0
  135. package/src/registry/providers/OpenAPIDocumentRegistryProvider.mjs +114 -0
  136. package/src/resolver/ArazzoValueResolver.cjs +42 -0
  137. package/src/resolver/ArazzoValueResolver.mjs +37 -0
  138. package/src/resolver/OpenAPIOperationParameterResolver.cjs +117 -0
  139. package/src/resolver/OpenAPIOperationParameterResolver.mjs +110 -0
  140. package/src/resolver/OutputResolver.cjs +71 -0
  141. package/src/resolver/OutputResolver.mjs +64 -0
  142. package/src/resolver/RequestBodyResolver.cjs +227 -0
  143. package/src/resolver/RequestBodyResolver.mjs +220 -0
  144. package/src/resolver/ResolverScope.cjs +5 -0
  145. package/src/resolver/ResolverScope.mjs +1 -0
  146. package/src/resolver/StepParameterResolver.cjs +22 -0
  147. package/src/resolver/StepParameterResolver.mjs +15 -0
  148. package/src/resolver/WorkflowParameterResolver.cjs +73 -0
  149. package/src/resolver/WorkflowParameterResolver.mjs +66 -0
  150. package/src/state/WorkflowExecutionState.cjs +99 -0
  151. package/src/state/WorkflowExecutionState.mjs +93 -0
  152. package/src/vendor/swagger-client.cjs +1 -0
  153. package/src/vendor/swagger-client.mjs +1 -0
  154. package/types/runner.d.ts +2410 -0
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
4
+ var _interopRequireWildcard = require("@babel/runtime-corejs3/helpers/interopRequireWildcard").default;
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.providerOptionsOverride = exports.default = void 0;
9
+ var _parser = require("@usearazzo/parser");
10
+ var _resolver = require("@usearazzo/resolver");
11
+ var _apidomDatamodel = require("@speclynx/apidom-datamodel");
12
+ var _empty = require("@speclynx/apidom-reference/configuration/empty");
13
+ var _apidomTraverse = require("@speclynx/apidom-traverse");
14
+ var _apidomCore = require("@speclynx/apidom-core");
15
+ var constants = _interopRequireWildcard(require("../../constants.cjs"));
16
+ var _OpenAPIDocument = _interopRequireDefault(require("../../document/OpenAPIDocument.cjs"));
17
+ var _DocumentRegistryProvider = _interopRequireWildcard(require("./DocumentRegistryProvider.cjs"));
18
+ var _OpenAPIOperationIndex = _interopRequireDefault(require("../../document/OpenAPIOperationIndex.cjs"));
19
+ /**
20
+ * Options for loading an OpenAPI document.
21
+ * @public
22
+ */
23
+
24
+ /**
25
+ * Default options for loading an OpenAPI document.
26
+ */
27
+ const providerOptionsOverride = exports.providerOptionsOverride = {
28
+ resolve: {
29
+ resolverOpts: {
30
+ cache: {
31
+ maxEntries: constants.MAX_HTTP_CACHE_ENTRIES,
32
+ maxStaleAge: constants.MAX_HTTP_CACHE_STALE_AGE
33
+ }
34
+ }
35
+ },
36
+ dereference: {
37
+ immutable: false,
38
+ circular: 'replace',
39
+ circularReplacer: _DocumentRegistryProvider.circularReplacer
40
+ }
41
+ };
42
+
43
+ /**
44
+ * Provides OpenAPIDocument instances for the DocumentRegistry.
45
+ *
46
+ * Parses, dereferences, and builds an OperationIndex for OpenAPI documents.
47
+ * @public
48
+ */
49
+ class OpenAPIDocumentRegistryProvider extends _DocumentRegistryProvider.default {
50
+ #options;
51
+ constructor(options = {}) {
52
+ super();
53
+ this.#options = (0, _empty.mergeOptions)(providerOptionsOverride, options);
54
+ }
55
+ async canProvide(uri) {
56
+ try {
57
+ const options = this.#buildParseOptions();
58
+ const data = await (0, _empty.readFile)(uri, options);
59
+ const file = new _empty.File({
60
+ uri,
61
+ data
62
+ });
63
+ const parsers = options.parse.parsers.filter(p => p.name.startsWith('openapi'));
64
+ for (const parser of parsers) {
65
+ if (await parser.canParse(file)) return true;
66
+ }
67
+ } catch (error) {
68
+ if (error instanceof _empty.UnmatchedResolverError) return false;
69
+ throw error;
70
+ }
71
+ return false;
72
+ }
73
+
74
+ /**
75
+ * Loads an OpenAPI document from a URI and produces an OpenAPIDocument.
76
+ */
77
+ async provide(uri) {
78
+ const parseResult = await (0, _parser.parseOpenAPI)(uri, this.#buildParseOptions());
79
+ const operationIndex = await this.#buildOperationIndex(parseResult);
80
+ return new _OpenAPIDocument.default(uri, parseResult, operationIndex);
81
+ }
82
+ async #buildOperationIndex(parseResult) {
83
+ const index = new _OpenAPIOperationIndex.default();
84
+ const dereferenceOptions = this.#buildDereferenceOptions(parseResult);
85
+ const apiDereferenced = await (0, _apidomTraverse.traverseAsync)(parseResult.api, {
86
+ async PathItemElement(path) {
87
+ const pathItem = path.node;
88
+ if (!pathItem.hasMetaProperty('path')) return path.skip();
89
+ if (!(0, _apidomDatamodel.isStringElement)(pathItem.$ref)) return;
90
+ const pathItemDereferenced = await (0, _resolver.dereferenceOpenAPIElement)(pathItem, dereferenceOptions);
91
+ path.replaceWith(pathItemDereferenced);
92
+ },
93
+ OperationElement(path) {
94
+ const operation = path.node;
95
+ const operationId = (0, _apidomCore.toValue)(operation.operationId);
96
+ if (typeof operationId !== 'string') return path.skip();
97
+ if (operationId === '') return path.skip();
98
+ index.set(operationId, path.formatPath('jsonpointer'));
99
+ path.skip();
100
+ }
101
+ });
102
+ parseResult.replaceResult(apiDereferenced);
103
+ return index;
104
+ }
105
+ #buildParseOptions() {
106
+ return (0, _empty.mergeOptions)(_parser.defaultParseOpenAPIOptions, this.#options);
107
+ }
108
+ #buildDereferenceOptions(parseResult) {
109
+ let options = (0, _empty.mergeOptions)(_resolver.defaultDereferenceOpenAPIOptions, this.#options);
110
+ if (parseResult) {
111
+ options = (0, _empty.mergeOptions)(options, {
112
+ dereference: {
113
+ strategyOpts: {
114
+ parseResult
115
+ }
116
+ }
117
+ });
118
+ }
119
+ return options;
120
+ }
121
+ }
122
+ var _default = exports.default = OpenAPIDocumentRegistryProvider;
@@ -0,0 +1,114 @@
1
+ import { parseOpenAPI, defaultParseOpenAPIOptions } from '@usearazzo/parser';
2
+ import { dereferenceOpenAPIElement, defaultDereferenceOpenAPIOptions } from '@usearazzo/resolver';
3
+ import { isStringElement } from '@speclynx/apidom-datamodel';
4
+ import { readFile, File, mergeOptions } from '@speclynx/apidom-reference/configuration/empty';
5
+ import { UnmatchedResolverError } from '@speclynx/apidom-reference/configuration/empty';
6
+ import { traverseAsync } from '@speclynx/apidom-traverse';
7
+ import { toValue } from '@speclynx/apidom-core';
8
+ import * as constants from "../../constants.mjs";
9
+ import OpenAPIDocument from "../../document/OpenAPIDocument.mjs";
10
+ import DocumentRegistryProvider, { circularReplacer } from "./DocumentRegistryProvider.mjs";
11
+ import OpenAPIOperationIndex from "../../document/OpenAPIOperationIndex.mjs";
12
+ /**
13
+ * Options for loading an OpenAPI document.
14
+ * @public
15
+ */
16
+ /**
17
+ * Default options for loading an OpenAPI document.
18
+ */
19
+ export const providerOptionsOverride = {
20
+ resolve: {
21
+ resolverOpts: {
22
+ cache: {
23
+ maxEntries: constants.MAX_HTTP_CACHE_ENTRIES,
24
+ maxStaleAge: constants.MAX_HTTP_CACHE_STALE_AGE
25
+ }
26
+ }
27
+ },
28
+ dereference: {
29
+ immutable: false,
30
+ circular: 'replace',
31
+ circularReplacer
32
+ }
33
+ };
34
+
35
+ /**
36
+ * Provides OpenAPIDocument instances for the DocumentRegistry.
37
+ *
38
+ * Parses, dereferences, and builds an OperationIndex for OpenAPI documents.
39
+ * @public
40
+ */
41
+ class OpenAPIDocumentRegistryProvider extends DocumentRegistryProvider {
42
+ #options;
43
+ constructor(options = {}) {
44
+ super();
45
+ this.#options = mergeOptions(providerOptionsOverride, options);
46
+ }
47
+ async canProvide(uri) {
48
+ try {
49
+ const options = this.#buildParseOptions();
50
+ const data = await readFile(uri, options);
51
+ const file = new File({
52
+ uri,
53
+ data
54
+ });
55
+ const parsers = options.parse.parsers.filter(p => p.name.startsWith('openapi'));
56
+ for (const parser of parsers) {
57
+ if (await parser.canParse(file)) return true;
58
+ }
59
+ } catch (error) {
60
+ if (error instanceof UnmatchedResolverError) return false;
61
+ throw error;
62
+ }
63
+ return false;
64
+ }
65
+
66
+ /**
67
+ * Loads an OpenAPI document from a URI and produces an OpenAPIDocument.
68
+ */
69
+ async provide(uri) {
70
+ const parseResult = await parseOpenAPI(uri, this.#buildParseOptions());
71
+ const operationIndex = await this.#buildOperationIndex(parseResult);
72
+ return new OpenAPIDocument(uri, parseResult, operationIndex);
73
+ }
74
+ async #buildOperationIndex(parseResult) {
75
+ const index = new OpenAPIOperationIndex();
76
+ const dereferenceOptions = this.#buildDereferenceOptions(parseResult);
77
+ const apiDereferenced = await traverseAsync(parseResult.api, {
78
+ async PathItemElement(path) {
79
+ const pathItem = path.node;
80
+ if (!pathItem.hasMetaProperty('path')) return path.skip();
81
+ if (!isStringElement(pathItem.$ref)) return;
82
+ const pathItemDereferenced = await dereferenceOpenAPIElement(pathItem, dereferenceOptions);
83
+ path.replaceWith(pathItemDereferenced);
84
+ },
85
+ OperationElement(path) {
86
+ const operation = path.node;
87
+ const operationId = toValue(operation.operationId);
88
+ if (typeof operationId !== 'string') return path.skip();
89
+ if (operationId === '') return path.skip();
90
+ index.set(operationId, path.formatPath('jsonpointer'));
91
+ path.skip();
92
+ }
93
+ });
94
+ parseResult.replaceResult(apiDereferenced);
95
+ return index;
96
+ }
97
+ #buildParseOptions() {
98
+ return mergeOptions(defaultParseOpenAPIOptions, this.#options);
99
+ }
100
+ #buildDereferenceOptions(parseResult) {
101
+ let options = mergeOptions(defaultDereferenceOpenAPIOptions, this.#options);
102
+ if (parseResult) {
103
+ options = mergeOptions(options, {
104
+ dereference: {
105
+ strategyOpts: {
106
+ parseResult
107
+ }
108
+ }
109
+ });
110
+ }
111
+ return options;
112
+ }
113
+ }
114
+ export default OpenAPIDocumentRegistryProvider;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _apidomCore = require("@speclynx/apidom-core");
8
+ var _arazzoRuntimeExpression = require("@swaggerexpert/arazzo-runtime-expression");
9
+ /**
10
+ * Resolves a runtime expression to its value.
11
+ *
12
+ * Bridged to a lenient runtime expression evaluator
13
+ * (`(expression) => runtimeExpressionEvaluator.evaluate(expression)`), so an
14
+ * unresolvable reference yields `undefined` rather than throwing.
15
+ * @public
16
+ */
17
+
18
+ /**
19
+ * Base of every resolver of authored Arazzo values — the single home of the
20
+ * literal-vs-expression rule they all share.
21
+ *
22
+ * Per Arazzo 1.0.1, an authored value (a parameter's `value`, an `outputs`
23
+ * entry, a `requestBody` replacement value) is either a literal or a whole
24
+ * runtime expression — there is no embedded/interpolated expression. So a
25
+ * value that is a string is resolved as an expression only when the entire
26
+ * string is a valid runtime expression; every other value (a non-expression
27
+ * string such as `"{$inputs.x}"`, a number, boolean, object, array, or null)
28
+ * is a literal and is used as-is. This is deliberately not template
29
+ * interpolation. The one exception is a `requestBody` payload, which "can
30
+ * contain" runtime expressions — {@link RequestBodyResolver} walks it instead.
31
+ * @public
32
+ */
33
+ class ArazzoValueResolver {
34
+ /**
35
+ * Resolves one authored value element by the rule above.
36
+ */
37
+ resolveValue(element, resolve) {
38
+ const value = (0, _apidomCore.toValue)(element);
39
+ return typeof value === 'string' && (0, _arazzoRuntimeExpression.test)(value) ? resolve(value) : value;
40
+ }
41
+ }
42
+ var _default = exports.default = ArazzoValueResolver;
@@ -0,0 +1,37 @@
1
+ import { toValue } from '@speclynx/apidom-core';
2
+ import { test as isRuntimeExpression } from '@swaggerexpert/arazzo-runtime-expression';
3
+
4
+ /**
5
+ * Resolves a runtime expression to its value.
6
+ *
7
+ * Bridged to a lenient runtime expression evaluator
8
+ * (`(expression) => runtimeExpressionEvaluator.evaluate(expression)`), so an
9
+ * unresolvable reference yields `undefined` rather than throwing.
10
+ * @public
11
+ */
12
+
13
+ /**
14
+ * Base of every resolver of authored Arazzo values — the single home of the
15
+ * literal-vs-expression rule they all share.
16
+ *
17
+ * Per Arazzo 1.0.1, an authored value (a parameter's `value`, an `outputs`
18
+ * entry, a `requestBody` replacement value) is either a literal or a whole
19
+ * runtime expression — there is no embedded/interpolated expression. So a
20
+ * value that is a string is resolved as an expression only when the entire
21
+ * string is a valid runtime expression; every other value (a non-expression
22
+ * string such as `"{$inputs.x}"`, a number, boolean, object, array, or null)
23
+ * is a literal and is used as-is. This is deliberately not template
24
+ * interpolation. The one exception is a `requestBody` payload, which "can
25
+ * contain" runtime expressions — {@link RequestBodyResolver} walks it instead.
26
+ * @public
27
+ */
28
+ class ArazzoValueResolver {
29
+ /**
30
+ * Resolves one authored value element by the rule above.
31
+ */
32
+ resolveValue(element, resolve) {
33
+ const value = toValue(element);
34
+ return typeof value === 'string' && isRuntimeExpression(value) ? resolve(value) : value;
35
+ }
36
+ }
37
+ export default ArazzoValueResolver;
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = void 0;
8
+ var _apidomDatamodel = require("@speclynx/apidom-datamodel");
9
+ var _apidomNsArazzo = require("@speclynx/apidom-ns-arazzo-1");
10
+ var _ParameterDelivery = _interopRequireDefault(require("../client/ParameterDelivery.cjs"));
11
+ var _ParameterIdentity = _interopRequireDefault(require("../document/ParameterIdentity.cjs"));
12
+ var _ResolverError = _interopRequireDefault(require("../errors/ResolverError.cjs"));
13
+ var _StepParameterResolver = _interopRequireDefault(require("./StepParameterResolver.cjs"));
14
+ /**
15
+ * Resolves the `parameters` of a step targeting an OpenAPI operation into the
16
+ * map the operation is executed with.
17
+ *
18
+ * Values follow the family-wide literal-vs-expression rule of
19
+ * {@link ArazzoValueResolver}. Keys and their first-wins claiming are
20
+ * `ParameterDelivery`'s: `'{in}.{name}'` for a location the client
21
+ * can address — a parameter is unique by `(name, in)`, so keying by name
22
+ * alone would collapse two parameters that differ only in their location into
23
+ * one entry and silently drop the other, where an operation legally declaring
24
+ * `token` both as a header and as a query parameter must receive both — and
25
+ * the bare name for Arazzo's `querystring`, which names no OpenAPI location.
26
+ * First-wins is the override order the specification requires: the list is
27
+ * ordered by precedence, most specific first, as `ArazzoWorkflowNormalizer`
28
+ * leaves it once a step's own parameters have been merged with the ones it
29
+ * inherits.
30
+ *
31
+ * What the map reports, this resolver judges. A parameter without a location
32
+ * throws {@link ResolverError}: a step targeting an operation requires one
33
+ * (the normalizer does not inherit input-shaped workflow parameters into such
34
+ * steps, so this is the step's own authoring error), and delivering it bare
35
+ * instead would let it capture *every* declared location of that name — see
36
+ * `ParameterDelivery` for the lookup order that makes it so. A
37
+ * non-string location throws for the same reason it deduplicates with nothing
38
+ * in the normalizer: it names no location. And two *different* parameters the
39
+ * map reports as colliding cannot both be delivered, so a collision throws
40
+ * rather than silently dropping one — whether they collide on one key (the
41
+ * scheme is not injective: a `querystring` parameter named `header.token` and
42
+ * a header parameter named `token` both produce `header.token`) or across a
43
+ * bare/qualified pair sharing a name (a `querystring` `token` next to a
44
+ * header `token`), where the client would consult the bare name first and
45
+ * silently capture the qualified value.
46
+ * @public
47
+ */
48
+ class OpenAPIOperationParameterResolver extends _StepParameterResolver.default {
49
+ /**
50
+ * Resolves each parameter's `value`, returning a
51
+ * `ParameterDelivery`-keyed record. Returns an empty object when
52
+ * there are no parameters.
53
+ *
54
+ * `scope` names the step in a thrown {@link ResolverError}.
55
+ */
56
+ resolve(parameters, resolve, scope) {
57
+ const delivery = new _ParameterDelivery.default();
58
+ if (parameters === undefined) return delivery.toRecord();
59
+ // present but scalar: walking it would fail as a bare
60
+ // `TypeError: parameters is not iterable`, raised by the language rather
61
+ // than the runner. Reported here as the authoring error it is.
62
+ if (!(0, _apidomDatamodel.isArrayElement)(parameters)) {
63
+ throw new _ResolverError.default('`parameters` is present but is not a list', {
64
+ ...scope,
65
+ target: 'parameters',
66
+ reason: 'malformed-parameters'
67
+ });
68
+ }
69
+ for (const parameter of parameters) {
70
+ if (!(0, _apidomNsArazzo.isParameterElement)(parameter)) continue;
71
+ // a Parameter Object without an identity has a missing or non-string
72
+ // name — reported as loudly as a malformed location below, rather than
73
+ // silently dropped from the request
74
+ const identity = _ParameterIdentity.default.of(parameter);
75
+ if (identity === undefined) {
76
+ throw new _ResolverError.default('Parameter has a missing or non-string name', {
77
+ ...scope,
78
+ reason: 'missing-name'
79
+ });
80
+ }
81
+ const {
82
+ name,
83
+ location
84
+ } = identity;
85
+ if (location === undefined) {
86
+ throw new _ResolverError.default(`Parameter "${name}" declares no location ("in"), which a step targeting an operation requires`, {
87
+ ...scope,
88
+ target: name,
89
+ reason: 'missing-location'
90
+ });
91
+ }
92
+ if (location === null) {
93
+ throw new _ResolverError.default(`Parameter "${name}" has a non-string location ("in")`, {
94
+ ...scope,
95
+ target: name,
96
+ reason: 'malformed-location'
97
+ });
98
+ }
99
+ const {
100
+ key,
101
+ outcome
102
+ } = delivery.claim(location, name);
103
+ // the same parameter declared again: the earlier, more specific one won
104
+ if (outcome === 'duplicate') continue;
105
+ if (outcome === 'collision') {
106
+ throw new _ResolverError.default(`Parameter "${name}" (in: ${location}) collides with another parameter on the ` + `delivery key "${key}" and cannot be delivered unambiguously`, {
107
+ ...scope,
108
+ target: name,
109
+ reason: 'ambiguous-delivery'
110
+ });
111
+ }
112
+ delivery.set(key, this.resolveValue(parameter.value, resolve));
113
+ }
114
+ return delivery.toRecord();
115
+ }
116
+ }
117
+ var _default = exports.default = OpenAPIOperationParameterResolver;
@@ -0,0 +1,110 @@
1
+ import { isArrayElement } from '@speclynx/apidom-datamodel';
2
+ import { isParameterElement } from '@speclynx/apidom-ns-arazzo-1';
3
+ import ParameterDelivery from "../client/ParameterDelivery.mjs";
4
+ import ParameterIdentity from "../document/ParameterIdentity.mjs";
5
+ import ResolverError from "../errors/ResolverError.mjs";
6
+ import StepParameterResolver from "./StepParameterResolver.mjs";
7
+ /**
8
+ * Resolves the `parameters` of a step targeting an OpenAPI operation into the
9
+ * map the operation is executed with.
10
+ *
11
+ * Values follow the family-wide literal-vs-expression rule of
12
+ * {@link ArazzoValueResolver}. Keys and their first-wins claiming are
13
+ * `ParameterDelivery`'s: `'{in}.{name}'` for a location the client
14
+ * can address — a parameter is unique by `(name, in)`, so keying by name
15
+ * alone would collapse two parameters that differ only in their location into
16
+ * one entry and silently drop the other, where an operation legally declaring
17
+ * `token` both as a header and as a query parameter must receive both — and
18
+ * the bare name for Arazzo's `querystring`, which names no OpenAPI location.
19
+ * First-wins is the override order the specification requires: the list is
20
+ * ordered by precedence, most specific first, as `ArazzoWorkflowNormalizer`
21
+ * leaves it once a step's own parameters have been merged with the ones it
22
+ * inherits.
23
+ *
24
+ * What the map reports, this resolver judges. A parameter without a location
25
+ * throws {@link ResolverError}: a step targeting an operation requires one
26
+ * (the normalizer does not inherit input-shaped workflow parameters into such
27
+ * steps, so this is the step's own authoring error), and delivering it bare
28
+ * instead would let it capture *every* declared location of that name — see
29
+ * `ParameterDelivery` for the lookup order that makes it so. A
30
+ * non-string location throws for the same reason it deduplicates with nothing
31
+ * in the normalizer: it names no location. And two *different* parameters the
32
+ * map reports as colliding cannot both be delivered, so a collision throws
33
+ * rather than silently dropping one — whether they collide on one key (the
34
+ * scheme is not injective: a `querystring` parameter named `header.token` and
35
+ * a header parameter named `token` both produce `header.token`) or across a
36
+ * bare/qualified pair sharing a name (a `querystring` `token` next to a
37
+ * header `token`), where the client would consult the bare name first and
38
+ * silently capture the qualified value.
39
+ * @public
40
+ */
41
+ class OpenAPIOperationParameterResolver extends StepParameterResolver {
42
+ /**
43
+ * Resolves each parameter's `value`, returning a
44
+ * `ParameterDelivery`-keyed record. Returns an empty object when
45
+ * there are no parameters.
46
+ *
47
+ * `scope` names the step in a thrown {@link ResolverError}.
48
+ */
49
+ resolve(parameters, resolve, scope) {
50
+ const delivery = new ParameterDelivery();
51
+ if (parameters === undefined) return delivery.toRecord();
52
+ // present but scalar: walking it would fail as a bare
53
+ // `TypeError: parameters is not iterable`, raised by the language rather
54
+ // than the runner. Reported here as the authoring error it is.
55
+ if (!isArrayElement(parameters)) {
56
+ throw new ResolverError('`parameters` is present but is not a list', {
57
+ ...scope,
58
+ target: 'parameters',
59
+ reason: 'malformed-parameters'
60
+ });
61
+ }
62
+ for (const parameter of parameters) {
63
+ if (!isParameterElement(parameter)) continue;
64
+ // a Parameter Object without an identity has a missing or non-string
65
+ // name — reported as loudly as a malformed location below, rather than
66
+ // silently dropped from the request
67
+ const identity = ParameterIdentity.of(parameter);
68
+ if (identity === undefined) {
69
+ throw new ResolverError('Parameter has a missing or non-string name', {
70
+ ...scope,
71
+ reason: 'missing-name'
72
+ });
73
+ }
74
+ const {
75
+ name,
76
+ location
77
+ } = identity;
78
+ if (location === undefined) {
79
+ throw new ResolverError(`Parameter "${name}" declares no location ("in"), which a step targeting an operation requires`, {
80
+ ...scope,
81
+ target: name,
82
+ reason: 'missing-location'
83
+ });
84
+ }
85
+ if (location === null) {
86
+ throw new ResolverError(`Parameter "${name}" has a non-string location ("in")`, {
87
+ ...scope,
88
+ target: name,
89
+ reason: 'malformed-location'
90
+ });
91
+ }
92
+ const {
93
+ key,
94
+ outcome
95
+ } = delivery.claim(location, name);
96
+ // the same parameter declared again: the earlier, more specific one won
97
+ if (outcome === 'duplicate') continue;
98
+ if (outcome === 'collision') {
99
+ throw new ResolverError(`Parameter "${name}" (in: ${location}) collides with another parameter on the ` + `delivery key "${key}" and cannot be delivered unambiguously`, {
100
+ ...scope,
101
+ target: name,
102
+ reason: 'ambiguous-delivery'
103
+ });
104
+ }
105
+ delivery.set(key, this.resolveValue(parameter.value, resolve));
106
+ }
107
+ return delivery.toRecord();
108
+ }
109
+ }
110
+ export default OpenAPIOperationParameterResolver;
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = void 0;
8
+ var _apidomCore = require("@speclynx/apidom-core");
9
+ var _apidomDatamodel = require("@speclynx/apidom-datamodel");
10
+ var _arazzoRuntimeExpression = require("@swaggerexpert/arazzo-runtime-expression");
11
+ var _ResolverError = _interopRequireDefault(require("../errors/ResolverError.cjs"));
12
+ var _ArazzoValueResolver = _interopRequireDefault(require("./ArazzoValueResolver.cjs"));
13
+ /**
14
+ * Resolves a step's or workflow's `outputs` to a plain map of name → value.
15
+ *
16
+ * The spec types `outputs` as `Map[string, {expression}]`, so a whole runtime
17
+ * expression is the *only* authored form — unlike a parameter's `value` or a
18
+ * `requestBody` payload (typed `Any`), where {@link ArazzoValueResolver} lets a
19
+ * literal through. An output that is not a valid runtime expression is an
20
+ * authoring error and throws a {@link ResolverError}.
21
+ *
22
+ * The result is the map an executor stores into the workflow execution state so
23
+ * later steps can read `$steps.{id}.outputs.{name}` / `$outputs.{name}`.
24
+ * @public
25
+ */
26
+ class OutputResolver extends _ArazzoValueResolver.default {
27
+ /**
28
+ * Resolves each output value, returning a `name` → value map. Returns an empty
29
+ * object when there are no outputs.
30
+ *
31
+ * `scope` names the step or workflow the outputs belong to, for a thrown
32
+ * {@link ResolverError}. An output value that is not a valid runtime
33
+ * expression throws with `reason: 'invalid-expression'`.
34
+ */
35
+ resolve(outputs, resolve, scope) {
36
+ const result = {};
37
+ if (outputs === undefined) return result;
38
+ // present but not a map: the walk below would fail as a bare
39
+ // `TypeError: outputs.forEach is not a function`.
40
+ if (!(0, _apidomDatamodel.isObjectElement)(outputs)) {
41
+ throw new _ResolverError.default('`outputs` is present but is not a map', {
42
+ ...scope,
43
+ target: 'outputs',
44
+ reason: 'malformed-outputs'
45
+ });
46
+ }
47
+ outputs.forEach((value, key) => {
48
+ const name = (0, _apidomCore.toValue)(key);
49
+ const expression = (0, _apidomCore.toValue)(value);
50
+ if (typeof expression !== 'string' || !(0, _arazzoRuntimeExpression.test)(expression)) {
51
+ throw new _ResolverError.default(`Output "${name}" is not a valid runtime expression`, {
52
+ ...scope,
53
+ target: 'outputs',
54
+ reason: 'invalid-expression'
55
+ });
56
+ }
57
+ // defined rather than assigned: a name like `__proto__` hits the
58
+ // Object.prototype accessor on bracket assignment, so no own property is
59
+ // ever created and the output is silently lost — and an object value
60
+ // additionally rewrites the record's prototype
61
+ Object.defineProperty(result, name, {
62
+ value: resolve(expression),
63
+ enumerable: true,
64
+ writable: true,
65
+ configurable: true
66
+ });
67
+ });
68
+ return result;
69
+ }
70
+ }
71
+ var _default = exports.default = OutputResolver;
@@ -0,0 +1,64 @@
1
+ import { toValue } from '@speclynx/apidom-core';
2
+ import { isObjectElement } from '@speclynx/apidom-datamodel';
3
+ import { test as isRuntimeExpression } from '@swaggerexpert/arazzo-runtime-expression';
4
+ import ResolverError from "../errors/ResolverError.mjs";
5
+ import ArazzoValueResolver from "./ArazzoValueResolver.mjs";
6
+ /**
7
+ * Resolves a step's or workflow's `outputs` to a plain map of name → value.
8
+ *
9
+ * The spec types `outputs` as `Map[string, {expression}]`, so a whole runtime
10
+ * expression is the *only* authored form — unlike a parameter's `value` or a
11
+ * `requestBody` payload (typed `Any`), where {@link ArazzoValueResolver} lets a
12
+ * literal through. An output that is not a valid runtime expression is an
13
+ * authoring error and throws a {@link ResolverError}.
14
+ *
15
+ * The result is the map an executor stores into the workflow execution state so
16
+ * later steps can read `$steps.{id}.outputs.{name}` / `$outputs.{name}`.
17
+ * @public
18
+ */
19
+ class OutputResolver extends ArazzoValueResolver {
20
+ /**
21
+ * Resolves each output value, returning a `name` → value map. Returns an empty
22
+ * object when there are no outputs.
23
+ *
24
+ * `scope` names the step or workflow the outputs belong to, for a thrown
25
+ * {@link ResolverError}. An output value that is not a valid runtime
26
+ * expression throws with `reason: 'invalid-expression'`.
27
+ */
28
+ resolve(outputs, resolve, scope) {
29
+ const result = {};
30
+ if (outputs === undefined) return result;
31
+ // present but not a map: the walk below would fail as a bare
32
+ // `TypeError: outputs.forEach is not a function`.
33
+ if (!isObjectElement(outputs)) {
34
+ throw new ResolverError('`outputs` is present but is not a map', {
35
+ ...scope,
36
+ target: 'outputs',
37
+ reason: 'malformed-outputs'
38
+ });
39
+ }
40
+ outputs.forEach((value, key) => {
41
+ const name = toValue(key);
42
+ const expression = toValue(value);
43
+ if (typeof expression !== 'string' || !isRuntimeExpression(expression)) {
44
+ throw new ResolverError(`Output "${name}" is not a valid runtime expression`, {
45
+ ...scope,
46
+ target: 'outputs',
47
+ reason: 'invalid-expression'
48
+ });
49
+ }
50
+ // defined rather than assigned: a name like `__proto__` hits the
51
+ // Object.prototype accessor on bracket assignment, so no own property is
52
+ // ever created and the output is silently lost — and an object value
53
+ // additionally rewrites the record's prototype
54
+ Object.defineProperty(result, name, {
55
+ value: resolve(expression),
56
+ enumerable: true,
57
+ writable: true,
58
+ configurable: true
59
+ });
60
+ });
61
+ return result;
62
+ }
63
+ }
64
+ export default OutputResolver;