@usearazzo/runner 0.0.0-stage → 1.0.1-alpha.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/LICENSE +202 -0
- package/NOTICE +20 -0
- package/README.md +777 -2
- package/dist/arazzo-runner.browser.js +111247 -0
- package/dist/arazzo-runner.browser.min.js +1 -0
- package/package.json +90 -4
- package/src/action/ActionResolver.cjs +160 -0
- package/src/action/ActionResolver.mjs +150 -0
- package/src/assembler/OpenAPI2DocumentAssembler.cjs +111 -0
- package/src/assembler/OpenAPI2DocumentAssembler.mjs +104 -0
- package/src/assembler/OpenAPI30DocumentAssembler.cjs +110 -0
- package/src/assembler/OpenAPI30DocumentAssembler.mjs +103 -0
- package/src/assembler/OpenAPI31DocumentAssembler.cjs +111 -0
- package/src/assembler/OpenAPI31DocumentAssembler.mjs +104 -0
- package/src/assembler/OpenAPIDocumentAssembler.cjs +58 -0
- package/src/assembler/OpenAPIDocumentAssembler.mjs +50 -0
- package/src/client/HTTPClient.cjs +5 -0
- package/src/client/HTTPClient.mjs +1 -0
- package/src/client/HTTPClientFetch.cjs +16 -0
- package/src/client/HTTPClientFetch.mjs +10 -0
- package/src/client/OpenAPIOperationRequest.cjs +5 -0
- package/src/client/OpenAPIOperationRequest.mjs +1 -0
- package/src/client/OpenAPIOperationResponse.cjs +42 -0
- package/src/client/OpenAPIOperationResponse.mjs +36 -0
- package/src/client/OpenAPIOperationResponseNormalizer.cjs +48 -0
- package/src/client/OpenAPIOperationResponseNormalizer.mjs +40 -0
- package/src/client/ParameterDelivery.cjs +119 -0
- package/src/client/ParameterDelivery.mjs +113 -0
- package/src/constants.cjs +9 -0
- package/src/constants.mjs +3 -0
- package/src/criterion/CriterionEvaluator.cjs +205 -0
- package/src/criterion/CriterionEvaluator.mjs +196 -0
- package/src/criterion/JSONPathCriterionEvaluator.cjs +47 -0
- package/src/criterion/JSONPathCriterionEvaluator.mjs +40 -0
- package/src/criterion/RegexCriterionEvaluator.cjs +67 -0
- package/src/criterion/RegexCriterionEvaluator.mjs +60 -0
- package/src/criterion/SimpleCriterionEvaluator.cjs +50 -0
- package/src/criterion/SimpleCriterionEvaluator.mjs +43 -0
- package/src/criterion/XPathCriterionEvaluator.cjs +117 -0
- package/src/criterion/XPathCriterionEvaluator.mjs +109 -0
- package/src/document/APIDocument.cjs +35 -0
- package/src/document/APIDocument.mjs +30 -0
- package/src/document/ArazzoDocument.cjs +81 -0
- package/src/document/ArazzoDocument.mjs +74 -0
- package/src/document/ArazzoSourceDescriptionIndex.cjs +26 -0
- package/src/document/ArazzoSourceDescriptionIndex.mjs +20 -0
- package/src/document/ArazzoStepIndex.cjs +25 -0
- package/src/document/ArazzoStepIndex.mjs +19 -0
- package/src/document/ArazzoWorkflowIndex.cjs +17 -0
- package/src/document/ArazzoWorkflowIndex.mjs +11 -0
- package/src/document/OpenAPIDocument.cjs +28 -0
- package/src/document/OpenAPIDocument.mjs +21 -0
- package/src/document/OpenAPIOperationIndex.cjs +24 -0
- package/src/document/OpenAPIOperationIndex.mjs +18 -0
- package/src/document/ParameterIdentity.cjs +93 -0
- package/src/document/ParameterIdentity.mjs +88 -0
- package/src/document/openapi-types.cjs +5 -0
- package/src/document/openapi-types.mjs +1 -0
- package/src/errors/ArazzoRunnerError.cjs +10 -0
- package/src/errors/ArazzoRunnerError.mjs +5 -0
- package/src/errors/AssemblerError.cjs +11 -0
- package/src/errors/AssemblerError.mjs +4 -0
- package/src/errors/ClientError.cjs +11 -0
- package/src/errors/ClientError.mjs +4 -0
- package/src/errors/CriterionError.cjs +11 -0
- package/src/errors/CriterionError.mjs +4 -0
- package/src/errors/ExecutionError.cjs +11 -0
- package/src/errors/ExecutionError.mjs +4 -0
- package/src/errors/ExtractionError.cjs +11 -0
- package/src/errors/ExtractionError.mjs +4 -0
- package/src/errors/InvalidEntryDocumentError.cjs +11 -0
- package/src/errors/InvalidEntryDocumentError.mjs +4 -0
- package/src/errors/NormalizationError.cjs +11 -0
- package/src/errors/NormalizationError.mjs +4 -0
- package/src/errors/ResolverError.cjs +11 -0
- package/src/errors/ResolverError.mjs +4 -0
- package/src/errors/RuntimeExpressionError.cjs +11 -0
- package/src/errors/RuntimeExpressionError.mjs +4 -0
- package/src/errors/UnmatchedProviderError.cjs +11 -0
- package/src/errors/UnmatchedProviderError.mjs +4 -0
- package/src/executor/ArazzoWorkflowLocatorNormalizer.cjs +147 -0
- package/src/executor/ArazzoWorkflowLocatorNormalizer.mjs +137 -0
- package/src/executor/OpenAPIOperationExecutor.cjs +457 -0
- package/src/executor/OpenAPIOperationExecutor.mjs +446 -0
- package/src/executor/OpenAPIOperationLocatorNormalizer.cjs +197 -0
- package/src/executor/OpenAPIOperationLocatorNormalizer.mjs +189 -0
- package/src/executor/SourceDescriptionsLocatorNormalizer.cjs +44 -0
- package/src/executor/SourceDescriptionsLocatorNormalizer.mjs +38 -0
- package/src/executor/StepExecutor.cjs +333 -0
- package/src/executor/StepExecutor.mjs +326 -0
- package/src/executor/StepRetryRunner.cjs +226 -0
- package/src/executor/StepRetryRunner.mjs +215 -0
- package/src/executor/StepTransitionInterpreter.cjs +159 -0
- package/src/executor/StepTransitionInterpreter.mjs +151 -0
- package/src/executor/WorkflowCallStack.cjs +116 -0
- package/src/executor/WorkflowCallStack.mjs +106 -0
- package/src/executor/WorkflowExecutor.cjs +1091 -0
- package/src/executor/WorkflowExecutor.mjs +1077 -0
- package/src/executor/abort.cjs +70 -0
- package/src/executor/abort.mjs +60 -0
- package/src/expression/RuntimeExpressionContext.cjs +5 -0
- package/src/expression/RuntimeExpressionContext.mjs +1 -0
- package/src/expression/RuntimeExpressionEvaluator.cjs +337 -0
- package/src/expression/RuntimeExpressionEvaluator.mjs +328 -0
- package/src/extractor/ArazzoStepExtractor.cjs +48 -0
- package/src/extractor/ArazzoStepExtractor.mjs +41 -0
- package/src/extractor/ArazzoWorkflowExtractor.cjs +50 -0
- package/src/extractor/ArazzoWorkflowExtractor.mjs +43 -0
- package/src/extractor/OpenAPIOperationExtractor.cjs +84 -0
- package/src/extractor/OpenAPIOperationExtractor.mjs +77 -0
- package/src/index.cjs +419 -0
- package/src/index.mjs +73 -0
- package/src/normalizer/ArazzoStepNormalizer.cjs +23 -0
- package/src/normalizer/ArazzoStepNormalizer.mjs +17 -0
- package/src/normalizer/ArazzoWorkflowNormalizer.cjs +214 -0
- package/src/normalizer/ArazzoWorkflowNormalizer.mjs +206 -0
- package/src/normalizer/OpenAPI2OperationNormalizer.cjs +128 -0
- package/src/normalizer/OpenAPI2OperationNormalizer.mjs +120 -0
- package/src/normalizer/OpenAPI30OperationNormalizer.cjs +129 -0
- package/src/normalizer/OpenAPI30OperationNormalizer.mjs +121 -0
- package/src/normalizer/OpenAPI31OperationNormalizer.cjs +131 -0
- package/src/normalizer/OpenAPI31OperationNormalizer.mjs +123 -0
- package/src/normalizer/OpenAPIOperationNormalizer.cjs +58 -0
- package/src/normalizer/OpenAPIOperationNormalizer.mjs +50 -0
- package/src/registry/DocumentRegistry.cjs +160 -0
- package/src/registry/DocumentRegistry.mjs +151 -0
- package/src/registry/providers/ArazzoDocumentRegistryProvider.cjs +154 -0
- package/src/registry/providers/ArazzoDocumentRegistryProvider.mjs +146 -0
- package/src/registry/providers/DocumentRegistryProvider.cjs +31 -0
- package/src/registry/providers/DocumentRegistryProvider.mjs +25 -0
- package/src/registry/providers/OpenAPIDocumentRegistryProvider.cjs +122 -0
- package/src/registry/providers/OpenAPIDocumentRegistryProvider.mjs +114 -0
- package/src/resolver/ArazzoValueResolver.cjs +42 -0
- package/src/resolver/ArazzoValueResolver.mjs +37 -0
- package/src/resolver/OpenAPIOperationParameterResolver.cjs +117 -0
- package/src/resolver/OpenAPIOperationParameterResolver.mjs +110 -0
- package/src/resolver/OutputResolver.cjs +71 -0
- package/src/resolver/OutputResolver.mjs +64 -0
- package/src/resolver/RequestBodyResolver.cjs +227 -0
- package/src/resolver/RequestBodyResolver.mjs +220 -0
- package/src/resolver/ResolverScope.cjs +5 -0
- package/src/resolver/ResolverScope.mjs +1 -0
- package/src/resolver/StepParameterResolver.cjs +22 -0
- package/src/resolver/StepParameterResolver.mjs +15 -0
- package/src/resolver/WorkflowParameterResolver.cjs +73 -0
- package/src/resolver/WorkflowParameterResolver.mjs +66 -0
- package/src/state/WorkflowExecutionState.cjs +99 -0
- package/src/state/WorkflowExecutionState.mjs +93 -0
- package/src/vendor/swagger-client.cjs +1 -0
- package/src/vendor/swagger-client.mjs +1 -0
- package/types/runner.d.ts +2341 -0
|
@@ -0,0 +1,48 @@
|
|
|
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 _swaggerClient = require("../vendor/swagger-client.cjs");
|
|
9
|
+
var _OpenAPIOperationResponse = _interopRequireDefault(require("./OpenAPIOperationResponse.cjs"));
|
|
10
|
+
// @ts-expect-error vendored swagger-client bundle has no type declarations
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Normalizes a raw WHATWG `Response` into an {@link OpenAPIOperationResponse}.
|
|
14
|
+
*
|
|
15
|
+
* Wraps the vendored swagger-client response deserializer (upstream
|
|
16
|
+
* `serializeRes`, aliased at the vendor boundary), whose battle-tested
|
|
17
|
+
* content-type dispatch (JSON/XML/YAML/text vs binary) means the response
|
|
18
|
+
* model runtime expressions and criteria see is defined here, on the runner's
|
|
19
|
+
* side of the {@link HTTPClient} seam, and stays identical across transports.
|
|
20
|
+
* Headers are taken from the `Response` directly rather than from the
|
|
21
|
+
* deserializer, which splits every value containing `", "` into an array:
|
|
22
|
+
* values stay strings as sent, with repeated fields (`Set-Cookie` included)
|
|
23
|
+
* combined by `Headers.get`.
|
|
24
|
+
* @public
|
|
25
|
+
*/
|
|
26
|
+
class OpenAPIOperationResponseNormalizer {
|
|
27
|
+
/**
|
|
28
|
+
* Deserializes the response body by content type and maps the result into the
|
|
29
|
+
* runner's response model. `request` is the request the operation was
|
|
30
|
+
* executed with; its `url` doubles as the fallback when the `Response`
|
|
31
|
+
* carries none (e.g. a stubbed transport).
|
|
32
|
+
*/
|
|
33
|
+
async normalize(response, request) {
|
|
34
|
+
const deserialized = await (0, _swaggerClient.deserializeResponse)(response, request?.url);
|
|
35
|
+
const headers = Object.fromEntries(Array.from(response.headers.keys(), name => [name, response.headers.get(name)]));
|
|
36
|
+
return new _OpenAPIOperationResponse.default({
|
|
37
|
+
ok: deserialized.ok,
|
|
38
|
+
url: deserialized.url,
|
|
39
|
+
status: deserialized.status,
|
|
40
|
+
statusText: deserialized.statusText,
|
|
41
|
+
headers,
|
|
42
|
+
text: deserialized.text,
|
|
43
|
+
body: deserialized.body,
|
|
44
|
+
request
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
var _default = exports.default = OpenAPIOperationResponseNormalizer;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// @ts-expect-error vendored swagger-client bundle has no type declarations
|
|
2
|
+
import { deserializeResponse } from '../vendor/swagger-client.mjs';
|
|
3
|
+
import OpenAPIOperationResponse from "./OpenAPIOperationResponse.mjs";
|
|
4
|
+
/**
|
|
5
|
+
* Normalizes a raw WHATWG `Response` into an {@link OpenAPIOperationResponse}.
|
|
6
|
+
*
|
|
7
|
+
* Wraps the vendored swagger-client response deserializer (upstream
|
|
8
|
+
* `serializeRes`, aliased at the vendor boundary), whose battle-tested
|
|
9
|
+
* content-type dispatch (JSON/XML/YAML/text vs binary) means the response
|
|
10
|
+
* model runtime expressions and criteria see is defined here, on the runner's
|
|
11
|
+
* side of the {@link HTTPClient} seam, and stays identical across transports.
|
|
12
|
+
* Headers are taken from the `Response` directly rather than from the
|
|
13
|
+
* deserializer, which splits every value containing `", "` into an array:
|
|
14
|
+
* values stay strings as sent, with repeated fields (`Set-Cookie` included)
|
|
15
|
+
* combined by `Headers.get`.
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
class OpenAPIOperationResponseNormalizer {
|
|
19
|
+
/**
|
|
20
|
+
* Deserializes the response body by content type and maps the result into the
|
|
21
|
+
* runner's response model. `request` is the request the operation was
|
|
22
|
+
* executed with; its `url` doubles as the fallback when the `Response`
|
|
23
|
+
* carries none (e.g. a stubbed transport).
|
|
24
|
+
*/
|
|
25
|
+
async normalize(response, request) {
|
|
26
|
+
const deserialized = await deserializeResponse(response, request?.url);
|
|
27
|
+
const headers = Object.fromEntries(Array.from(response.headers.keys(), name => [name, response.headers.get(name)]));
|
|
28
|
+
return new OpenAPIOperationResponse({
|
|
29
|
+
ok: deserialized.ok,
|
|
30
|
+
url: deserialized.url,
|
|
31
|
+
status: deserialized.status,
|
|
32
|
+
statusText: deserialized.statusText,
|
|
33
|
+
headers,
|
|
34
|
+
text: deserialized.text,
|
|
35
|
+
body: deserialized.body,
|
|
36
|
+
request
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export default OpenAPIOperationResponseNormalizer;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* The outcome of claiming a delivery key: `claimed` for a first claim,
|
|
9
|
+
* `duplicate` when the same `(name, in)` parameter claims its key again, and
|
|
10
|
+
* `collision` when a *different* parameter produces an already-claimed key.
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* A parameter claim: the delivery key the `(location, name)` pair encodes to,
|
|
16
|
+
* and how the claim resolved against the map's earlier entries.
|
|
17
|
+
* @internal
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The parameters map an OpenAPI operation is executed with — the single owner
|
|
22
|
+
* of the vendored swagger-client's parameter-addressing scheme.
|
|
23
|
+
*
|
|
24
|
+
* The client accepts two key shapes in its `parameters` map and, for each
|
|
25
|
+
* parameter the operation declares, consults the bare `name` *before* the
|
|
26
|
+
* qualified `'{in}.{name}'` key (deminified from the vendored bundle:
|
|
27
|
+
* `r = m[e.name]; if (r === undefined) r = m[`${e.in}.${e.name}`]`). Two
|
|
28
|
+
* consequences shape everything that feeds the map:
|
|
29
|
+
*
|
|
30
|
+
* - qualified keys are what let parameters differing only in their location
|
|
31
|
+
* coexist — the client builds the same key from the declared parameter and
|
|
32
|
+
* matches it verbatim, never splitting it, so dots in a name are safe;
|
|
33
|
+
* - a bare key silently outranks the qualified keys of every declared
|
|
34
|
+
* parameter bearing that name, so nothing may emit one for a location the
|
|
35
|
+
* client can address.
|
|
36
|
+
*
|
|
37
|
+
* Arazzo's `querystring` is the one location the client cannot address — it
|
|
38
|
+
* names no OpenAPI location — so it keeps the bare name, which can still
|
|
39
|
+
* reach a same-named declared parameter. Every other location is qualified,
|
|
40
|
+
* including an unrecognized one: an unmatched qualified key is inert, where a
|
|
41
|
+
* bare one would capture.
|
|
42
|
+
*
|
|
43
|
+
* Keys are claimed first-wins. The scheme is not injective, so the map also
|
|
44
|
+
* discriminates a genuine duplicate from a collision of two different
|
|
45
|
+
* parameters on one key: given a key, the claimant's name is determined by
|
|
46
|
+
* its location (the key embeds the name, or is the name), so the location
|
|
47
|
+
* alone identifies the claimant. A bare key and a qualified key sharing one
|
|
48
|
+
* name are a collision too, even though the keys differ — the client consults
|
|
49
|
+
* the bare name first for every declared parameter bearing it, so the bare
|
|
50
|
+
* entry would silently capture the qualified one. What to do about a
|
|
51
|
+
* collision is the caller's policy — the map only reports it.
|
|
52
|
+
*
|
|
53
|
+
* Diff this against the vendored bundle's lookup when bumping swagger-client.
|
|
54
|
+
* @internal
|
|
55
|
+
*/
|
|
56
|
+
class ParameterDelivery {
|
|
57
|
+
/**
|
|
58
|
+
* The key a `(location, name)` pair is delivered under — `'{in}.{name}'`,
|
|
59
|
+
* or the bare name for `querystring`. See the class doc for why.
|
|
60
|
+
*/
|
|
61
|
+
static keyFor(location, name) {
|
|
62
|
+
return location === 'querystring' ? name : `${location}.${name}`;
|
|
63
|
+
}
|
|
64
|
+
#values = {};
|
|
65
|
+
#claimedBy = new Map();
|
|
66
|
+
#bareNames = new Set();
|
|
67
|
+
#qualifiedNames = new Set();
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Claims the delivery key for a `(location, name)` pair, first-wins.
|
|
71
|
+
* Only a `claimed` outcome entitles the caller to {@link ParameterDelivery.set}
|
|
72
|
+
* the key; a `duplicate` means the same parameter already holds it, and a
|
|
73
|
+
* `collision` means a different parameter does — on the same key, or across
|
|
74
|
+
* a bare/qualified pair sharing the name (see the class doc).
|
|
75
|
+
*/
|
|
76
|
+
claim(location, name) {
|
|
77
|
+
const key = ParameterDelivery.keyFor(location, name);
|
|
78
|
+
const claimant = this.#claimedBy.get(key);
|
|
79
|
+
if (claimant !== undefined) {
|
|
80
|
+
return {
|
|
81
|
+
key,
|
|
82
|
+
outcome: claimant === location ? 'duplicate' : 'collision'
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
const bare = key === name;
|
|
86
|
+
if (bare ? this.#qualifiedNames.has(name) : this.#bareNames.has(name)) {
|
|
87
|
+
return {
|
|
88
|
+
key,
|
|
89
|
+
outcome: 'collision'
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
(bare ? this.#bareNames : this.#qualifiedNames).add(name);
|
|
93
|
+
this.#claimedBy.set(key, location);
|
|
94
|
+
return {
|
|
95
|
+
key,
|
|
96
|
+
outcome: 'claimed'
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
set(key, value) {
|
|
100
|
+
// defined rather than assigned: a key like `__proto__` hits the
|
|
101
|
+
// Object.prototype accessor on bracket assignment, so no own property is
|
|
102
|
+
// ever created and the parameter is silently lost — and an object value
|
|
103
|
+
// additionally rewrites the record's prototype
|
|
104
|
+
Object.defineProperty(this.#values, key, {
|
|
105
|
+
value,
|
|
106
|
+
enumerable: true,
|
|
107
|
+
writable: true,
|
|
108
|
+
configurable: true
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* The accumulated record, in the shape `buildRequest` consumes.
|
|
114
|
+
*/
|
|
115
|
+
toRecord() {
|
|
116
|
+
return this.#values;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
var _default = exports.default = ParameterDelivery;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The outcome of claiming a delivery key: `claimed` for a first claim,
|
|
3
|
+
* `duplicate` when the same `(name, in)` parameter claims its key again, and
|
|
4
|
+
* `collision` when a *different* parameter produces an already-claimed key.
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A parameter claim: the delivery key the `(location, name)` pair encodes to,
|
|
10
|
+
* and how the claim resolved against the map's earlier entries.
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The parameters map an OpenAPI operation is executed with — the single owner
|
|
16
|
+
* of the vendored swagger-client's parameter-addressing scheme.
|
|
17
|
+
*
|
|
18
|
+
* The client accepts two key shapes in its `parameters` map and, for each
|
|
19
|
+
* parameter the operation declares, consults the bare `name` *before* the
|
|
20
|
+
* qualified `'{in}.{name}'` key (deminified from the vendored bundle:
|
|
21
|
+
* `r = m[e.name]; if (r === undefined) r = m[`${e.in}.${e.name}`]`). Two
|
|
22
|
+
* consequences shape everything that feeds the map:
|
|
23
|
+
*
|
|
24
|
+
* - qualified keys are what let parameters differing only in their location
|
|
25
|
+
* coexist — the client builds the same key from the declared parameter and
|
|
26
|
+
* matches it verbatim, never splitting it, so dots in a name are safe;
|
|
27
|
+
* - a bare key silently outranks the qualified keys of every declared
|
|
28
|
+
* parameter bearing that name, so nothing may emit one for a location the
|
|
29
|
+
* client can address.
|
|
30
|
+
*
|
|
31
|
+
* Arazzo's `querystring` is the one location the client cannot address — it
|
|
32
|
+
* names no OpenAPI location — so it keeps the bare name, which can still
|
|
33
|
+
* reach a same-named declared parameter. Every other location is qualified,
|
|
34
|
+
* including an unrecognized one: an unmatched qualified key is inert, where a
|
|
35
|
+
* bare one would capture.
|
|
36
|
+
*
|
|
37
|
+
* Keys are claimed first-wins. The scheme is not injective, so the map also
|
|
38
|
+
* discriminates a genuine duplicate from a collision of two different
|
|
39
|
+
* parameters on one key: given a key, the claimant's name is determined by
|
|
40
|
+
* its location (the key embeds the name, or is the name), so the location
|
|
41
|
+
* alone identifies the claimant. A bare key and a qualified key sharing one
|
|
42
|
+
* name are a collision too, even though the keys differ — the client consults
|
|
43
|
+
* the bare name first for every declared parameter bearing it, so the bare
|
|
44
|
+
* entry would silently capture the qualified one. What to do about a
|
|
45
|
+
* collision is the caller's policy — the map only reports it.
|
|
46
|
+
*
|
|
47
|
+
* Diff this against the vendored bundle's lookup when bumping swagger-client.
|
|
48
|
+
* @internal
|
|
49
|
+
*/
|
|
50
|
+
class ParameterDelivery {
|
|
51
|
+
/**
|
|
52
|
+
* The key a `(location, name)` pair is delivered under — `'{in}.{name}'`,
|
|
53
|
+
* or the bare name for `querystring`. See the class doc for why.
|
|
54
|
+
*/
|
|
55
|
+
static keyFor(location, name) {
|
|
56
|
+
return location === 'querystring' ? name : `${location}.${name}`;
|
|
57
|
+
}
|
|
58
|
+
#values = {};
|
|
59
|
+
#claimedBy = new Map();
|
|
60
|
+
#bareNames = new Set();
|
|
61
|
+
#qualifiedNames = new Set();
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Claims the delivery key for a `(location, name)` pair, first-wins.
|
|
65
|
+
* Only a `claimed` outcome entitles the caller to {@link ParameterDelivery.set}
|
|
66
|
+
* the key; a `duplicate` means the same parameter already holds it, and a
|
|
67
|
+
* `collision` means a different parameter does — on the same key, or across
|
|
68
|
+
* a bare/qualified pair sharing the name (see the class doc).
|
|
69
|
+
*/
|
|
70
|
+
claim(location, name) {
|
|
71
|
+
const key = ParameterDelivery.keyFor(location, name);
|
|
72
|
+
const claimant = this.#claimedBy.get(key);
|
|
73
|
+
if (claimant !== undefined) {
|
|
74
|
+
return {
|
|
75
|
+
key,
|
|
76
|
+
outcome: claimant === location ? 'duplicate' : 'collision'
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
const bare = key === name;
|
|
80
|
+
if (bare ? this.#qualifiedNames.has(name) : this.#bareNames.has(name)) {
|
|
81
|
+
return {
|
|
82
|
+
key,
|
|
83
|
+
outcome: 'collision'
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
(bare ? this.#bareNames : this.#qualifiedNames).add(name);
|
|
87
|
+
this.#claimedBy.set(key, location);
|
|
88
|
+
return {
|
|
89
|
+
key,
|
|
90
|
+
outcome: 'claimed'
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
set(key, value) {
|
|
94
|
+
// defined rather than assigned: a key like `__proto__` hits the
|
|
95
|
+
// Object.prototype accessor on bracket assignment, so no own property is
|
|
96
|
+
// ever created and the parameter is silently lost — and an object value
|
|
97
|
+
// additionally rewrites the record's prototype
|
|
98
|
+
Object.defineProperty(this.#values, key, {
|
|
99
|
+
value,
|
|
100
|
+
enumerable: true,
|
|
101
|
+
writable: true,
|
|
102
|
+
configurable: true
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* The accumulated record, in the shape `buildRequest` consumes.
|
|
108
|
+
*/
|
|
109
|
+
toRecord() {
|
|
110
|
+
return this.#values;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
export default ParameterDelivery;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.MAX_HTTP_CACHE_STALE_AGE = exports.MAX_HTTP_CACHE_ENTRIES = exports.MAX_DOCUMENT_REGISTRY_SIZE = void 0;
|
|
7
|
+
const MAX_HTTP_CACHE_ENTRIES = exports.MAX_HTTP_CACHE_ENTRIES = 6;
|
|
8
|
+
const MAX_HTTP_CACHE_STALE_AGE = exports.MAX_HTTP_CACHE_STALE_AGE = 120_000; // 2 minutes in milliseconds
|
|
9
|
+
const MAX_DOCUMENT_REGISTRY_SIZE = exports.MAX_DOCUMENT_REGISTRY_SIZE = 4;
|
|
@@ -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;
|