@swaggerexpert/arazzo-runtime-expression 1.0.1 → 2.0.2
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/README.md +157 -77
- package/SECURITY.md +2 -1
- package/cjs/apg-lite.cjs +28 -28
- package/cjs/errors/ArazzoRuntimeExpressionError.cjs +44 -0
- package/cjs/errors/ArazzoRuntimeExpressionParseError.cjs +8 -0
- package/cjs/extract.cjs +35 -9
- package/cjs/{runtime-expression.cjs → grammar.cjs} +824 -286
- package/cjs/index.cjs +17 -5
- package/cjs/parse/callbacks/cst.cjs +28 -0
- package/cjs/parse/index.cjs +31 -32
- package/cjs/parse/trace/Expectations.cjs +10 -0
- package/cjs/parse/trace/Trace.cjs +35 -0
- package/cjs/parse/translators/ASTTranslator/index.cjs +15 -0
- package/cjs/parse/translators/ASTTranslator/transformers.cjs +225 -0
- package/cjs/parse/translators/CSTTranslator.cjs +55 -0
- package/cjs/parse/translators/XMLTranslator.cjs +12 -0
- package/cjs/test/index.cjs +18 -0
- package/es/errors/ArazzoRuntimeExpressionError.mjs +40 -0
- package/es/errors/ArazzoRuntimeExpressionParseError.mjs +3 -0
- package/es/extract.mjs +34 -9
- package/es/{runtime-expression.mjs → grammar.mjs} +824 -286
- package/es/index.mjs +9 -3
- package/es/parse/callbacks/cst.mjs +24 -0
- package/es/parse/index.mjs +31 -32
- package/es/parse/trace/Expectations.mjs +6 -0
- package/es/parse/trace/Trace.mjs +30 -0
- package/es/parse/translators/ASTTranslator/index.mjs +9 -0
- package/es/parse/translators/ASTTranslator/transformers.mjs +219 -0
- package/es/parse/translators/CSTTranslator.mjs +50 -0
- package/es/parse/translators/XMLTranslator.mjs +7 -0
- package/es/test/index.mjs +13 -0
- package/package.json +21 -14
- package/types/index.d.ts +364 -34
- package/cjs/parse/callbacks/body-reference.cjs +0 -14
- package/cjs/parse/callbacks/expression.cjs +0 -15
- package/cjs/parse/callbacks/header-reference.cjs +0 -14
- package/cjs/parse/callbacks/json-pointer.cjs +0 -14
- package/cjs/parse/callbacks/name.cjs +0 -14
- package/cjs/parse/callbacks/parameter-name.cjs +0 -14
- package/cjs/parse/callbacks/path-reference.cjs +0 -14
- package/cjs/parse/callbacks/query-reference.cjs +0 -14
- package/cjs/parse/callbacks/reference-token.cjs +0 -14
- package/cjs/parse/callbacks/source.cjs +0 -14
- package/cjs/parse/callbacks/token.cjs +0 -15
- package/cjs/test.cjs +0 -15
- package/es/parse/callbacks/body-reference.mjs +0 -10
- package/es/parse/callbacks/expression.mjs +0 -11
- package/es/parse/callbacks/header-reference.mjs +0 -10
- package/es/parse/callbacks/json-pointer.mjs +0 -10
- package/es/parse/callbacks/name.mjs +0 -10
- package/es/parse/callbacks/parameter-name.mjs +0 -10
- package/es/parse/callbacks/path-reference.mjs +0 -10
- package/es/parse/callbacks/query-reference.mjs +0 -10
- package/es/parse/callbacks/reference-token.mjs +0 -10
- package/es/parse/callbacks/source.mjs +0 -10
- package/es/parse/callbacks/token.mjs +0 -10
- package/es/test.mjs +0 -10
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ It supports Runtime Expressions defined in following Arazzo specification versio
|
|
|
20
20
|
<table>
|
|
21
21
|
<tr>
|
|
22
22
|
<td align="right" valign="middle">
|
|
23
|
-
<img src="https://
|
|
23
|
+
<img src="https://raw.githubusercontent.com/swaggerexpert/arazzo-runtime-expression/main/assets/tidelift.webp" alt="Tidelift" width="60" />
|
|
24
24
|
</td>
|
|
25
25
|
<td valign="middle">
|
|
26
26
|
<a href="https://tidelift.com/subscription/pkg/npm-.swaggerexpert-arazzo-runtime-expression?utm_source=npm-swaggerexpert-arazzo-runtime-expression&utm_medium=referral&utm_campaign=readme">
|
|
@@ -37,7 +37,11 @@ It supports Runtime Expressions defined in following Arazzo specification versio
|
|
|
37
37
|
- [Usage](#usage)
|
|
38
38
|
- [Extraction](#extraction)
|
|
39
39
|
- [Parsing](#parsing)
|
|
40
|
+
- [Translators](#translators)
|
|
41
|
+
- [Statistics](#statistics)
|
|
42
|
+
- [Tracing](#tracing)
|
|
40
43
|
- [Validation](#validation)
|
|
44
|
+
- [Errors](#errors)
|
|
41
45
|
- [Grammar](#grammar)
|
|
42
46
|
- [More about Arazzo runtime expressions](#more-about-arazzo-runtime-expressions)
|
|
43
47
|
- [License](#license)
|
|
@@ -63,17 +67,32 @@ and use [apg-lite](https://github.com/ldthomas/apg-lite) parser generator.
|
|
|
63
67
|
|
|
64
68
|
Arazzo embeds Runtime Expressions into string values surrounded with `{}` curly braces.
|
|
65
69
|
To extract Runtime Expressions from this embedded form, use the **extract** function.
|
|
66
|
-
|
|
70
|
+
The function returns an array of all extracted expressions, which can be used for further parsing or validation.
|
|
67
71
|
|
|
68
72
|
```js
|
|
69
73
|
import { extract, test, parse } from '@swaggerexpert/arazzo-runtime-expression';
|
|
70
74
|
|
|
71
|
-
|
|
75
|
+
// Extract single expression
|
|
76
|
+
extract('{$request.header.accept}'); // => ['$request.header.accept']
|
|
72
77
|
|
|
73
|
-
|
|
74
|
-
|
|
78
|
+
// Extract multiple expressions from a template string
|
|
79
|
+
extract('client_id={$inputs.clientId}&grant_type={$inputs.grantType}');
|
|
80
|
+
// => ['$inputs.clientId', '$inputs.grantType']
|
|
81
|
+
|
|
82
|
+
// No expressions found
|
|
83
|
+
extract('no expressions here'); // => []
|
|
84
|
+
|
|
85
|
+
// Use extracted expressions
|
|
86
|
+
const expressions = extract('{$url}');
|
|
87
|
+
test(expressions[0]); // => true
|
|
88
|
+
parse(expressions[0]); // => { result, tree }
|
|
75
89
|
```
|
|
76
90
|
|
|
91
|
+
**Known limitation:** `$request.body#/...` and `$response.body#/...` expressions with JSON pointers cannot be reliably
|
|
92
|
+
extracted from `{expression}` syntax. This is because [RFC 6901](https://datatracker.ietf.org/doc/html/rfc6901)
|
|
93
|
+
(JSON Pointer) allows the `}` character in pointer paths, making it impossible to determine where the expression ends.
|
|
94
|
+
Use `parse()` directly on the raw expression for these cases.
|
|
95
|
+
|
|
77
96
|
#### Parsing
|
|
78
97
|
|
|
79
98
|
Parsing a Runtime Expression is as simple as importing the **parse** function and calling it.
|
|
@@ -88,97 +107,101 @@ const parseResult = parse('$request.header.accept');
|
|
|
88
107
|
|
|
89
108
|
```
|
|
90
109
|
{
|
|
91
|
-
result:
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
length: 22,
|
|
96
|
-
matched: 22,
|
|
97
|
-
maxMatched: 22,
|
|
98
|
-
maxTreeDepth: 13,
|
|
99
|
-
nodeHits: 152
|
|
100
|
-
},
|
|
101
|
-
ast: fnast {
|
|
102
|
-
callbacks: [
|
|
103
|
-
expression: [Function: expression],
|
|
104
|
-
'parameter-name': [Function: parameterName],
|
|
105
|
-
source: [Function: source],
|
|
106
|
-
'header-reference': [Function: headerReference],
|
|
107
|
-
'query-reference': [Function: queryReference],
|
|
108
|
-
'path-reference': [Function: pathReference],
|
|
109
|
-
'body-reference': [Function: bodyReference],
|
|
110
|
-
'json-pointer': [Function: jsonPointer],
|
|
111
|
-
'reference-token': [Function: referenceToken],
|
|
112
|
-
name: [Function: name],
|
|
113
|
-
token: [Function: token]
|
|
114
|
-
],
|
|
115
|
-
init: [Function (anonymous)],
|
|
116
|
-
ruleDefined: [Function (anonymous)],
|
|
117
|
-
udtDefined: [Function (anonymous)],
|
|
118
|
-
down: [Function (anonymous)],
|
|
119
|
-
up: [Function (anonymous)],
|
|
120
|
-
translate: [Function (anonymous)],
|
|
121
|
-
setLength: [Function (anonymous)],
|
|
122
|
-
getLength: [Function (anonymous)],
|
|
123
|
-
toXml: [Function (anonymous)]
|
|
124
|
-
}
|
|
110
|
+
result: <ParseResult['result']>,
|
|
111
|
+
tree: <ParseResult['tree']>,
|
|
112
|
+
stats: <ParseResult['stats']>,
|
|
113
|
+
trace: <ParseResult['trace']>,
|
|
125
114
|
}
|
|
126
115
|
```
|
|
127
116
|
|
|
128
|
-
|
|
117
|
+
[TypeScript typings](https://github.com/swaggerexpert/arazzo-runtime-expression/blob/main/types/index.d.ts) are available for all fields attached to parse result object returned by the `parse` function.
|
|
118
|
+
|
|
119
|
+
##### Translators
|
|
120
|
+
|
|
121
|
+
`@swaggerexpert/arazzo-runtime-expression` provides several translators to convert the parse result into different tree representations.
|
|
122
|
+
|
|
123
|
+
###### CST translator
|
|
124
|
+
|
|
125
|
+
[Concrete Syntax Tree](https://en.wikipedia.org/wiki/Parse_tree) (Parse tree) representation is available on parse result
|
|
126
|
+
when instance of `CSTTranslator` is provided via a `translator` option to the `parse` function.
|
|
127
|
+
CST is suitable to be consumed by other tools like IDEs, editors, etc...
|
|
128
|
+
|
|
129
|
+
```js
|
|
130
|
+
import { parse, CSTTranslator } from '@swaggerexpert/arazzo-runtime-expression';
|
|
131
|
+
|
|
132
|
+
const { tree: cst } = parse('$request.header.accept', { translator: new CSTTranslator() });
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
CST tree has a shape documented by [TypeScript typings (CSTNode)](https://github.com/swaggerexpert/arazzo-runtime-expression/blob/main/types/index.d.ts).
|
|
136
|
+
|
|
137
|
+
###### AST translator
|
|
138
|
+
|
|
139
|
+
**Default translator**. [Abstract Syntax Tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree) representation is available on parse result
|
|
140
|
+
by default or when instance of `ASTTranslator` is provided via a `translator` option to the `parse` function.
|
|
141
|
+
AST is suitable to be consumed by implementations that need to analyze the structure of the runtime expression.
|
|
129
142
|
|
|
130
143
|
```js
|
|
131
144
|
import { parse } from '@swaggerexpert/arazzo-runtime-expression';
|
|
132
145
|
|
|
133
|
-
const
|
|
134
|
-
|
|
146
|
+
const { tree: ast } = parse('$request.header.accept');
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
or
|
|
150
|
+
|
|
151
|
+
```js
|
|
152
|
+
import { parse, ASTTranslator } from '@swaggerexpert/arazzo-runtime-expression';
|
|
135
153
|
|
|
136
|
-
|
|
154
|
+
const { tree: ast } = parse('$request.header.accept', { translator: new ASTTranslator() });
|
|
137
155
|
```
|
|
138
156
|
|
|
139
|
-
|
|
157
|
+
AST tree has a shape documented by [TypeScript typings (ASTNode)](https://github.com/swaggerexpert/arazzo-runtime-expression/blob/main/types/index.d.ts).
|
|
158
|
+
|
|
159
|
+
###### XML translator
|
|
140
160
|
|
|
141
161
|
```js
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
[ 'header-reference', 'header.accept' ],
|
|
146
|
-
[ 'token', 'accept' ],
|
|
147
|
-
]
|
|
162
|
+
import { parse, XMLTranslator } from '@swaggerexpert/arazzo-runtime-expression';
|
|
163
|
+
|
|
164
|
+
const { tree: xml } = parse('$request.header.accept', { translator: new XMLTranslator() });
|
|
148
165
|
```
|
|
149
166
|
|
|
150
|
-
|
|
167
|
+
##### Statistics
|
|
168
|
+
|
|
169
|
+
`parse` function returns additional statistical information about the parsing process.
|
|
170
|
+
Collection of the statistics can be enabled by setting `stats` option to `true`.
|
|
151
171
|
|
|
152
172
|
```js
|
|
153
173
|
import { parse } from '@swaggerexpert/arazzo-runtime-expression';
|
|
154
174
|
|
|
155
|
-
const
|
|
156
|
-
|
|
175
|
+
const { stats } = parse('$request.header.accept', { stats: true });
|
|
176
|
+
|
|
177
|
+
stats.displayStats(); // returns operator statistics as string
|
|
157
178
|
```
|
|
158
179
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
<node name="token" index="16" length="6">
|
|
173
|
-
accept
|
|
174
|
-
</node><!-- name="token" -->
|
|
175
|
-
</node><!-- name="header-reference" -->
|
|
176
|
-
</node><!-- name="source" -->
|
|
177
|
-
</node><!-- name="expression" -->
|
|
178
|
-
</root>
|
|
180
|
+
##### Tracing
|
|
181
|
+
|
|
182
|
+
`parse` function returns additional tracing information about the parsing process.
|
|
183
|
+
Tracing can be enabled by setting `trace` option to `true`. Tracing is essential
|
|
184
|
+
for debugging failed parses or analyzing rule execution flow.
|
|
185
|
+
|
|
186
|
+
```js
|
|
187
|
+
import { parse } from '@swaggerexpert/arazzo-runtime-expression';
|
|
188
|
+
|
|
189
|
+
const { result, trace } = parse('$invalid', { trace: true });
|
|
190
|
+
|
|
191
|
+
result.success; // false
|
|
192
|
+
trace.displayTrace(); // returns trace information as string
|
|
179
193
|
```
|
|
180
194
|
|
|
181
|
-
|
|
195
|
+
Tracing also allows you to infer expected tokens at a failure point. This is useful for generating meaningful syntax error messages.
|
|
196
|
+
|
|
197
|
+
```js
|
|
198
|
+
import { parse } from '@swaggerexpert/arazzo-runtime-expression';
|
|
199
|
+
|
|
200
|
+
const { trace } = parse('$invalid', { trace: true });
|
|
201
|
+
|
|
202
|
+
const expectations = trace.inferExpectations();
|
|
203
|
+
console.log(expectations.toString()); // e.g., "expected '$url', '$method', '$statusCode', '$request.', ..."
|
|
204
|
+
```
|
|
182
205
|
|
|
183
206
|
#### Validation
|
|
184
207
|
|
|
@@ -191,6 +214,30 @@ test('$request.header.accept'); // => true
|
|
|
191
214
|
test('nonsensical string'); // => false
|
|
192
215
|
```
|
|
193
216
|
|
|
217
|
+
#### Errors
|
|
218
|
+
|
|
219
|
+
`@swaggerexpert/arazzo-runtime-expression` provides a structured error class hierarchy,
|
|
220
|
+
enabling precise error handling across runtime expression operations.
|
|
221
|
+
|
|
222
|
+
```js
|
|
223
|
+
import { ArazzoRuntimeExpressionError, ArazzoRuntimeExpressionParseError } from '@swaggerexpert/arazzo-runtime-expression';
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
**ArazzoRuntimeExpressionError** is the base class for all errors. **ArazzoRuntimeExpressionParseError** is thrown when parsing fails
|
|
227
|
+
and includes additional context about the expression that failed to parse.
|
|
228
|
+
|
|
229
|
+
```js
|
|
230
|
+
import { parse, ArazzoRuntimeExpressionParseError } from '@swaggerexpert/arazzo-runtime-expression';
|
|
231
|
+
|
|
232
|
+
try {
|
|
233
|
+
parse(123); // non-string input
|
|
234
|
+
} catch (error) {
|
|
235
|
+
if (error instanceof ArazzoRuntimeExpressionParseError) {
|
|
236
|
+
console.log(error.runtimeExpression); // the expression that failed
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
194
241
|
#### Grammar
|
|
195
242
|
|
|
196
243
|
New grammar instance can be created in following way:
|
|
@@ -219,8 +266,7 @@ The runtime expression is defined by the following [ABNF](https://tools.ietf.org
|
|
|
219
266
|
|
|
220
267
|
```abnf
|
|
221
268
|
; Arazzo runtime expression ABNF syntax
|
|
222
|
-
expression = ( "$url" / "$method" / "$statusCode" / "$request." source / "$response." source / "$inputs." name / "$outputs." name / "$steps." name / "$workflows." name / "$sourceDescriptions." name / "$components." name
|
|
223
|
-
parameter-name = name ; Reuses 'name' rule for parameter names
|
|
269
|
+
expression = ( "$url" / "$method" / "$statusCode" / "$request." source / "$response." source / "$inputs." name / "$outputs." name / "$steps." name / "$workflows." name / "$sourceDescriptions." name / "$components." name )
|
|
224
270
|
source = ( header-reference / query-reference / path-reference / body-reference )
|
|
225
271
|
header-reference = "header." token
|
|
226
272
|
query-reference = "query." name
|
|
@@ -228,6 +274,39 @@ path-reference = "path." name
|
|
|
228
274
|
body-reference = "body" ["#" json-pointer ]
|
|
229
275
|
name = *( CHAR )
|
|
230
276
|
|
|
277
|
+
; Grammar for parsing template strings with embedded expressions
|
|
278
|
+
expression-string = *( literal-char / embedded-expression )
|
|
279
|
+
embedded-expression = "{" expression "}"
|
|
280
|
+
literal-char = %x00-7A / %x7C / %x7E-10FFFF ; anything except { (%x7B) and } (%x7D)
|
|
281
|
+
|
|
282
|
+
; Secondary grammar for parsing $steps name part
|
|
283
|
+
; Format: {stepId}.{field}.{subField}[#/{jsonPointer}]
|
|
284
|
+
steps-name = steps-id "." steps-field "." steps-sub-field ["#" json-pointer]
|
|
285
|
+
steps-id = 1*(ALPHA / DIGIT / "_" / "-")
|
|
286
|
+
steps-field = "outputs"
|
|
287
|
+
steps-sub-field = 1*(ALPHA / DIGIT / "." / "-" / "_")
|
|
288
|
+
|
|
289
|
+
; Secondary grammar for parsing $workflows name part
|
|
290
|
+
; Format: {workflowId}.{field}.{subField}[#/{jsonPointer}]
|
|
291
|
+
workflows-name = workflows-id "." workflows-field "." workflows-sub-field ["#" json-pointer]
|
|
292
|
+
workflows-id = 1*(ALPHA / DIGIT / "_" / "-")
|
|
293
|
+
workflows-field = "inputs" / "outputs"
|
|
294
|
+
workflows-sub-field = 1*(ALPHA / DIGIT / "." / "-" / "_")
|
|
295
|
+
|
|
296
|
+
; Secondary grammar for parsing $sourceDescriptions name part
|
|
297
|
+
; Format: {sourceName}.{reference}
|
|
298
|
+
; reference can be operationId (unconstrained) or workflowId (constrained)
|
|
299
|
+
source-descriptions-name = source-descriptions-source-name "." source-descriptions-reference
|
|
300
|
+
source-descriptions-source-name = 1*(ALPHA / DIGIT / "_" / "-")
|
|
301
|
+
source-descriptions-reference = 1*CHAR
|
|
302
|
+
|
|
303
|
+
; Secondary grammar for parsing $components name part
|
|
304
|
+
; Format: {field}.{subField}
|
|
305
|
+
; Allowed fields: parameters, successActions, failureActions
|
|
306
|
+
components-name = components-field "." components-sub-field
|
|
307
|
+
components-field = "parameters" / "successActions" / "failureActions"
|
|
308
|
+
components-sub-field = 1*(ALPHA / DIGIT / "." / "-" / "_")
|
|
309
|
+
|
|
231
310
|
; https://datatracker.ietf.org/doc/html/rfc6901#section-3
|
|
232
311
|
json-pointer = *( "/" reference-token )
|
|
233
312
|
reference-token = *( unescaped / escaped )
|
|
@@ -256,7 +335,8 @@ CHAR = unescape /
|
|
|
256
335
|
%x74 / ; t tab U+0009
|
|
257
336
|
%x75 4HEXDIG ) ; uXXXX U+XXXX
|
|
258
337
|
escape = %x5C ; \
|
|
259
|
-
unescape = %x20-21 / %x23-5B / %x5D-10FFFF
|
|
338
|
+
unescape = %x20-21 / %x23-5B / %x5D-7A / %x7C / %x7E-10FFFF
|
|
339
|
+
; %x7B ('{') and %x7D ('}') are excluded from 'unescape'
|
|
260
340
|
|
|
261
341
|
; https://datatracker.ietf.org/doc/html/rfc5234#appendix-B.1
|
|
262
342
|
HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
|
package/SECURITY.md
CHANGED
|
@@ -6,7 +6,8 @@ If you believe you've found an exploitable security issue in @swaggerexpert/araz
|
|
|
6
6
|
|
|
7
7
|
| Version | Supported |
|
|
8
8
|
|---------|--------------------|
|
|
9
|
-
| ^1.0.0 | :
|
|
9
|
+
| ^1.0.0 | :x: |
|
|
10
|
+
| ^2.0.0 | :white_check_mark: |
|
|
10
11
|
|
|
11
12
|
## Reporting a Vulnerability
|
|
12
13
|
|
package/cjs/apg-lite.cjs
CHANGED
|
@@ -2,31 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
exports.__esModule = true;
|
|
4
4
|
exports.utilities = exports.identifiers = exports.Trace = exports.Stats = exports.Parser = exports.Ast = void 0;
|
|
5
|
-
/* *************************************************************************************
|
|
6
|
-
* copyright: Copyright (c) 2023 Lowell D. Thomas, all rights reserved
|
|
7
|
-
* license: BSD-2-Clause (https://opensource.org/licenses/BSD-2-Clause)
|
|
8
|
-
*
|
|
9
|
-
* Redistribution and use in source and binary forms, with or without
|
|
10
|
-
* modification, are permitted provided that the following conditions are met:
|
|
11
|
-
*
|
|
12
|
-
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
13
|
-
* list of conditions and the following disclaimer.
|
|
14
|
-
*
|
|
15
|
-
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
16
|
-
* this list of conditions and the following disclaimer in the documentation
|
|
17
|
-
* and/or other materials provided with the distribution.
|
|
18
|
-
*
|
|
19
|
-
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
20
|
-
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
21
|
-
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
22
|
-
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
23
|
-
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
24
|
-
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
25
|
-
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
26
|
-
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
27
|
-
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
28
|
-
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
29
|
-
*
|
|
5
|
+
/* *************************************************************************************
|
|
6
|
+
* copyright: Copyright (c) 2023 Lowell D. Thomas, all rights reserved
|
|
7
|
+
* license: BSD-2-Clause (https://opensource.org/licenses/BSD-2-Clause)
|
|
8
|
+
*
|
|
9
|
+
* Redistribution and use in source and binary forms, with or without
|
|
10
|
+
* modification, are permitted provided that the following conditions are met:
|
|
11
|
+
*
|
|
12
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
13
|
+
* list of conditions and the following disclaimer.
|
|
14
|
+
*
|
|
15
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
16
|
+
* this list of conditions and the following disclaimer in the documentation
|
|
17
|
+
* and/or other materials provided with the distribution.
|
|
18
|
+
*
|
|
19
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
20
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
21
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
22
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
23
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
24
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
25
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
26
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
27
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
28
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
29
|
+
*
|
|
30
30
|
* ********************************************************************************* */
|
|
31
31
|
|
|
32
32
|
const Parser = exports.Parser = function fnparser() {
|
|
@@ -665,7 +665,7 @@ const Ast = exports.Ast = function fnast() {
|
|
|
665
665
|
a.ruleDefined = index => !!nodeCallbacks[index];
|
|
666
666
|
/* AST node UDT callbacks - called by the parser's `UDT` operator */
|
|
667
667
|
a.udtDefined = index => !!nodeCallbacks[rules.length + index];
|
|
668
|
-
/* called by the parser's `RNM` & `UDT` operators
|
|
668
|
+
/* called by the parser's `RNM` & `UDT` operators
|
|
669
669
|
builds a record for the downward traversal of the node */
|
|
670
670
|
a.down = (callbackIndex, name) => {
|
|
671
671
|
const thisIndex = records.length;
|
|
@@ -963,8 +963,8 @@ const Stats = exports.Stats = function fnstats() {
|
|
|
963
963
|
out += displayRow('TOTAL', totals.match, totals.empty, totals.nomatch, totals.total);
|
|
964
964
|
return out;
|
|
965
965
|
};
|
|
966
|
-
/*
|
|
967
|
-
Display rule/udt
|
|
966
|
+
/*
|
|
967
|
+
Display rule/udt
|
|
968
968
|
*/
|
|
969
969
|
this.displayHits = type => {
|
|
970
970
|
let out = '';
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.default = void 0;
|
|
5
|
+
class ArazzoRuntimeExpressionError extends Error {
|
|
6
|
+
constructor(message, options = undefined) {
|
|
7
|
+
super(message, options);
|
|
8
|
+
this.name = this.constructor.name;
|
|
9
|
+
if (typeof message === 'string') {
|
|
10
|
+
this.message = message;
|
|
11
|
+
}
|
|
12
|
+
if (typeof Error.captureStackTrace === 'function') {
|
|
13
|
+
Error.captureStackTrace(this, this.constructor);
|
|
14
|
+
} else {
|
|
15
|
+
this.stack = new Error(message).stack;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* This needs to stay here until our minimum supported version of Node.js is >= 16.9.0.
|
|
20
|
+
* Node.js is >= 16.9.0 supports error causes natively.
|
|
21
|
+
*/
|
|
22
|
+
if (options != null && typeof options === 'object' && Object.hasOwn(options, 'cause') && !('cause' in this)) {
|
|
23
|
+
const {
|
|
24
|
+
cause
|
|
25
|
+
} = options;
|
|
26
|
+
this.cause = cause;
|
|
27
|
+
if (cause instanceof Error && 'stack' in cause) {
|
|
28
|
+
this.stack = `${this.stack}\nCAUSE: ${cause.stack}`;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Allows to assign arbitrary properties to the error object.
|
|
34
|
+
*/
|
|
35
|
+
if (options != null && typeof options === 'object') {
|
|
36
|
+
const {
|
|
37
|
+
cause,
|
|
38
|
+
...causelessOptions
|
|
39
|
+
} = options;
|
|
40
|
+
Object.assign(this, causelessOptions);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
var _default = exports.default = ArazzoRuntimeExpressionError;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.default = void 0;
|
|
5
|
+
var _ArazzoRuntimeExpressionError = _interopRequireDefault(require("./ArazzoRuntimeExpressionError.cjs"));
|
|
6
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
|
+
class ArazzoRuntimeExpressionParseError extends _ArazzoRuntimeExpressionError.default {}
|
|
8
|
+
var _default = exports.default = ArazzoRuntimeExpressionParseError;
|
package/cjs/extract.cjs
CHANGED
|
@@ -2,20 +2,46 @@
|
|
|
2
2
|
|
|
3
3
|
exports.__esModule = true;
|
|
4
4
|
exports.default = void 0;
|
|
5
|
+
var _apgLite = require("apg-lite.cjs");
|
|
6
|
+
var _grammar = _interopRequireDefault(require("./grammar.cjs"));
|
|
7
|
+
var _CSTTranslator = _interopRequireDefault(require("./parse/translators/CSTTranslator.cjs"));
|
|
8
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
const grammar = new _grammar.default();
|
|
10
|
+
|
|
5
11
|
/**
|
|
6
|
-
*
|
|
12
|
+
* Extract runtime expressions from a string containing embedded {expression} patterns.
|
|
7
13
|
*
|
|
8
14
|
* @example
|
|
9
15
|
*
|
|
10
|
-
* extract('{$url}'); // => '$url'
|
|
16
|
+
* extract('{$url}'); // => ['$url']
|
|
17
|
+
* extract('id={$inputs.id}&name={$inputs.name}'); // => ['$inputs.id', '$inputs.name']
|
|
11
18
|
*/
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (typeof arazzoRuntimeExpression !== 'string') {
|
|
16
|
-
return null;
|
|
19
|
+
const extract = str => {
|
|
20
|
+
if (typeof str !== 'string') {
|
|
21
|
+
return [];
|
|
17
22
|
}
|
|
18
|
-
const
|
|
19
|
-
|
|
23
|
+
const parser = new _apgLite.Parser();
|
|
24
|
+
parser.ast = new _CSTTranslator.default();
|
|
25
|
+
const result = parser.parse(grammar, 'expression-string', str);
|
|
26
|
+
if (!result.success) {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
const cst = parser.ast.getTree();
|
|
30
|
+
const expressions = [];
|
|
31
|
+
|
|
32
|
+
// Traverse CST to find all embedded-expression nodes
|
|
33
|
+
const traverse = node => {
|
|
34
|
+
if (node.type === 'embedded-expression') {
|
|
35
|
+
const exprNode = node.children.find(c => c.type === 'expression');
|
|
36
|
+
if (exprNode) {
|
|
37
|
+
expressions.push(exprNode.text);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
for (const child of node.children || []) {
|
|
41
|
+
traverse(child);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
traverse(cst);
|
|
45
|
+
return expressions;
|
|
20
46
|
};
|
|
21
47
|
var _default = exports.default = extract;
|