|
| 1 | +<section align="center"> |
| 2 | + <img src="https://cdn.jsdelivr.net/emojione/assets/svg/1f54e.svg" width="256" height="256" alt="Parse a function"> |
| 3 | +</section> |
| 4 | + |
| 5 | +# parse-function [![npm version][npmv-img]][npmv-url] [![github release][github-release-img]][github-release-url] [![mit License][license-img]][license-url] [![NPM Downloads Weekly][downloads-weekly-img]][downloads-weekly-url] [![NPM Downloads Total][downloads-total-img]][downloads-total-url] |
| 6 | + |
| 7 | +> Parse a function into an object using espree, acorn or babylon parsers. Extensible through Smart Plugins |
| 8 | +
|
| 9 | +_You might also be interested in [function-arguments][] library if you need more lightweight solution and need for just getting the names of the function arguments._ |
| 10 | + |
| 11 | +## Quality Assurance :100: |
| 12 | + |
| 13 | +[![Code Climate][codeclimate-img]][codeclimate-url] |
| 14 | +[![Code Style Standard][standard-img]][standard-url] |
| 15 | +[![Linux Build][travis-img]][travis-url] |
| 16 | +[![Code Coverage][codecov-img]][codecov-url] |
| 17 | +[![Dependencies Status][dependencies-img]][dependencies-url] |
| 18 | +[![Renovate App Status][renovate-img]][renovate-url] |
| 19 | + |
| 20 | +If you have any _how-to_ kind of questions, please read [Code of Conduct](./CODE_OF_CONDUCT.md) and **join the chat** room or [open an issue][open-issue-url]. |
| 21 | +You may also read the [Contributing Guide](./CONTRIBUTING.md). There, beside _"How to contribute?"_, we describe everything **_stated_** by the badges. |
| 22 | + |
| 23 | +[![tunnckoCore support][gitterchat-img]][gitterchat-url] |
| 24 | +[![Code Format Prettier][prettier-img]][prettier-url] |
| 25 | +[![node security status][nodesecurity-img]][nodesecurity-url] |
| 26 | +[![conventional Commits][ccommits-img]][ccommits-url] |
| 27 | +[![semantic release][semantic-release-img]][semantic-release-url] |
| 28 | +[![Node Version Required][nodeversion-img]][nodeversion-url] |
| 29 | + |
| 30 | +## Table of Contents |
| 31 | +- [Install](#install) |
| 32 | +- [API](#api) |
| 33 | + * [parseFunction](#parsefunction) |
| 34 | + * [.parse](#parse) |
| 35 | + * [.use](#use) |
| 36 | + * [.define](#define) |
| 37 | +- [Related](#related) |
| 38 | +- [Contributing](#contributing) |
| 39 | +- [Author](#author) |
| 40 | +- [License](#license) |
| 41 | + |
| 42 | +_(TOC generated by [verb](https://github.com/verbose/verb) using [markdown-toc](https://github.com/jonschlinkert/markdown-toc))_ |
| 43 | + |
| 44 | +## Install |
| 45 | + |
| 46 | +This project requires [Node.js][nodeversion-url] v6 and above. Use [npm](https://www.npmjs.com) to install it. |
| 47 | + |
| 48 | +``` |
| 49 | +$ npm install parse-function |
| 50 | +``` |
| 51 | + |
| 52 | +## API |
| 53 | +Review carefully the provided examples and the working [tests](./test.js). |
| 54 | + |
| 55 | +### [parseFunction](index.js#L59) |
| 56 | + |
| 57 | +> Initializes with optional `opts` object which is passed directly |
| 58 | +to the desired parser and returns an object |
| 59 | +with `.use` and `.parse` methods. The default parse which |
| 60 | +is used is [babylon][]'s `.parseExpression` method from `v7`. |
| 61 | + |
| 62 | +**Params** |
| 63 | + |
| 64 | +* `opts` **{Object}**: optional, merged with options passed to `.parse` method |
| 65 | +* `returns` **{Object}** |
| 66 | + |
| 67 | +**Example** |
| 68 | + |
| 69 | +```jsx |
| 70 | +const parseFunction = require('parse-function') |
| 71 | + |
| 72 | +const app = parseFunction({ |
| 73 | + ecmaVersion: 2017 |
| 74 | +}) |
| 75 | + |
| 76 | +const fixtureFn = (a, b, c) => { |
| 77 | + a = b + c |
| 78 | + return a + 2 |
| 79 | +} |
| 80 | + |
| 81 | +const result = app.parse(fixtureFn) |
| 82 | +console.log(result) |
| 83 | + |
| 84 | +// see more |
| 85 | +console.log(result.name) // => null |
| 86 | +console.log(result.isNamed) // => false |
| 87 | +console.log(result.isArrow) // => true |
| 88 | +console.log(result.isAnonymous) // => true |
| 89 | + |
| 90 | +// array of names of the arguments |
| 91 | +console.log(result.args) // => ['a', 'b', 'c'] |
| 92 | + |
| 93 | +// comma-separated names of the arguments |
| 94 | +console.log(result.params) // => 'a, b, c' |
| 95 | +``` |
| 96 | + |
| 97 | +### [.parse](index.js#L98) |
| 98 | + |
| 99 | +> Parse a given `code` and returns a `result` object |
| 100 | +with useful properties - such as `name`, `body` and `args`. |
| 101 | +By default it uses Babylon parser, but you can switch it by |
| 102 | +passing `options.parse` - for example `options.parse: acorn.parse`. |
| 103 | +In the below example will show how to use `acorn` parser, instead |
| 104 | +of the default one. |
| 105 | + |
| 106 | +**Params** |
| 107 | + |
| 108 | +* `code` **{Function|String}**: any kind of function or string to be parsed |
| 109 | +* `options` **{Object}**: directly passed to the parser - babylon, acorn, espree |
| 110 | +* `options.parse` **{Function}**: by default `babylon.parseExpression`, all `options` are passed as second argument to that provided function |
| 111 | +* `returns` **{Object}** |
| 112 | + |
| 113 | +**Example** |
| 114 | + |
| 115 | +```jsx |
| 116 | +const acorn = require('acorn') |
| 117 | +const parseFn = require('parse-function') |
| 118 | +const app = parseFn() |
| 119 | + |
| 120 | +const fn = function foo (bar, baz) { return bar * baz } |
| 121 | +const result = app.parse(fn, { |
| 122 | + parse: acorn.parse, |
| 123 | + ecmaVersion: 2017 |
| 124 | +}) |
| 125 | + |
| 126 | +console.log(result.name) // => 'foo' |
| 127 | +console.log(result.args) // => ['bar', 'baz'] |
| 128 | +console.log(result.body) // => ' return bar * baz ' |
| 129 | +console.log(result.isNamed) // => true |
| 130 | +console.log(result.isArrow) // => false |
| 131 | +console.log(result.isAnonymous) // => false |
| 132 | +console.log(result.isGenerator) // => false |
| 133 | +``` |
| 134 | + |
| 135 | +### [.use](index.js#L164) |
| 136 | +> Add a plugin `fn` function for extending the API or working on the AST nodes. The `fn` is immediately invoked and passed with `app` argument which is instance of `parseFunction()` call. That `fn` may return another function that accepts `(node, result)` signature, where `node` is an AST node and `result` is an object which will be returned [result](#result) from the `.parse` method. This retuned function is called on each node only when `.parse` method is called. |
| 137 | +
|
| 138 | +_See [Plugins Architecture](#plugins-architecture) section._ |
| 139 | + |
| 140 | +**Params** |
| 141 | + |
| 142 | +* `fn` **{Function}**: plugin to be called |
| 143 | +* `returns` **{Object}** |
| 144 | + |
| 145 | +**Example** |
| 146 | + |
| 147 | +```jsx |
| 148 | +// plugin extending the `app` |
| 149 | +app.use((app) => { |
| 150 | + app.define(app, 'hello', (place) => `Hello ${place}!`) |
| 151 | +}) |
| 152 | + |
| 153 | +const hi = app.hello('World') |
| 154 | +console.log(hi) // => 'Hello World!' |
| 155 | + |
| 156 | +// or plugin that works on AST nodes |
| 157 | +app.use((app) => (node, result) => { |
| 158 | + if (node.type === 'ArrowFunctionExpression') { |
| 159 | + result.thatIsArrow = true |
| 160 | + } |
| 161 | + return result |
| 162 | +}) |
| 163 | + |
| 164 | +const result = app.parse((a, b) => (a + b + 123)) |
| 165 | +console.log(result.name) // => null |
| 166 | +console.log(result.isArrow) // => true |
| 167 | +console.log(result.thatIsArrow) // => true |
| 168 | + |
| 169 | +const result = app.parse(function foo () { return 123 }) |
| 170 | +console.log(result.name) // => 'foo' |
| 171 | +console.log(result.isArrow) // => false |
| 172 | +console.log(result.thatIsArrow) // => undefined |
| 173 | +``` |
| 174 | + |
| 175 | +### [.define](index.js#L223) |
| 176 | + |
| 177 | +> Define a non-enumerable property on an object. Just |
| 178 | +a convenience mirror of the [define-property][] library, |
| 179 | +so check out its docs. Useful to be used in plugins. |
| 180 | + |
| 181 | +**Params** |
| 182 | + |
| 183 | +* `obj` **{Object}**: the object on which to define the property |
| 184 | +* `prop` **{String}**: the name of the property to be defined or modified |
| 185 | +* `val` **{Any}**: the descriptor for the property being defined or modified |
| 186 | +* `returns` **{Object}** |
| 187 | + |
| 188 | +**Example** |
| 189 | + |
| 190 | +```jsx |
| 191 | +const parseFunction = require('parse-function') |
| 192 | +const app = parseFunction() |
| 193 | + |
| 194 | +// use it like `define-property` lib |
| 195 | +const obj = {} |
| 196 | +app.define(obj, 'hi', 'world') |
| 197 | +console.log(obj) // => { hi: 'world' } |
| 198 | + |
| 199 | +// or define a custom plugin that adds `.foo` property |
| 200 | +// to the end result, returned from `app.parse` |
| 201 | +app.use((app) => { |
| 202 | + return (node, result) => { |
| 203 | + // this function is called |
| 204 | + // only when `.parse` is called |
| 205 | + |
| 206 | + app.define(result, 'foo', 123) |
| 207 | + |
| 208 | + return result |
| 209 | + } |
| 210 | +}) |
| 211 | + |
| 212 | +// fixture function to be parsed |
| 213 | +const asyncFn = async (qux) => { |
| 214 | + const bar = await Promise.resolve(qux) |
| 215 | + return bar |
| 216 | +} |
| 217 | + |
| 218 | +const result = app.parse(asyncFn) |
| 219 | + |
| 220 | +console.log(result.name) // => null |
| 221 | +console.log(result.foo) // => 123 |
| 222 | +console.log(result.args) // => ['qux'] |
| 223 | + |
| 224 | +console.log(result.isAsync) // => true |
| 225 | +console.log(result.isArrow) // => true |
| 226 | +console.log(result.isNamed) // => false |
| 227 | +console.log(result.isAnonymous) // => true |
| 228 | +``` |
| 229 | + |
| 230 | +## Related |
| 231 | +- [acorn](https://www.npmjs.com/package/acorn): ECMAScript parser | [homepage](https://github.com/ternjs/acorn "ECMAScript parser") |
| 232 | +- [babylon](https://www.npmjs.com/package/babylon): A JavaScript parser | [homepage](https://babeljs.io/ "A JavaScript parser") |
| 233 | +- [charlike-cli](https://www.npmjs.com/package/charlike-cli): Command line interface for the [charlike][] project scaffolder. | [homepage](https://github.com/tunnckoCore/charlike-cli#readme "Command line interface for the [charlike][] project scaffolder.") |
| 234 | +- [espree](https://www.npmjs.com/package/espree): An Esprima-compatible JavaScript parser built on Acorn | [homepage](https://github.com/eslint/espree "An Esprima-compatible JavaScript parser built on Acorn") |
| 235 | +- [hela](https://www.npmjs.com/package/hela): Task runner based on [execa][]. Includes few predefined tasks for linting, testing… [more](https://github.com/tunnckoCore/hela) | [homepage](https://github.com/tunnckoCore/hela "Task runner based on [execa][]. Includes few predefined tasks for linting, testing & releasing") |
| 236 | +- [parse-semver](https://www.npmjs.com/package/parse-semver): Parse, normalize and validate given semver shorthand (e.g. gulp@v3.8.10) to object. | [homepage](https://github.com/tunnckocore/parse-semver#readme "Parse, normalize and validate given semver shorthand (e.g. gulp@v3.8.10) to object.") |
| 237 | + |
| 238 | +## Contributing |
| 239 | +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue][open-issue-url]. |
| 240 | +Please read the [Contributing Guide](./CONTRIBUTING.md) and [Code of Conduct](./CODE_OF_CONDUCT.md) documents for advices. |
| 241 | + |
| 242 | +## Author |
| 243 | +- [github/tunnckoCore](https://github.com/tunnckoCore) |
| 244 | +- [twitter/tunnckoCore](https://twitter.com/tunnckoCore) |
| 245 | +- [codementor/tunnckoCore](https://codementor.io/tunnckoCore) |
| 246 | + |
| 247 | +## License |
| 248 | +Copyright © 2016-2017, [Charlike Mike Reagent](https://i.am.charlike.online). Released under the [MIT License](LICENSE). |
| 249 | + |
| 250 | +*** |
| 251 | + |
| 252 | +_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.6.0, on August 10, 2017._ |
| 253 | +Project scaffolded using [charlike-cli][]. |
| 254 | + |
| 255 | +[babylon]: https://babeljs.io/ |
| 256 | +[charlike-cli]: https://github.com/tunnckoCore/charlike-cli |
| 257 | +[charlike]: https://github.com/tunnckoCore/charlike |
| 258 | +[define-property]: https://github.com/jonschlinkert/define-property |
| 259 | +[execa]: https://github.com/sindresorhus/execa |
| 260 | +[function-arguments]: https://github.com/tunnckocore/function-arguments |
| 261 | + |
| 262 | +<!-- Heading badges --> |
| 263 | +[npmv-url]: https://www.npmjs.com/package/parse-function |
| 264 | +[npmv-img]: https://img.shields.io/npm/v/parse-function.svg |
| 265 | + |
| 266 | +[open-issue-url]: https://github.com/tunnckoCore/parse-function/issues/new |
| 267 | +[github-release-url]: https://github.com/tunnckoCore/parse-function/releases/latest |
| 268 | +[github-release-img]: https://img.shields.io/github/release/tunnckoCore/parse-function.svg |
| 269 | + |
| 270 | +[license-url]: https://github.com/tunnckoCore/parse-function/blob/master/LICENSE |
| 271 | +[license-img]: https://img.shields.io/npm/l/parse-function.svg |
| 272 | + |
| 273 | +[downloads-weekly-url]: https://www.npmjs.com/package/parse-function |
| 274 | +[downloads-weekly-img]: https://img.shields.io/npm/dw/parse-function.svg |
| 275 | + |
| 276 | +[downloads-total-url]: https://www.npmjs.com/package/parse-function |
| 277 | +[downloads-total-img]: https://img.shields.io/npm/dt/parse-function.svg |
| 278 | + |
| 279 | +<!-- Front line badges --> |
| 280 | +[codeclimate-url]: https://codeclimate.com/github/tunnckoCore/parse-function |
| 281 | +[codeclimate-img]: https://img.shields.io/codeclimate/github/tunnckoCore/parse-function.svg |
| 282 | + |
| 283 | +[standard-url]: https://github.com/standard/standard |
| 284 | +[standard-img]: https://img.shields.io/badge/code_style-standard-brightgreen.svg |
| 285 | + |
| 286 | +[travis-url]: https://travis-ci.org/tunnckoCore/parse-function |
| 287 | +[travis-img]: https://img.shields.io/travis/tunnckoCore/parse-function/master.svg?label=linux |
| 288 | + |
| 289 | +[codecov-url]: https://codecov.io/gh/tunnckoCore/parse-function |
| 290 | +[codecov-img]: https://img.shields.io/codecov/c/github/tunnckoCore/parse-function/master.svg |
| 291 | + |
| 292 | +[dependencies-url]: https://david-dm.org/tunnckoCore/parse-function |
| 293 | +[dependencies-img]: https://img.shields.io/david/tunnckoCore/parse-function.svg |
| 294 | + |
| 295 | +[renovate-url]: https://renovateapp.com |
| 296 | +[renovate-img]: https://img.shields.io/badge/renovate-enabled-brightgreen.svg |
| 297 | + |
| 298 | +<!-- Second front of badges --> |
| 299 | + |
| 300 | +[gitterchat-url]: https://gitter.im/tunnckoCore/support |
| 301 | +[gitterchat-img]: https://img.shields.io/gitter/room/tunnckoCore/support.svg |
| 302 | + |
| 303 | +[prettier-url]: https://github.com/prettier/prettier |
| 304 | +[prettier-img]: https://img.shields.io/badge/styled_with-prettier-f952a5.svg |
| 305 | + |
| 306 | +[nodesecurity-url]: https://nodesecurity.io/orgs/tunnckocore-dev/projects/5d75a388-acfe-4668-ad18-e98564e387e1 |
| 307 | +[nodesecurity-img]: https://nodesecurity.io/orgs/tunnckocore-dev/projects/5d75a388-acfe-4668-ad18-e98564e387e1/badge |
| 308 | +<!-- the original color of nsp: |
| 309 | +[nodesec-img]: https://img.shields.io/badge/nsp-no_known_vulns-35a9e0.svg --> |
| 310 | + |
| 311 | +[semantic-release-url]: https://github.com/semantic-release/semantic-release |
| 312 | +[semantic-release-img]: https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg |
| 313 | + |
| 314 | +[ccommits-url]: https://conventionalcommits.org/ |
| 315 | +[ccommits-img]: https://img.shields.io/badge/conventional_commits-1.0.0-yellow.svg |
| 316 | + |
| 317 | +[nodeversion-url]: https://nodejs.org/en/download |
| 318 | +[nodeversion-img]: https://img.shields.io/node/v/parse-function.svg |
| 319 | + |
0 commit comments