@neuralegion/nextemplate
v3.0.1
Published
Template parser library used for dynamic values interpolation in [Bright DAST app](https://app.brightsec.com).
Downloads
96
Readme
nextemplate
Template parser library used for dynamic values interpolation in Bright DAST app.
Template syntax
The template syntax in nextemplate
utilizes double curly braces {{
and }}
as delimiters for interpolation expressions.
Two types of interpolation expressions are supported within these curly braces: variable expressions and yield expressions (prefixed with $
).
Variable expressions
⚠️ Variable expressions must be prefixed with a context name. Currently, the only supported contexts are
auth_object
andentrypoint
. Additional supported contexts may be added in the future.
⚠️ Each context currently has a limited set of supported references. Under the
auth_object
context, you can currently use stage references and OTP token references. Under theentrypoint
context, currently only parameter references are supported.
Stage references
Example: {{ auth_object.stages.custom_stage_name1.response.body }}
A stage reference consists of the following components:
- context (
auth_object
) - special word (
stages
) - stage name:
- any word (\w), number (\d) or underscore characters
- or special
any
literal
- source (
request
orresponse
) - location in the source (
url
,headers
, orbody
).
For data transformation, a pipe operator (|
) is available, supporting parameters and chaining.
Example: {{ auth_object.stages.custom_stage_name1.response.headers | get: '/Set-Cookie' | match: /sid=(.+)/ : 1 }}
OTP token references
Example: {{ auth_object.otps.custom_otp_token_name1 }}
OTP token references do not support nested references or pipes.
Entrypoint parameters references
Example: {{ entrypoint.params.some_param_name }}
A parameter name should start with a letter and can be followed by letters, digits, and underscores.
Entrypoint parameters references do not support nested references or pipes.
Yield expressions
⚠️ Yield expressions other than $faker could be supported in the future, but currently parser will produce an error.
$faker references
Example: {{ $faker.datatype.uuid }}
Inspired by @faker-js/faker.
The first part is predefined $faker
literal, the second part - faker dataset name (datatype
is single supported atm),
the third - function name from given dataset (ony uuid
and number
are supported).
Supported pipes
get
Returns the value associated with the XPath, or undefined if there is none.
Format: {{ stage_reference | get : xpath }}
Parameters:
xpath
- xpath string
Example: {{ auth_object.stages.custom_stage_name1.response.headers | get: '/Set-Cookie' }}
match
Retrieves the result of matching a string against a regular expression.
Format: {{ stage_reference | match : regexp : group }}
Parameters:
regexp
- regular expression,group
- number of the capture group (optional, default 1)
Example: {{ auth_object.stages.custom_stage_name1.response.body | match: /sid=(.+)/ : 1 }}
encode
Encodes the value to some format.
Format: {{ stage_reference | encode : format }}
Parameters:
format
-base64
,url
,html
ornone
(optional, defaultnone
)
Example: {{ auth_object.stages.custom_stage_name1.response.body | encode: 'base64' }}
decode
Decodes the value from some format.
Format: {{ stage_reference | decode : format }}
Parameters:
format
-base64
,url
,html
ornone
(optional, defaultnone
)
Example: {{ auth_object.stages.custom_stage_name1.response.body | decode: 'base64' }}
Install 🚀
npm i --save @neuralegion/nextemplate
API
Main parser function:
parse(template: string): ParseResult
Auxiliary faker
-like generator that consumes generation template (like faker.datatype.uuid
) as string or source
from ParsedFakerExpression
from parser output:
fakerFn(fakerTemplate: string | { source: string } & any): string
where
type ParseResult = (string | ParsedOtpTokenExpression | ParsedStageVariableExpression | ParsedFakerExpression)[];
interface ParsedExpression {
type: 'variable' | 'yield';
source: string;
raw: string;
}
interface ParsedVariableExpression extends ParsedExpression {
context: 'auth_object' | 'entrypoint';
type: 'variable';
}
interface ParsedOtpTokenExpression extends ParsedVariableExpression {
context: 'auth_object';
}
interface ParsedStageVariableExpression extends ParsedVariableExpression {
context: 'auth_object';
pipes: ParsedPipe[];
}
interface ParsedEntrypointParamsVariableExpression extends ParsedVariableExpression {
context: 'entrypoint';
source: 'params';
name: string;
}
interface ParsedPipe {
name: 'get' | 'match' | 'encode' | 'decode;
args: (string | number)[];
}
interface ParsedYieldExpression extends ParsedExpression {
type: 'yield';
value: string;
}
interface ParsedFakerExpression extends ParsedYieldExpression {
}
Sample output
Input template string
prefix {{ auth_object.stages.custom_stage_name1.response.headers | get : '/Set-Cookie' | match : /sid=(.+)/ | encode : 'base64' }} {{ $faker.datatype.uuid }} {{ auth_object.otps.custom_otp_token_name1 }} {{ entrypoint.params.some_param_name }} suffix
Parser output
[
"prefix ",
{
"context": "auth_object",
"type": "variable",
"source": "stages.custom_stage_name1.response.headers",
"pipes": [
{
"name": "get",
"args": ["/Set-Cookie"]
},
{
"name": "match",
"args": ["/sid=(.+)/", 1]
},
{
"name": "encode",
"args": ["base64"]
}
],
"raw": "{{ auth_object.stages.custom_stage_name1.response.headers | get : '/Set-Cookie' | match : /sid=(.+)/ | encode : 'base64' }}"
},
" ",
{
"type": "yield",
"source": "faker.datatype.uuid",
"value": "c6c27519-acb4-4875-91d9-298b921b5104",
"raw": "{{ $faker.datatype.uuid }}"
},
" ",
{
"context": "auth_object",
"type": "variable",
"source": "otps.custom_otp_token_name1",
"raw": "{{ auth_object.otps.custom_otp_token_name1 }}"
},
" ",
{
"context": "entrypoint",
"type": "variable",
"source": "params",
"name": "some_param_name",
"raw": "{{ entrypoint.params.some_param_name }}"
},
" suffix"
]
fakerFn usage examples
> fakerFn('faker.datatype.uuid')
48b0504d-b146-40f7-8fc2-fe19b7b9dc7b
> fakerFn({ source: 'faker.datatype.uuid' })`
b81b54de-735f-401d-aa77-ebd69d4293c2
Usage
import { parse } from '@neuralegion/nextemplate';
console.log(parse('some_template'));
const parser = require('@neuralegion/nextemplate');
console.log(parser.parse('some_template'));
usage.mjs
file:
import parser from '@neuralegion/nextemplate';
console.log(parser.parse('some_template'));
Running: node --experimental-modules ./usage.mjs
<script src="./node_modules/@neuralegion/nextemplate/dist/bundle.umd.js"></script>
<script>
alert(nextemplate.parse('some_template'));
</script>
<script type="module">
import { parse } from './node_modules/@neuralegion/nextemplate/dist/bundle.es.js';
alert(parse('some_template'));
</script>
Development 🛠
Issues and pull requests are highly welcome. 👍
Please, don't forget to lint (npm run lint
) and test (npm t
) the code.
License
Copyright © 2023 Bright Security.
This project is licensed under the MIT License - see the LICENSE file for details.