# node-falafel **Repository Path**: mirrors_Financial-Times/node-falafel ## Basic Information - **Project Name**: node-falafel - **Description**: transform the ast on a recursive walk - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-09-24 - **Last Updated**: 2026-07-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # falafel Transform the [ast](http://en.wikipedia.org/wiki/Abstract_syntax_tree) on a recursive walk. [![browser support](http://ci.testling.com/substack/node-falafel.png)](http://ci.testling.com/substack/node-falafel) [![build status](https://secure.travis-ci.org/substack/node-falafel.png)](http://travis-ci.org/substack/node-falafel) This module is like [burrito](https://github.com/substack/node-burrito), except that it uses [esprima](http://esprima.org) instead of [uglify](https://github.com/mishoo/UglifyJS) for friendlier-looking ast nodes. ![falafel döner](http://substack.net/images/falafel.png) # example ## array.js Put a function wrapper around all array literals. ``` js var falafel = require('falafel'); var src = '(' + function () { var xs = [ 1, 2, [ 3, 4 ] ]; var ys = [ 5, 6 ]; console.dir([ xs, ys ]); } + ')()'; var output = falafel(src, function (node) { if (node.type === 'ArrayExpression') { node.update('fn(' + node.source() + ')'); } }); console.log(output); ``` output: ``` (function () { var xs = fn([ 1, 2, fn([ 3, 4 ]) ]); var ys = fn([ 5, 6 ]); console.dir(fn([ xs, ys ])); })() ``` ## custom keyword Creating custom keywords is super simple! This example creates a new `beep` keyword that uppercases its arguments: ``` js var falafel = require('falafel'); var src = 'console.log(beep "boop", "BOOP");'; function isKeyword (id) { if (id === 'beep') return true; } var output = falafel(src, { isKeyword: isKeyword }, function (node) { if (node.type === 'UnaryExpression' && node.keyword === 'beep') { node.update( 'String(' + node.argument.source() + ').toUpperCase()' ); } }); console.log(output); ``` Now the source string `console.log(beep "boop", "BOOP");` is converted to: ``` $ node example/keyword.js console.log(String("boop").toUpperCase(), "BOOP"); ``` which we can execute: ``` $ node example/keyword.js | node BOOP BOOP ``` Neat! # methods ``` js var falafel = require('falafel') ``` ## falafel(src, opts={}, fn) Transform the string source `src` with the function `fn`, returning a string-like transformed output object. For every node in the ast, `fn(node)` fires. The recursive walk is a pre-traversal, so children get called before their parents. Performing a pre-traversal makes it easier to write nested transforms since transforming parents often requires transforming all its children first. The return value is string-like (it defines `.toString()` and `.inspect()`) so that you can call `node.update()` asynchronously after the function has returned and still capture the output. Instead of passing a `src` you can also use `opts.source`. All of the `opts` will be passed directly to esprima except for `'range'` which is always turned on because falafel needs it. Some of the options you might want from esprima includes: `'loc'`, `'raw'`, `'comment'`, `'tokens'`, and `'tolerant'`. falafel uses a custom patch of esprima with support for an `opts.isKeyword()` function. When `opts.isKeyword(id)` returns `true`, the string `id` will be treated as a keyword. You can use this behavior to create custom unary expression keywords. An `opts.isKeyword(id)` value that is a string will be mapped to existing types. The only currently supported string value is `"block"`. # nodes Aside from the regular [esprima](http://esprima.org) data, you can also call some inserted methods on nodes. Aside from updating the current node, you can also reach into sub-nodes to call update functions on children from parent nodes. ## node.source() Return the source for the given node, including any modifications made to children nodes. ## node.update(s) Transform the source for the present node to the string `s`. Note that in `'ForStatement'` node types, there is an existing subnode called `update`. For those nodes all the properties are copied over onto the `node.update()` function. ## node.parent Reference to the parent element or `null` at the root element. # install With [npm](http://npmjs.org) do: ``` npm install falafel ``` # license MIT