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

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 (151) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +20 -0
  3. package/README.md +784 -2
  4. package/dist/arazzo-runner.browser.js +111247 -0
  5. package/dist/arazzo-runner.browser.min.js +1 -0
  6. package/package.json +88 -4
  7. package/src/action/ActionResolver.cjs +160 -0
  8. package/src/action/ActionResolver.mjs +150 -0
  9. package/src/assembler/OpenAPI2DocumentAssembler.cjs +111 -0
  10. package/src/assembler/OpenAPI2DocumentAssembler.mjs +104 -0
  11. package/src/assembler/OpenAPI30DocumentAssembler.cjs +110 -0
  12. package/src/assembler/OpenAPI30DocumentAssembler.mjs +103 -0
  13. package/src/assembler/OpenAPI31DocumentAssembler.cjs +111 -0
  14. package/src/assembler/OpenAPI31DocumentAssembler.mjs +104 -0
  15. package/src/assembler/OpenAPIDocumentAssembler.cjs +58 -0
  16. package/src/assembler/OpenAPIDocumentAssembler.mjs +50 -0
  17. package/src/client/HTTPClient.cjs +5 -0
  18. package/src/client/HTTPClient.mjs +1 -0
  19. package/src/client/HTTPClientFetch.cjs +16 -0
  20. package/src/client/HTTPClientFetch.mjs +10 -0
  21. package/src/client/OpenAPIOperationRequest.cjs +5 -0
  22. package/src/client/OpenAPIOperationRequest.mjs +1 -0
  23. package/src/client/OpenAPIOperationResponse.cjs +42 -0
  24. package/src/client/OpenAPIOperationResponse.mjs +36 -0
  25. package/src/client/OpenAPIOperationResponseNormalizer.cjs +48 -0
  26. package/src/client/OpenAPIOperationResponseNormalizer.mjs +40 -0
  27. package/src/client/ParameterDelivery.cjs +119 -0
  28. package/src/client/ParameterDelivery.mjs +113 -0
  29. package/src/constants.cjs +9 -0
  30. package/src/constants.mjs +3 -0
  31. package/src/criterion/CriterionEvaluator.cjs +205 -0
  32. package/src/criterion/CriterionEvaluator.mjs +196 -0
  33. package/src/criterion/JSONPathCriterionEvaluator.cjs +47 -0
  34. package/src/criterion/JSONPathCriterionEvaluator.mjs +40 -0
  35. package/src/criterion/RegexCriterionEvaluator.cjs +67 -0
  36. package/src/criterion/RegexCriterionEvaluator.mjs +60 -0
  37. package/src/criterion/SimpleCriterionEvaluator.cjs +50 -0
  38. package/src/criterion/SimpleCriterionEvaluator.mjs +43 -0
  39. package/src/criterion/XPathCriterionEvaluator.cjs +117 -0
  40. package/src/criterion/XPathCriterionEvaluator.mjs +109 -0
  41. package/src/document/APIDocument.cjs +35 -0
  42. package/src/document/APIDocument.mjs +30 -0
  43. package/src/document/ArazzoDocument.cjs +81 -0
  44. package/src/document/ArazzoDocument.mjs +74 -0
  45. package/src/document/ArazzoSourceDescriptionIndex.cjs +26 -0
  46. package/src/document/ArazzoSourceDescriptionIndex.mjs +20 -0
  47. package/src/document/ArazzoStepIndex.cjs +25 -0
  48. package/src/document/ArazzoStepIndex.mjs +19 -0
  49. package/src/document/ArazzoWorkflowIndex.cjs +17 -0
  50. package/src/document/ArazzoWorkflowIndex.mjs +11 -0
  51. package/src/document/OpenAPIDocument.cjs +28 -0
  52. package/src/document/OpenAPIDocument.mjs +21 -0
  53. package/src/document/OpenAPIOperationIndex.cjs +24 -0
  54. package/src/document/OpenAPIOperationIndex.mjs +18 -0
  55. package/src/document/ParameterIdentity.cjs +93 -0
  56. package/src/document/ParameterIdentity.mjs +88 -0
  57. package/src/document/openapi-types.cjs +5 -0
  58. package/src/document/openapi-types.mjs +1 -0
  59. package/src/errors/ArazzoRunnerError.cjs +10 -0
  60. package/src/errors/ArazzoRunnerError.mjs +5 -0
  61. package/src/errors/AssemblerError.cjs +11 -0
  62. package/src/errors/AssemblerError.mjs +4 -0
  63. package/src/errors/ClientError.cjs +11 -0
  64. package/src/errors/ClientError.mjs +4 -0
  65. package/src/errors/CriterionError.cjs +11 -0
  66. package/src/errors/CriterionError.mjs +4 -0
  67. package/src/errors/ExecutionError.cjs +11 -0
  68. package/src/errors/ExecutionError.mjs +4 -0
  69. package/src/errors/ExtractionError.cjs +11 -0
  70. package/src/errors/ExtractionError.mjs +4 -0
  71. package/src/errors/InvalidEntryDocumentError.cjs +11 -0
  72. package/src/errors/InvalidEntryDocumentError.mjs +4 -0
  73. package/src/errors/NormalizationError.cjs +11 -0
  74. package/src/errors/NormalizationError.mjs +4 -0
  75. package/src/errors/ResolverError.cjs +11 -0
  76. package/src/errors/ResolverError.mjs +4 -0
  77. package/src/errors/RuntimeExpressionError.cjs +11 -0
  78. package/src/errors/RuntimeExpressionError.mjs +4 -0
  79. package/src/errors/UnmatchedProviderError.cjs +11 -0
  80. package/src/errors/UnmatchedProviderError.mjs +4 -0
  81. package/src/executor/ArazzoWorkflowLocatorNormalizer.cjs +147 -0
  82. package/src/executor/ArazzoWorkflowLocatorNormalizer.mjs +137 -0
  83. package/src/executor/OpenAPIOperationExecutor.cjs +457 -0
  84. package/src/executor/OpenAPIOperationExecutor.mjs +446 -0
  85. package/src/executor/OpenAPIOperationLocatorNormalizer.cjs +197 -0
  86. package/src/executor/OpenAPIOperationLocatorNormalizer.mjs +189 -0
  87. package/src/executor/SourceDescriptionsLocatorNormalizer.cjs +44 -0
  88. package/src/executor/SourceDescriptionsLocatorNormalizer.mjs +38 -0
  89. package/src/executor/StepExecutor.cjs +333 -0
  90. package/src/executor/StepExecutor.mjs +326 -0
  91. package/src/executor/StepRetryRunner.cjs +226 -0
  92. package/src/executor/StepRetryRunner.mjs +215 -0
  93. package/src/executor/StepTransitionInterpreter.cjs +159 -0
  94. package/src/executor/StepTransitionInterpreter.mjs +151 -0
  95. package/src/executor/WorkflowCallStack.cjs +116 -0
  96. package/src/executor/WorkflowCallStack.mjs +106 -0
  97. package/src/executor/WorkflowExecutor.cjs +1091 -0
  98. package/src/executor/WorkflowExecutor.mjs +1077 -0
  99. package/src/executor/abort.cjs +70 -0
  100. package/src/executor/abort.mjs +60 -0
  101. package/src/expression/RuntimeExpressionContext.cjs +5 -0
  102. package/src/expression/RuntimeExpressionContext.mjs +1 -0
  103. package/src/expression/RuntimeExpressionEvaluator.cjs +337 -0
  104. package/src/expression/RuntimeExpressionEvaluator.mjs +328 -0
  105. package/src/extractor/ArazzoStepExtractor.cjs +48 -0
  106. package/src/extractor/ArazzoStepExtractor.mjs +41 -0
  107. package/src/extractor/ArazzoWorkflowExtractor.cjs +50 -0
  108. package/src/extractor/ArazzoWorkflowExtractor.mjs +43 -0
  109. package/src/extractor/OpenAPIOperationExtractor.cjs +84 -0
  110. package/src/extractor/OpenAPIOperationExtractor.mjs +77 -0
  111. package/src/index.cjs +419 -0
  112. package/src/index.mjs +73 -0
  113. package/src/normalizer/ArazzoStepNormalizer.cjs +23 -0
  114. package/src/normalizer/ArazzoStepNormalizer.mjs +17 -0
  115. package/src/normalizer/ArazzoWorkflowNormalizer.cjs +214 -0
  116. package/src/normalizer/ArazzoWorkflowNormalizer.mjs +206 -0
  117. package/src/normalizer/OpenAPI2OperationNormalizer.cjs +128 -0
  118. package/src/normalizer/OpenAPI2OperationNormalizer.mjs +120 -0
  119. package/src/normalizer/OpenAPI30OperationNormalizer.cjs +129 -0
  120. package/src/normalizer/OpenAPI30OperationNormalizer.mjs +121 -0
  121. package/src/normalizer/OpenAPI31OperationNormalizer.cjs +131 -0
  122. package/src/normalizer/OpenAPI31OperationNormalizer.mjs +123 -0
  123. package/src/normalizer/OpenAPIOperationNormalizer.cjs +58 -0
  124. package/src/normalizer/OpenAPIOperationNormalizer.mjs +50 -0
  125. package/src/registry/DocumentRegistry.cjs +160 -0
  126. package/src/registry/DocumentRegistry.mjs +151 -0
  127. package/src/registry/providers/ArazzoDocumentRegistryProvider.cjs +154 -0
  128. package/src/registry/providers/ArazzoDocumentRegistryProvider.mjs +146 -0
  129. package/src/registry/providers/DocumentRegistryProvider.cjs +31 -0
  130. package/src/registry/providers/DocumentRegistryProvider.mjs +25 -0
  131. package/src/registry/providers/OpenAPIDocumentRegistryProvider.cjs +122 -0
  132. package/src/registry/providers/OpenAPIDocumentRegistryProvider.mjs +114 -0
  133. package/src/resolver/ArazzoValueResolver.cjs +42 -0
  134. package/src/resolver/ArazzoValueResolver.mjs +37 -0
  135. package/src/resolver/OpenAPIOperationParameterResolver.cjs +117 -0
  136. package/src/resolver/OpenAPIOperationParameterResolver.mjs +110 -0
  137. package/src/resolver/OutputResolver.cjs +71 -0
  138. package/src/resolver/OutputResolver.mjs +64 -0
  139. package/src/resolver/RequestBodyResolver.cjs +227 -0
  140. package/src/resolver/RequestBodyResolver.mjs +220 -0
  141. package/src/resolver/ResolverScope.cjs +5 -0
  142. package/src/resolver/ResolverScope.mjs +1 -0
  143. package/src/resolver/StepParameterResolver.cjs +22 -0
  144. package/src/resolver/StepParameterResolver.mjs +15 -0
  145. package/src/resolver/WorkflowParameterResolver.cjs +73 -0
  146. package/src/resolver/WorkflowParameterResolver.mjs +66 -0
  147. package/src/state/WorkflowExecutionState.cjs +99 -0
  148. package/src/state/WorkflowExecutionState.mjs +93 -0
  149. package/src/vendor/swagger-client.cjs +1 -0
  150. package/src/vendor/swagger-client.mjs +1 -0
  151. package/types/runner.d.ts +2341 -0
