@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,205 @@
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 _apidomNsArazzo = require("@speclynx/apidom-ns-arazzo-1");
11
+ var _arazzoRuntimeExpression = require("@swaggerexpert/arazzo-runtime-expression");
12
+ var _CriterionError = _interopRequireDefault(require("../errors/CriterionError.cjs"));
13
+ var _RegexCriterionEvaluator = _interopRequireDefault(require("./RegexCriterionEvaluator.cjs"));
14
+ var _SimpleCriterionEvaluator = _interopRequireDefault(require("./SimpleCriterionEvaluator.cjs"));
15
+ var _JSONPathCriterionEvaluator = _interopRequireDefault(require("./JSONPathCriterionEvaluator.cjs"));
16
+ var _XPathCriterionEvaluator = _interopRequireDefault(require("./XPathCriterionEvaluator.cjs"));
17
+ /**
18
+ * Resolves a runtime expression to a value during criterion evaluation.
19
+ *
20
+ * Used both for a criterion's `context` (regex/jsonpath/xpath) and for the
21
+ * expressions embedded in a `simple` condition. It should resolve leniently —
22
+ * an unresolvable reference returning `undefined` fails the criterion rather
23
+ * than throwing (a common way to drive it is
24
+ * `(expression) => runtimeExpressionEvaluator.evaluate(expression)` with a
25
+ * lenient evaluator).
26
+ * @public
27
+ */
28
+
29
+ /**
30
+ * Options for the CriterionEvaluator.
31
+ * @public
32
+ */
33
+
34
+ /**
35
+ * Evaluates an Arazzo Criterion Object to a boolean.
36
+ *
37
+ * Dispatches on the criterion's `type` (defaulting to `simple` when omitted):
38
+ * - `simple` — evaluates the condition directly, resolving the runtime
39
+ * expressions embedded in it.
40
+ * - `regex` — resolves the `context` runtime expression, then applies the
41
+ * pattern to the resolved value.
42
+ * - `jsonpath` — resolves the `context` runtime expression, then applies the
43
+ * JSONPath query to the resolved value (met when the query matches). Only the
44
+ * `rfc9535` version is supported (the spec default); an explicit other version
45
+ * throws.
46
+ * - `xpath` — resolves the `context` runtime expression, then applies the XPath
47
+ * 3.1 query to the resolved XML value (met by the Effective Boolean Value).
48
+ * Only the `xpath-31` version is supported (the spec default); an explicit
49
+ * other version throws.
50
+ *
51
+ * The evaluator is agnostic about how runtime expressions are resolved: the
52
+ * caller supplies a {@link CriterionContextResolver} per evaluation, keeping
53
+ * runtime-state, document, and registry concerns in the runtime expression
54
+ * evaluator rather than duplicated here.
55
+ * @public
56
+ */
57
+ class CriterionEvaluator {
58
+ #simple;
59
+ #regex;
60
+ #jsonpath;
61
+ #xpath;
62
+ constructor(options = {}) {
63
+ this.#simple = options.simple ?? new _SimpleCriterionEvaluator.default();
64
+ this.#regex = options.regex ?? new _RegexCriterionEvaluator.default();
65
+ this.#jsonpath = options.jsonpath ?? new _JSONPathCriterionEvaluator.default();
66
+ this.#xpath = options.xpath ?? new _XPathCriterionEvaluator.default();
67
+ }
68
+
69
+ /**
70
+ * Evaluates a criterion element, returning whether the condition is met.
71
+ *
72
+ * `resolve` turns a runtime expression into a value: for `simple` it resolves
73
+ * the expressions embedded in the condition; for the other types it resolves
74
+ * the criterion's `context` expression that the condition is applied to.
75
+ */
76
+ evaluate(criterion, resolve) {
77
+ if (!(0, _apidomNsArazzo.isCriterionElement)(criterion)) {
78
+ throw new _CriterionError.default('Element is not a Criterion Object', {
79
+ reason: 'invalid-criterion'
80
+ });
81
+ }
82
+ const condition = (0, _apidomDatamodel.isStringElement)(criterion.condition) ? (0, _apidomCore.toValue)(criterion.condition) : undefined;
83
+ // `condition` is required; an empty string is not a meaningful condition
84
+ // (e.g. an empty regex would match unconditionally), so reject it too.
85
+ if (condition === undefined || condition === '') {
86
+ throw new _CriterionError.default('Criterion is missing a "condition"', {
87
+ reason: 'missing-condition'
88
+ });
89
+ }
90
+ const type = this.#resolveType(criterion);
91
+ this.#requireValidContext(criterion, type);
92
+ switch (type) {
93
+ case 'simple':
94
+ return this.#simple.evaluate(condition, resolve);
95
+ case 'regex':
96
+ return this.#regex.evaluate(condition, this.#resolveContext(criterion, type, resolve));
97
+ case 'jsonpath':
98
+ // only rfc9535 is supported; it is the spec default, so an omitted
99
+ // version is accepted. draft-goessner has different semantics and is
100
+ // rejected rather than mis-evaluated.
101
+ this.#requireVersion(criterion, type, condition, 'rfc9535');
102
+ return this.#jsonpath.evaluate(condition, this.#resolveContext(criterion, type, resolve));
103
+ case 'xpath':
104
+ // only XPath 3.1 is supported; xpath-31 is the spec default, so an
105
+ // omitted version is accepted. Older versions are rejected.
106
+ this.#requireVersion(criterion, type, condition, 'xpath-31');
107
+ return this.#xpath.evaluate(condition, this.#resolveContext(criterion, type, resolve));
108
+ default:
109
+ throw new _CriterionError.default(`Unknown criterion type "${type}"`, {
110
+ condition,
111
+ type,
112
+ reason: 'unknown-type'
113
+ });
114
+ }
115
+ }
116
+
117
+ /**
118
+ * Determines the criterion `type`, defaulting to `simple` only when the field
119
+ * is omitted. The `type` field may be a bare string or a Criterion Expression
120
+ * Type Object (whose own `type` names the flavor). A present-but-unreadable
121
+ * `type` throws a {@link CriterionError} rather than silently defaulting.
122
+ */
123
+ #resolveType(criterion) {
124
+ const type = criterion.type;
125
+ if (type === undefined) return 'simple';
126
+ if ((0, _apidomNsArazzo.isCriterionExpressionTypeElement)(type) && (0, _apidomDatamodel.isStringElement)(type.type)) {
127
+ return (0, _apidomCore.toValue)(type.type);
128
+ }
129
+ if ((0, _apidomDatamodel.isStringElement)(type)) return (0, _apidomCore.toValue)(type);
130
+ throw new _CriterionError.default('Criterion has an invalid "type"', {
131
+ reason: 'invalid-type'
132
+ });
133
+ }
134
+
135
+ /**
136
+ * Extracts the expression `version` from a Criterion Expression Type Object,
137
+ * or `undefined` when no version is declared (a bare-string `type`, or a type
138
+ * object without a `version`) — in which case the spec default for the type
139
+ * applies. A `version` that is present but not a string is malformed and
140
+ * throws a {@link CriterionError} rather than silently defaulting.
141
+ */
142
+ #resolveVersion(criterion) {
143
+ const type = criterion.type;
144
+ if (!(0, _apidomNsArazzo.isCriterionExpressionTypeElement)(type) || type.version === undefined) {
145
+ return undefined;
146
+ }
147
+ if ((0, _apidomDatamodel.isStringElement)(type.version)) {
148
+ return (0, _apidomCore.toValue)(type.version);
149
+ }
150
+ throw new _CriterionError.default('Criterion has an invalid expression type "version"', {
151
+ reason: 'invalid-version'
152
+ });
153
+ }
154
+
155
+ /**
156
+ * Enforces that a versioned condition type declares only the one version this
157
+ * runner supports. An omitted version is accepted (it is the spec default);
158
+ * any other declared version throws a {@link CriterionError}.
159
+ */
160
+ #requireVersion(criterion, type, condition, supported) {
161
+ const version = this.#resolveVersion(criterion);
162
+ if (version !== undefined && version !== supported) {
163
+ throw new _CriterionError.default(`Unsupported ${type} version "${version}" (only ${supported})`, {
164
+ condition,
165
+ type,
166
+ reason: 'unsupported-version'
167
+ });
168
+ }
169
+ }
170
+
171
+ /**
172
+ * Enforces that a present `context` is a valid runtime expression, for every
173
+ * criterion type: the spec types it `{expression}`, and `simple` ignores it,
174
+ * so a malformed one would otherwise go unnoticed there.
175
+ */
176
+ #requireValidContext(criterion, type) {
177
+ const {
178
+ context
179
+ } = criterion;
180
+ if (context === undefined) return;
181
+ if (!(0, _apidomDatamodel.isStringElement)(context) || !(0, _arazzoRuntimeExpression.test)((0, _apidomCore.toValue)(context))) {
182
+ throw new _CriterionError.default('Criterion has a "context" that is not a valid runtime expression', {
183
+ type,
184
+ reason: 'invalid-context'
185
+ });
186
+ }
187
+ }
188
+
189
+ /**
190
+ * Resolves the criterion's `context` runtime expression to the value the
191
+ * condition is applied to. The condition types that need a context (`regex`,
192
+ * `jsonpath`, `xpath`) must declare one; a criterion of such a type without a
193
+ * `context` throws a {@link CriterionError}.
194
+ */
195
+ #resolveContext(criterion, type, resolve) {
196
+ if (!(0, _apidomDatamodel.isStringElement)(criterion.context)) {
197
+ throw new _CriterionError.default(`Criterion type "${type}" requires a "context"`, {
198
+ type,
199
+ reason: 'missing-context'
200
+ });
201
+ }
202
+ return resolve((0, _apidomCore.toValue)(criterion.context));
203
+ }
204
+ }
205
+ var _default = exports.default = CriterionEvaluator;
@@ -0,0 +1,196 @@
1
+ import { toValue } from '@speclynx/apidom-core';
2
+ import { isStringElement } from '@speclynx/apidom-datamodel';
3
+ import { isCriterionElement, isCriterionExpressionTypeElement } from '@speclynx/apidom-ns-arazzo-1';
4
+ import { test as isRuntimeExpression } from '@swaggerexpert/arazzo-runtime-expression';
5
+ import CriterionError from "../errors/CriterionError.mjs";
6
+ import RegexCriterionEvaluator from "./RegexCriterionEvaluator.mjs";
7
+ import SimpleCriterionEvaluator from "./SimpleCriterionEvaluator.mjs";
8
+ import JSONPathCriterionEvaluator from "./JSONPathCriterionEvaluator.mjs";
9
+ import XPathCriterionEvaluator from "./XPathCriterionEvaluator.mjs";
10
+ /**
11
+ * Resolves a runtime expression to a value during criterion evaluation.
12
+ *
13
+ * Used both for a criterion's `context` (regex/jsonpath/xpath) and for the
14
+ * expressions embedded in a `simple` condition. It should resolve leniently —
15
+ * an unresolvable reference returning `undefined` fails the criterion rather
16
+ * than throwing (a common way to drive it is
17
+ * `(expression) => runtimeExpressionEvaluator.evaluate(expression)` with a
18
+ * lenient evaluator).
19
+ * @public
20
+ */
21
+ /**
22
+ * Options for the CriterionEvaluator.
23
+ * @public
24
+ */
25
+ /**
26
+ * Evaluates an Arazzo Criterion Object to a boolean.
27
+ *
28
+ * Dispatches on the criterion's `type` (defaulting to `simple` when omitted):
29
+ * - `simple` — evaluates the condition directly, resolving the runtime
30
+ * expressions embedded in it.
31
+ * - `regex` — resolves the `context` runtime expression, then applies the
32
+ * pattern to the resolved value.
33
+ * - `jsonpath` — resolves the `context` runtime expression, then applies the
34
+ * JSONPath query to the resolved value (met when the query matches). Only the
35
+ * `rfc9535` version is supported (the spec default); an explicit other version
36
+ * throws.
37
+ * - `xpath` — resolves the `context` runtime expression, then applies the XPath
38
+ * 3.1 query to the resolved XML value (met by the Effective Boolean Value).
39
+ * Only the `xpath-31` version is supported (the spec default); an explicit
40
+ * other version throws.
41
+ *
42
+ * The evaluator is agnostic about how runtime expressions are resolved: the
43
+ * caller supplies a {@link CriterionContextResolver} per evaluation, keeping
44
+ * runtime-state, document, and registry concerns in the runtime expression
45
+ * evaluator rather than duplicated here.
46
+ * @public
47
+ */
48
+ class CriterionEvaluator {
49
+ #simple;
50
+ #regex;
51
+ #jsonpath;
52
+ #xpath;
53
+ constructor(options = {}) {
54
+ this.#simple = options.simple ?? new SimpleCriterionEvaluator();
55
+ this.#regex = options.regex ?? new RegexCriterionEvaluator();
56
+ this.#jsonpath = options.jsonpath ?? new JSONPathCriterionEvaluator();
57
+ this.#xpath = options.xpath ?? new XPathCriterionEvaluator();
58
+ }
59
+
60
+ /**
61
+ * Evaluates a criterion element, returning whether the condition is met.
62
+ *
63
+ * `resolve` turns a runtime expression into a value: for `simple` it resolves
64
+ * the expressions embedded in the condition; for the other types it resolves
65
+ * the criterion's `context` expression that the condition is applied to.
66
+ */
67
+ evaluate(criterion, resolve) {
68
+ if (!isCriterionElement(criterion)) {
69
+ throw new CriterionError('Element is not a Criterion Object', {
70
+ reason: 'invalid-criterion'
71
+ });
72
+ }
73
+ const condition = isStringElement(criterion.condition) ? toValue(criterion.condition) : undefined;
74
+ // `condition` is required; an empty string is not a meaningful condition
75
+ // (e.g. an empty regex would match unconditionally), so reject it too.
76
+ if (condition === undefined || condition === '') {
77
+ throw new CriterionError('Criterion is missing a "condition"', {
78
+ reason: 'missing-condition'
79
+ });
80
+ }
81
+ const type = this.#resolveType(criterion);
82
+ this.#requireValidContext(criterion, type);
83
+ switch (type) {
84
+ case 'simple':
85
+ return this.#simple.evaluate(condition, resolve);
86
+ case 'regex':
87
+ return this.#regex.evaluate(condition, this.#resolveContext(criterion, type, resolve));
88
+ case 'jsonpath':
89
+ // only rfc9535 is supported; it is the spec default, so an omitted
90
+ // version is accepted. draft-goessner has different semantics and is
91
+ // rejected rather than mis-evaluated.
92
+ this.#requireVersion(criterion, type, condition, 'rfc9535');
93
+ return this.#jsonpath.evaluate(condition, this.#resolveContext(criterion, type, resolve));
94
+ case 'xpath':
95
+ // only XPath 3.1 is supported; xpath-31 is the spec default, so an
96
+ // omitted version is accepted. Older versions are rejected.
97
+ this.#requireVersion(criterion, type, condition, 'xpath-31');
98
+ return this.#xpath.evaluate(condition, this.#resolveContext(criterion, type, resolve));
99
+ default:
100
+ throw new CriterionError(`Unknown criterion type "${type}"`, {
101
+ condition,
102
+ type,
103
+ reason: 'unknown-type'
104
+ });
105
+ }
106
+ }
107
+
108
+ /**
109
+ * Determines the criterion `type`, defaulting to `simple` only when the field
110
+ * is omitted. The `type` field may be a bare string or a Criterion Expression
111
+ * Type Object (whose own `type` names the flavor). A present-but-unreadable
112
+ * `type` throws a {@link CriterionError} rather than silently defaulting.
113
+ */
114
+ #resolveType(criterion) {
115
+ const type = criterion.type;
116
+ if (type === undefined) return 'simple';
117
+ if (isCriterionExpressionTypeElement(type) && isStringElement(type.type)) {
118
+ return toValue(type.type);
119
+ }
120
+ if (isStringElement(type)) return toValue(type);
121
+ throw new CriterionError('Criterion has an invalid "type"', {
122
+ reason: 'invalid-type'
123
+ });
124
+ }
125
+
126
+ /**
127
+ * Extracts the expression `version` from a Criterion Expression Type Object,
128
+ * or `undefined` when no version is declared (a bare-string `type`, or a type
129
+ * object without a `version`) — in which case the spec default for the type
130
+ * applies. A `version` that is present but not a string is malformed and
131
+ * throws a {@link CriterionError} rather than silently defaulting.
132
+ */
133
+ #resolveVersion(criterion) {
134
+ const type = criterion.type;
135
+ if (!isCriterionExpressionTypeElement(type) || type.version === undefined) {
136
+ return undefined;
137
+ }
138
+ if (isStringElement(type.version)) {
139
+ return toValue(type.version);
140
+ }
141
+ throw new CriterionError('Criterion has an invalid expression type "version"', {
142
+ reason: 'invalid-version'
143
+ });
144
+ }
145
+
146
+ /**
147
+ * Enforces that a versioned condition type declares only the one version this
148
+ * runner supports. An omitted version is accepted (it is the spec default);
149
+ * any other declared version throws a {@link CriterionError}.
150
+ */
151
+ #requireVersion(criterion, type, condition, supported) {
152
+ const version = this.#resolveVersion(criterion);
153
+ if (version !== undefined && version !== supported) {
154
+ throw new CriterionError(`Unsupported ${type} version "${version}" (only ${supported})`, {
155
+ condition,
156
+ type,
157
+ reason: 'unsupported-version'
158
+ });
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Enforces that a present `context` is a valid runtime expression, for every
164
+ * criterion type: the spec types it `{expression}`, and `simple` ignores it,
165
+ * so a malformed one would otherwise go unnoticed there.
166
+ */
167
+ #requireValidContext(criterion, type) {
168
+ const {
169
+ context
170
+ } = criterion;
171
+ if (context === undefined) return;
172
+ if (!isStringElement(context) || !isRuntimeExpression(toValue(context))) {
173
+ throw new CriterionError('Criterion has a "context" that is not a valid runtime expression', {
174
+ type,
175
+ reason: 'invalid-context'
176
+ });
177
+ }
178
+ }
179
+
180
+ /**
181
+ * Resolves the criterion's `context` runtime expression to the value the
182
+ * condition is applied to. The condition types that need a context (`regex`,
183
+ * `jsonpath`, `xpath`) must declare one; a criterion of such a type without a
184
+ * `context` throws a {@link CriterionError}.
185
+ */
186
+ #resolveContext(criterion, type, resolve) {
187
+ if (!isStringElement(criterion.context)) {
188
+ throw new CriterionError(`Criterion type "${type}" requires a "context"`, {
189
+ type,
190
+ reason: 'missing-context'
191
+ });
192
+ }
193
+ return resolve(toValue(criterion.context));
194
+ }
195
+ }
196
+ export default CriterionEvaluator;
@@ -0,0 +1,47 @@
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 _jsonpath = require("@swaggerexpert/jsonpath");
9
+ var _CriterionError = _interopRequireDefault(require("../errors/CriterionError.cjs"));
10
+ /**
11
+ * Evaluates a `jsonpath` Arazzo criterion condition against a resolved context value.
12
+ *
13
+ * The condition is a JSONPath query (RFC 9535, per the Criterion Expression
14
+ * Type Object's pinned version) applied to the resolved `context`. The criterion
15
+ * is met when the query yields a non-empty node list.
16
+ *
17
+ * Per Arazzo 1.1.0, a `null` or `undefined` context fails the condition. The
18
+ * context is a plain runtime value (the runtime expression evaluator has already
19
+ * converted any ApiDOM element), so the default JSON evaluation realm applies.
20
+ * @public
21
+ */
22
+ class JSONPathCriterionEvaluator {
23
+ /**
24
+ * Runs the JSONPath `condition` against the resolved context value, returning
25
+ * whether it matched anything.
26
+ *
27
+ * Returns `false` when the context is `null` or `undefined`. Throws
28
+ * {@link CriterionError} when the condition is not a valid JSONPath query.
29
+ */
30
+ evaluate(condition, context) {
31
+ if (context === null || context === undefined) return false;
32
+ try {
33
+ return (0, _jsonpath.evaluate)(context, condition).length > 0;
34
+ } catch (error) {
35
+ if (error instanceof _jsonpath.JSONPathError) {
36
+ throw new _CriterionError.default(`Invalid jsonpath criterion condition "${condition}"`, {
37
+ cause: error,
38
+ condition,
39
+ type: 'jsonpath',
40
+ reason: 'invalid-jsonpath'
41
+ });
42
+ }
43
+ throw error;
44
+ }
45
+ }
46
+ }
47
+ var _default = exports.default = JSONPathCriterionEvaluator;
@@ -0,0 +1,40 @@
1
+ import { evaluate as evaluateJSONPath, JSONPathError } from '@swaggerexpert/jsonpath';
2
+ import CriterionError from "../errors/CriterionError.mjs";
3
+ /**
4
+ * Evaluates a `jsonpath` Arazzo criterion condition against a resolved context value.
5
+ *
6
+ * The condition is a JSONPath query (RFC 9535, per the Criterion Expression
7
+ * Type Object's pinned version) applied to the resolved `context`. The criterion
8
+ * is met when the query yields a non-empty node list.
9
+ *
10
+ * Per Arazzo 1.1.0, a `null` or `undefined` context fails the condition. The
11
+ * context is a plain runtime value (the runtime expression evaluator has already
12
+ * converted any ApiDOM element), so the default JSON evaluation realm applies.
13
+ * @public
14
+ */
15
+ class JSONPathCriterionEvaluator {
16
+ /**
17
+ * Runs the JSONPath `condition` against the resolved context value, returning
18
+ * whether it matched anything.
19
+ *
20
+ * Returns `false` when the context is `null` or `undefined`. Throws
21
+ * {@link CriterionError} when the condition is not a valid JSONPath query.
22
+ */
23
+ evaluate(condition, context) {
24
+ if (context === null || context === undefined) return false;
25
+ try {
26
+ return evaluateJSONPath(context, condition).length > 0;
27
+ } catch (error) {
28
+ if (error instanceof JSONPathError) {
29
+ throw new CriterionError(`Invalid jsonpath criterion condition "${condition}"`, {
30
+ cause: error,
31
+ condition,
32
+ type: 'jsonpath',
33
+ reason: 'invalid-jsonpath'
34
+ });
35
+ }
36
+ throw error;
37
+ }
38
+ }
39
+ }
40
+ export default JSONPathCriterionEvaluator;
@@ -0,0 +1,67 @@
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 _CriterionError = _interopRequireDefault(require("../errors/CriterionError.cjs"));
9
+ /**
10
+ * Evaluates a `regex` Arazzo criterion condition against a resolved context value.
11
+ *
12
+ * The Arazzo specification does not pin a regular expression dialect for the
13
+ * `regex` criterion type. This evaluator uses ECMA-262 (the native `RegExp`
14
+ * dialect), matching OpenAPI, which pins ECMA-262 for `pattern` via JSON Schema.
15
+ * The pattern is applied with search (not full-match) semantics — anchoring is
16
+ * the author's responsibility via `^`/`$`, consistent with the spec's `^200$`
17
+ * example.
18
+ *
19
+ * Per Arazzo 1.1.0, a `null` or `undefined` context fails the condition. A
20
+ * non-scalar context is serialized with `JSON.stringify` (matching how the
21
+ * runtime expression evaluator stringifies values for interpolation), so a
22
+ * pattern can match against an object/array body; scalars are coerced with
23
+ * `String()`.
24
+ *
25
+ * The pattern is a native `RegExp`, which has no execution timeout; a
26
+ * pathological author pattern (catastrophic backtracking) against a long
27
+ * context can stall. Patterns originate from the Arazzo document, so this is
28
+ * treated as trusted input rather than guarded here.
29
+ * @public
30
+ */
31
+ class RegexCriterionEvaluator {
32
+ /**
33
+ * Tests the resolved context value against the regular expression `condition`.
34
+ *
35
+ * The context is coerced to a string before matching. Returns `false` when the
36
+ * context is `null` or `undefined`. Throws {@link CriterionError} when the
37
+ * condition is not a valid regular expression.
38
+ */
39
+ evaluate(condition, context) {
40
+ if (context === null || context === undefined) return false;
41
+ let regExp;
42
+ try {
43
+ regExp = new RegExp(condition);
44
+ } catch (error) {
45
+ throw new _CriterionError.default(`Invalid regex criterion condition "${condition}"`, {
46
+ cause: error,
47
+ condition,
48
+ type: 'regex',
49
+ reason: 'invalid-regex'
50
+ });
51
+ }
52
+ return regExp.test(this.#stringify(context));
53
+ }
54
+
55
+ /**
56
+ * Coerces a non-null context value to the string the pattern is tested
57
+ * against, matching the runtime expression evaluator's interpolation
58
+ * stringify: strings as-is, objects/arrays as JSON, everything else via
59
+ * `String()`. A value whose `JSON.stringify` is `undefined` becomes `''`.
60
+ */
61
+ #stringify(context) {
62
+ if (typeof context === 'string') return context;
63
+ if (typeof context === 'object') return JSON.stringify(context) ?? '';
64
+ return String(context);
65
+ }
66
+ }
67
+ var _default = exports.default = RegexCriterionEvaluator;
@@ -0,0 +1,60 @@
1
+ import CriterionError from "../errors/CriterionError.mjs";
2
+ /**
3
+ * Evaluates a `regex` Arazzo criterion condition against a resolved context value.
4
+ *
5
+ * The Arazzo specification does not pin a regular expression dialect for the
6
+ * `regex` criterion type. This evaluator uses ECMA-262 (the native `RegExp`
7
+ * dialect), matching OpenAPI, which pins ECMA-262 for `pattern` via JSON Schema.
8
+ * The pattern is applied with search (not full-match) semantics — anchoring is
9
+ * the author's responsibility via `^`/`$`, consistent with the spec's `^200$`
10
+ * example.
11
+ *
12
+ * Per Arazzo 1.1.0, a `null` or `undefined` context fails the condition. A
13
+ * non-scalar context is serialized with `JSON.stringify` (matching how the
14
+ * runtime expression evaluator stringifies values for interpolation), so a
15
+ * pattern can match against an object/array body; scalars are coerced with
16
+ * `String()`.
17
+ *
18
+ * The pattern is a native `RegExp`, which has no execution timeout; a
19
+ * pathological author pattern (catastrophic backtracking) against a long
20
+ * context can stall. Patterns originate from the Arazzo document, so this is
21
+ * treated as trusted input rather than guarded here.
22
+ * @public
23
+ */
24
+ class RegexCriterionEvaluator {
25
+ /**
26
+ * Tests the resolved context value against the regular expression `condition`.
27
+ *
28
+ * The context is coerced to a string before matching. Returns `false` when the
29
+ * context is `null` or `undefined`. Throws {@link CriterionError} when the
30
+ * condition is not a valid regular expression.
31
+ */
32
+ evaluate(condition, context) {
33
+ if (context === null || context === undefined) return false;
34
+ let regExp;
35
+ try {
36
+ regExp = new RegExp(condition);
37
+ } catch (error) {
38
+ throw new CriterionError(`Invalid regex criterion condition "${condition}"`, {
39
+ cause: error,
40
+ condition,
41
+ type: 'regex',
42
+ reason: 'invalid-regex'
43
+ });
44
+ }
45
+ return regExp.test(this.#stringify(context));
46
+ }
47
+
48
+ /**
49
+ * Coerces a non-null context value to the string the pattern is tested
50
+ * against, matching the runtime expression evaluator's interpolation
51
+ * stringify: strings as-is, objects/arrays as JSON, everything else via
52
+ * `String()`. A value whose `JSON.stringify` is `undefined` becomes `''`.
53
+ */
54
+ #stringify(context) {
55
+ if (typeof context === 'string') return context;
56
+ if (typeof context === 'object') return JSON.stringify(context) ?? '';
57
+ return String(context);
58
+ }
59
+ }
60
+ export default RegexCriterionEvaluator;
@@ -0,0 +1,50 @@
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 _arazzoCriterion = require("@swaggerexpert/arazzo-criterion");
9
+ var _CriterionError = _interopRequireDefault(require("../errors/CriterionError.cjs"));
10
+ /**
11
+ * Evaluates a `simple` Arazzo criterion condition.
12
+ *
13
+ * A simple condition embeds runtime expressions directly in the condition
14
+ * (e.g. `$statusCode == 200 && $response.body.status == 'available'`), so —
15
+ * unlike `regex`/`jsonpath`/`xpath` — it has no separate `context`. Parsing,
16
+ * loose/case-insensitive comparison, and member/index navigation are delegated
17
+ * to `@swaggerexpert/arazzo-criterion`; each embedded runtime expression is
18
+ * resolved through the supplied resolver.
19
+ *
20
+ * An operand that resolves to `undefined` (a lenient miss) does not throw; it is
21
+ * compared per the library's rules (e.g. `undefined == x` and relational
22
+ * comparisons are false, matching the spec's "null equals only null"), so a
23
+ * negated or disjunctive condition may still pass. A malformed condition throws
24
+ * {@link CriterionError}.
25
+ * @public
26
+ */
27
+ class SimpleCriterionEvaluator {
28
+ /**
29
+ * Evaluates the simple `condition`, resolving each embedded runtime
30
+ * expression via `resolve`.
31
+ */
32
+ evaluate(condition, resolve) {
33
+ try {
34
+ return (0, _arazzoCriterion.evaluate)(condition, {
35
+ resolve
36
+ });
37
+ } catch (error) {
38
+ if (error instanceof _arazzoCriterion.ArazzoCriterionError) {
39
+ throw new _CriterionError.default(`Invalid simple criterion condition "${condition}"`, {
40
+ cause: error,
41
+ condition,
42
+ type: 'simple',
43
+ reason: 'invalid-simple'
44
+ });
45
+ }
46
+ throw error;
47
+ }
48
+ }
49
+ }
50
+ var _default = exports.default = SimpleCriterionEvaluator;