Template parser library used for dynamic values interpolation in [Bright DAST app](https://app.brightsec.com).
npm install @neuralegion/nextemplateTemplate parser library used for dynamic values interpolation in Bright DAST app.
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 must be prefixed with a context name. Currently, the only supported contexts are auth_object and entrypoint. 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 the entrypoint 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 or response)
- location in the source (url, headers, or body).
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.
The pipes are supported, e.g.: {{ auth_object.otps.custom_otp_token_name1 | match: /^.{1}(.)/ : 1 }}
#### 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 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).
#### 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 or none (optional, default none)
_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 or none (optional, default none)
_Example_: {{ auth_object.stages.custom_stage_name1.response.body | decode: 'base64' }}
npm i --save @neuralegion/nextemplate
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
``ts
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 {
}
`
#### 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
`json`
[
"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",
"pipes": [],
"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
``
ECMAScript 2015, Typescript modules
`
import { parse } from '@neuralegion/nextemplate';
console.log(parse('some_template'));
`
NodeJS (CommonJS module)
`
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
Browser (globals from umd bundle)
``
Browser (ES modules)
``
Issues and pull requests are highly welcome. 👍
Please, don't forget to lint (npm run lint) and test (npm t`) the code.
Copyright © 2023 Bright Security.
This project is licensed under the MIT License - see the LICENSE file for details.