@@ -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;
@@ -0,0 +1,43 @@
1
+ import { evaluate as evaluateSimpleCriterion, ArazzoCriterionError } from '@swaggerexpert/arazzo-criterion';
2
+ import CriterionError from "../errors/CriterionError.mjs";
3
+ /**
4
+ * Evaluates a `simple` Arazzo criterion condition.
5
+ *
6
+ * A simple condition embeds runtime expressions directly in the condition
7
+ * (e.g. `$statusCode == 200 && $response.body.status == 'available'`), so —
8
+ * unlike `regex`/`jsonpath`/`xpath` — it has no separate `context`. Parsing,
9
+ * loose/case-insensitive comparison, and member/index navigation are delegated
10
+ * to `@swaggerexpert/arazzo-criterion`; each embedded runtime expression is
11
+ * resolved through the supplied resolver.
12
+ *
13
+ * An operand that resolves to `undefined` (a lenient miss) does not throw; it is
14
+ * compared per the library's rules (e.g. `undefined == x` and relational
15
+ * comparisons are false, matching the spec's "null equals only null"), so a
16
+ * negated or disjunctive condition may still pass. A malformed condition throws
17
+ * {@link CriterionError}.
18
+ * @public
19
+ */
20
+ class SimpleCriterionEvaluator {
21
+ /**
22
+ * Evaluates the simple `condition`, resolving each embedded runtime
23
+ * expression via `resolve`.
24
+ */
25
+ evaluate(condition, resolve) {
26
+ try {
27
+ return evaluateSimpleCriterion(condition, {
28
+ resolve
29
+ });
30
+ } catch (error) {
31
+ if (error instanceof ArazzoCriterionError) {
32
+ throw new CriterionError(`Invalid simple criterion condition "${condition}"`, {
33
+ cause: error,
34
+ condition,
35
+ type: 'simple',
36
+ reason: 'invalid-simple'
37
+ });
38
+ }
39
+ throw error;
40
+ }
41
+ }
42
+ }
43
+ export default SimpleCriterionEvaluator;
@@ -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 _fontoxpath = _interopRequireDefault(require("fontoxpath"));
9
+ var _xmldom = require("@xmldom/xmldom");
10
+ var _CriterionError = _interopRequireDefault(require("../errors/CriterionError.cjs"));
11
+ // fontoxpath is CommonJS and its named exports are not statically resolvable
12
+ // under ESM, so import the default and destructure.
13
+
14
+ const {
15
+ evaluateXPathToBoolean,
16
+ evaluateXPath
17
+ } = _fontoxpath.default;
18
+
19
+ /**
20
+ * Evaluates an `xpath` Arazzo criterion condition against a resolved context value.
21
+ *
22
+ * The condition is an XPath 3.1 query applied to the resolved `context`, which
23
+ * must be XML. A string context is parsed as XML; an already-parsed DOM node is
24
+ * used as-is. The criterion is met by the query's Effective Boolean Value
25
+ * (XPath 3.1 §19.1.2), as the Arazzo specification mandates — so a boolean
26
+ * predicate (`//status = 'ok'`), a non-empty node set, a non-zero number, and a
27
+ * non-empty string all evaluate to `true`.
28
+ *
29
+ * Only XPath 3.1 is supported (`fontoxpath`'s engine); version gating happens in
30
+ * the facade. Per Arazzo 1.1.0, a `null` or `undefined` context fails the
31
+ * condition. An invalid query throws {@link CriterionError}.
32
+ * @public
33
+ */
34
+ class XPathCriterionEvaluator {
35
+ /**
36
+ * Evaluates the XPath `condition` against the resolved context value, returning
37
+ * its Effective Boolean Value.
38
+ *
39
+ * Returns `false` when the context is `null` or `undefined`. Throws
40
+ * {@link CriterionError} when the context is not XML or the query is invalid.
41
+ */
42
+ evaluate(condition, context) {
43
+ if (context === null || context === undefined) return false;
44
+ const node = this.#toNode(condition, context);
45
+ try {
46
+ return evaluateXPathToBoolean(condition, node, null, null, {
47
+ language: evaluateXPath.XPATH_3_1_LANGUAGE
48
+ });
49
+ } catch (error) {
50
+ throw new _CriterionError.default(`Invalid xpath criterion condition "${condition}"`, {
51
+ cause: error,
52
+ condition,
53
+ type: 'xpath',
54
+ reason: 'invalid-xpath'
55
+ });
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Coerces the resolved context to an XML DOM node: an already-parsed node is
61
+ * used as-is, a string is parsed as XML. Any other value cannot be an XPath
62
+ * context and throws.
63
+ */
64
+ #toNode(condition, context) {
65
+ if (this.#isNode(context)) return context;
66
+ if (typeof context !== 'string') {
67
+ throw new _CriterionError.default('xpath criterion context is not XML', {
68
+ condition,
69
+ type: 'xpath',
70
+ reason: 'invalid-context'
71
+ });
72
+ }
73
+
74
+ // capture parse errors via `onError` rather than the default handler: this
75
+ // both suppresses the parser writing to the console and catches *recoverable*
76
+ // errors (e.g. an undefined entity, stray text) that do not throw but would
77
+ // otherwise yield a degraded document evaluated silently.
78
+ let parseError;
79
+ try {
80
+ const document = new _xmldom.DOMParser({
81
+ onError: (_level, message) => {
82
+ parseError ??= message;
83
+ }
84
+ }).parseFromString(context, 'text/xml');
85
+ if (parseError !== undefined) {
86
+ throw new _CriterionError.default('xpath criterion context is not valid XML', {
87
+ cause: parseError,
88
+ condition,
89
+ type: 'xpath',
90
+ reason: 'invalid-context'
91
+ });
92
+ }
93
+ return document;
94
+ } catch (error) {
95
+ if (error instanceof _CriterionError.default) throw error;
96
+ throw new _CriterionError.default('xpath criterion context is not valid XML', {
97
+ cause: error,
98
+ condition,
99
+ type: 'xpath',
100
+ reason: 'invalid-context'
101
+ });
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Duck-types a DOM node, so a caller may pass an already-parsed document
107
+ * instead of an XML string. Requires both a numeric `nodeType` and a string
108
+ * `nodeName` so a plain JSON value that happens to carry a `nodeType` property
109
+ * is not mistaken for a node (and is instead rejected as a non-XML context).
110
+ */
111
+ #isNode(value) {
112
+ if (typeof value !== 'object' || value === null) return false;
113
+ const node = value;
114
+ return typeof node.nodeType === 'number' && typeof node.nodeName === 'string';
115
+ }
116
+ }
117
+ var _default = exports.default = XPathCriterionEvaluator;