Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

edge-parser

Package Overview
Dependencies
Maintainers
1
Versions
92
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

edge-parser

Parser for edge template engine

  • 5.0.5
  • Source
  • npm
  • Socket score

Version published
Maintainers
1
Created
Source

Edge Parser

Parser to convert edge template to invokable functions

circleci-image npm-image license-image

Table of contents

This repo is the parser to convert edge templates to a self invoked Javascript function. Later you can invoke this function by providing a context.

Usage

Install the package from npm registry as follows:

npm i edge-parser

# yarn
yarn add edge-parser

and then use it as follows

import { Parser } from 'edge-parser'

const tagsIfAny = {}
const parser = new Parser(tagsIfAny, { filename: 'foo.edge' })

parser.parse(`Hello {{ username }}`)

Output

let out = "";
let $lineNumber = 1;
let $filename = "eval.edge";
try {
out += "Hello ";
out += `${ctx.escape(state.username)}`;
} catch (error) {
ctx.reThrow(error, $filename, $lineNumber);
}
return out;

Notice of use of ctx in the function body. Parser doesn't provide the implementation of ctx, the runtime of template engine should provide it.

Parser API

Along with parsing the main template, the parser also exposes the API, that tags can use to selectively parse the content of a tag.

generateAST(jsExpression, lexerLoc, filename)

Parses a string as a Javascript expression. The output is a valid Estree expression

The following example returns a BinaryExpression

const loc = {
  start: { line: 1, col: 1 },
  end: { line: 1, col: 1 },
}
const filename = 'eval.edge'

parser.utils.generateAST('2 + 2', loc, filename)
transformAst(acornAst, filename)

Transform the acorn AST and make it compatible with Edge runtime. This method mutates the inner nodes of the original AST.

const loc = {
  start: { line: 1, col: 1 },
  end: { line: 1, col: 1 },
}
const filename = 'eval.edge'

parser.utils.transformAst(
  parser.utils.generateAST('2 + 2', loc, filename),
  filename,
)
tokenize (template)

Returns an array of lexer tokens for the given template. The method is a shortcut to self import the lexer module and then generating tokens.

const tokens = parser.tokenize('Hello {{ username }}')

Output

[
  {
    "type": "raw",
    "line": 1,
    "value": "Hello "
  },
  {
    "type": "mustache",
    "filename": "eval.edge",
    "loc": {
      "start": {
        "line": 1,
        "col": 8
      },
      "end": {
        "line": 1,
        "col": 20
      }
    },
    "properties": {
      "jsArg": " username "
    }
  }
]
stringify(expression)

Convert edge or acorn expression back to a string. This is helpful, when you mutate some nodes inside the expression and now want a valid Javascript string out of it.

const expression = parser.utils.generateAST('2 + 2', {
  start: { line: 1, col: 1 },
  end: { line: 1, col: 1 },
}, 'eval.edge')

expression.left.value = 3
parser.utils.stringify(expression) // returns 3 + 2
parse(template)

Parse a template to an IIFE. This is what you will use most of the time.

parser.parse('Hello {{ username }}')

Output

let out = "";
let $lineNumber = 1;
let $filename = "eval.edge";
try {
out += "Hello ";
out += `${ctx.escape(state.username)}`;
} catch (error) {
ctx.reThrow(error, $filename, $lineNumber);
}
return out;
processToken(token, buffer)

You will often find yourself using this method as a tag author, when you want to recursively process all children of your tag

const byPass = {
  block: true,
  seekable: false,
  name: 'bypass',

  compile (parser, buffer, token) {
    token.children.forEach((child) => parser.processToken(child, buffer))
  }
}

and then use it as

@bypass
  Hello {{ username }}
@endbypass

Supported Expressions

The following expressions are supported by the parser. Can you also access the list of supported expressions as

import { expressions } from 'edge-parser'
Identifier

The identifier are prefixed with state. In following statement username is the identifier

Hello {{ username }}
Literal

A string literal

Hello {{ 'Guest' }}
ArrayExpression

The [1, 2, 3, 4] is an array expression.

Evens are {{
  [1, 2, 3, 4].filter((num) => num % 2 === 0)
}}
ObjectExpression

The { username: 'virk' } is an Object expression

{{ toJSON({ username: 'virk' })  }}
UnaryExpression

Following are examples of UnaryExpression.

{{ typeof(username) }}

{{ !!username }}
BinaryExpression

Here {{ 2 + 2 }} is the binary expression

{{ 2 + 2 }} = 4
LogicalExpression

Following is the example of LogicalExpression.

{{ username || admin.username }}
MemberExpression
{{ username.toUpperCase() }}
ConditionalExpression
{{ username ? username : 'Guest' }}
CallExpression
{{ upper(username) }}
SequenceExpression

Sequence is not supported in mustache blocks and instead used inside tags. For example:

Everything inside () is a sequence expression.

@component('button', text = 'Submit', type = 'Primary')
TemplateLiteral
{{ Hello `${username}` }}
ArrowFunctionExpression
{{
  users.map((user) => {
    return user.username
  })
}}
AwaitExpression
{{ await foo() }}
FunctionDeclaration
{{ function foo () {} }}

Template expectations

You must define a context object with escape and reThrow methods when executing the parser compiled function

const ctx = {
  escape (value) {
    if (typeof (value) === 'string') {
      return escapedValue
    }
    
    return value
  },

  reThrow (error, fileName, lineNumber) {
  }
}

API Docs

Following are the auto generated files via Type doc

Keywords

FAQs

Package last updated on 14 Apr 2020

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc