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

parse-function

Package Overview
Dependencies
Maintainers
2
Versions
86
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

parse-function - npm Package Compare versions

Comparing version 5.4.1 to 5.4.2

11

CHANGELOG.md

@@ -6,2 +6,13 @@ # Change Log

## [5.4.2](https://github.com/tunnckoCore/opensource/compare/parse-function@5.4.1...parse-function@5.4.2) (2019-10-22)
### Bug Fixes
* update errors in parse-function, run docs+fmt ([667c253](https://github.com/tunnckoCore/opensource/commit/667c2539f668bfe07659ea397d9dda1305b7da4e))
## [5.4.1](https://github.com/tunnckoCore/opensource/compare/parse-function@5.4.0...parse-function@5.4.1) (2019-10-22)

@@ -8,0 +19,0 @@

37

dist/cjs/index.js

@@ -28,3 +28,2 @@ 'use strict';

const utils = {};
utils.define = typeof Reflect !== 'undefined' ? Reflect.defineProperty : Object.defineProperty;
utils.arrayify = arrify_1;

@@ -52,11 +51,11 @@

utils.setHiddenDefaults = function setHiddenDefaults(result, code) {
utils.define(result, 'defaults', {});
utils.define(result, 'value', code);
utils.define(result, 'isValid', code.length > 0);
utils.define(result, 'isArrow', false);
utils.define(result, 'isAsync', false);
utils.define(result, 'isNamed', false);
utils.define(result, 'isAnonymous', false);
utils.define(result, 'isGenerator', false);
utils.define(result, 'isExpression', false);
result.defaults = {};
result.value = code;
result.isValid = code.length > 0;
result.isArrow = false;
result.isAsync = false;
result.isNamed = false;
result.isAnonymous = false;
result.isGenerator = false;
result.isExpression = false;
return result;

@@ -88,9 +87,9 @@ };

const props = (app => (node, result) => {
app.define(result, 'isArrow', node.type.startsWith('Arrow'));
app.define(result, 'isAsync', node.async || false);
app.define(result, 'isGenerator', node.generator || false);
app.define(result, 'isExpression', node.expression || false);
app.define(result, 'isAnonymous', node.id === null);
app.define(result, 'isNamed', !result.isAnonymous);
const props = (() => (node, result) => {
result.isArrow = node.type.startsWith('Arrow');
result.isAsync = node.async || false;
result.isGenerator = node.generator || false;
result.isExpression = node.expression || false;
result.isAnonymous = node.id === null;
result.isNamed = !result.isAnonymous;
result.name = result.isAnonymous ? null : node.id.name;

@@ -135,3 +134,3 @@ return result;

result = props(app)(node, result);
result = props()(node, result);
result = params()(node, result);

@@ -143,3 +142,3 @@ result = body()(node, result);

function parseFunction(opts = {}) {
const plugins = [...fakeChange];
const plugins = [];
const app = {

@@ -146,0 +145,0 @@ parse(code, options) {

@@ -26,3 +26,2 @@ import { parseExpression } from '@babel/parser';

const utils = {};
utils.define = typeof Reflect !== 'undefined' ? Reflect.defineProperty : Object.defineProperty;
utils.arrayify = arrify_1;

@@ -50,11 +49,11 @@

utils.setHiddenDefaults = function setHiddenDefaults(result, code) {
utils.define(result, 'defaults', {});
utils.define(result, 'value', code);
utils.define(result, 'isValid', code.length > 0);
utils.define(result, 'isArrow', false);
utils.define(result, 'isAsync', false);
utils.define(result, 'isNamed', false);
utils.define(result, 'isAnonymous', false);
utils.define(result, 'isGenerator', false);
utils.define(result, 'isExpression', false);
result.defaults = {};
result.value = code;
result.isValid = code.length > 0;
result.isArrow = false;
result.isAsync = false;
result.isNamed = false;
result.isAnonymous = false;
result.isGenerator = false;
result.isExpression = false;
return result;

@@ -86,9 +85,9 @@ };

const props = (app => (node, result) => {
app.define(result, 'isArrow', node.type.startsWith('Arrow'));
app.define(result, 'isAsync', node.async || false);
app.define(result, 'isGenerator', node.generator || false);
app.define(result, 'isExpression', node.expression || false);
app.define(result, 'isAnonymous', node.id === null);
app.define(result, 'isNamed', !result.isAnonymous);
const props = (() => (node, result) => {
result.isArrow = node.type.startsWith('Arrow');
result.isAsync = node.async || false;
result.isGenerator = node.generator || false;
result.isExpression = node.expression || false;
result.isAnonymous = node.id === null;
result.isNamed = !result.isAnonymous;
result.name = result.isAnonymous ? null : node.id.name;

@@ -133,3 +132,3 @@ return result;

result = props(app)(node, result);
result = props()(node, result);
result = params()(node, result);

@@ -141,3 +140,3 @@ result = body()(node, result);

function parseFunction(opts = {}) {
const plugins = [...fakeChange];
const plugins = [];
const app = {

@@ -144,0 +143,0 @@ parse(code, options) {

{
"name": "parse-function",
"version": "5.4.1",
"version": "5.4.2",
"description": "Parse a function into an object using espree, acorn or babylon parsers. Extensible through Smart Plugins",

@@ -64,2 +64,12 @@ "repository": {

},
"jest": {
"coverageThreshold": {
"src/**/*.js": {
"statements": 100,
"branches": 100,
"functions": 100,
"lines": 100
}
}
},
"licenseStart": 2016,

@@ -91,13 +101,3 @@ "verb": {

},
"jest": {
"coverageThreshold": {
"src/**/*.js": {
"statements": 100,
"branches": 100,
"functions": 100,
"lines": 100
}
}
},
"gitHead": "6c19103482bd5eeabc6d9c8ca7cc12cf3ea21d07"
"gitHead": "13bc1e024e35fce9f89c1b027ec05d01a5cba5af"
}

@@ -55,29 +55,7 @@ # parse-function [![npm version][npmv-img]][npmv-url] [![License][license-img]][license-url]

## Features
() => include(process.cwd() + '/.verb.head.md')
- **Always up-to-date:** auto-publish new version when new version of dependency is out, [Renovate](https://renovateapp.com)
- **Standard:** using StandardJS, Prettier, SemVer, Semantic Release and conventional commits
- **Smart Plugins:** for extending the core API or the end [Result](#result), see [.use](#use) method and [Plugins Architecture](#plugins-architecture)
- **Extensible:** using plugins for working directly on AST nodes, see the [Plugins Architecture](#plugins-architecture)
- **ES2020+ Ready:** by using `.parseExpression` method of the Babel `v7.x` parser
- **Customization:** allows switching the parser, through `options.parse`
- **Support for:** arrow functions, default parameters, generators and async/await functions
- **Stable:** battle-tested in production and against all parsers - [espree][], [acorn][], [@babel/parser](https://npmjs.com/packages/@babel/parser)
- **Tested:** with [450+ tests](./test/index.js) for _200%_ coverage
## Table of Contents
- [Install](#install)
- [Which version to use?](#which-version-to-use)
- [Notes](#notes)
- [Throws in one specific case](#throws-in-one-specific-case)
- [Function named _"anonymous"_](#function-named-_anonymous_)
- [Real anonymous function](#real-anonymous-function)
- [Plugins Architecture](#plugins-architecture)
- [API](#api)
- [parseFunction](#parsefunction)
- [.parse](#parse)
- [.use](#use)
- [.define](#define)
- [Result](#result)
- [Contributing](#contributing)

@@ -102,342 +80,6 @@ - [Guides and Community](#guides-and-community)

## Which version to use?
() => include(process.cwd() + '/.verb.md')
There's no breaking changes between the `v2.x` version. The only breaking is `v2.1` which also is not
working properly, so no use it.
**Use v2.0.x**
When you don't need support for `arrow functions` and `es6 default params`. This version
uses a RegExp expression to work.
**Use v2.2.x**
Only when you need a _basic_ support for `es6 features` like arrow functions. This version
uses a RegExp expression to work.
**Use v2.3.x**
When you want _full\*_ support for `arrow functions` and `es6 default params`. Where this "full",
means "almost full", because it has bugs. This version also uses (`acorn.parse`) real parser
to do the parsing.
**Use v3.x**
When you want to use different parser instead of the default `babylon.parse`, by passing custom
parse function to the `options.parse` option. **From this version we require `node >= 4`**.
**Use v4.x**
When you want full customization and most stable support for old and modern features. This version
uses `babylon.parseExpression` for parsing and provides a [Plugins API](#plugins-architecture).
See the [Features](#features) section for more info.
**Use v5.x**
It is basically the same as `v4`, but requires Node 6 & npm 5. Another is boilerplate stuff.
**[back to top](#readme)**
## Notes
### Throws in one specific case
> _see: [issue #3](https://github.com/tunnckoCore/parse-function/issues/3) and [test/index.js#L229-L235](https://github.com/tunnckoCore/parse-function/blob/master/test/index.js#L229-L235)_
It may throw in one specific case, otherwise it won't throw, so you should
relay on the `result.isValid` for sure.
### Function named _"anonymous"_
> _see: [test/index.js#L319-L324](https://github.com/tunnckoCore/parse-function/blob/master/test/index.js#L319-L324) and [Result](#result) section_
If you pass a function which is named _"anonymous"_ the `result.name` will be `'anonymous'`,
but the `result.isAnonymous` will be `false` and `result.isNamed` will be `true`, because
in fact it's a named function.
### Real anonymous function
> _see: [test/index.js#L326-L331](https://github.com/tunnckoCore/parse-function/blob/master/test/index.js#L326-L331) and [Result](#result) section_
Only if you pass really an anonymous function you will get `result.name` equal to `null`,
`result.isAnonymous` equal to `true` and `result.isNamed` equal to `false`.
**[back to top](#readme)**
### Plugins Architecture
> _see: the [.use](#use) method, [test/index.js#L305-L317](https://github.com/tunnckoCore/parse-function/blob/master/test/index.js#L305-L317) and [test/index.js#L396-L414](https://github.com/tunnckoCore/parse-function/blob/master/test/index.js#L396-L414)_
A more human description of the plugin mechanism. Plugins are **synchronous** - no support
and no need for **async** plugins here, but notice that you can do that manually, because
that exact architecture.
The first function that is passed to the [.use](#use) method is used for extending the core API,
for example adding a new method to the `app` instance. That function is immediately invoked.
```js
const parseFunction = require('parse-function');
const app = parseFunction();
app.use((self) => {
// self is same as `app`
console.log(self.use);
console.log(self.parse);
console.log(self.define);
self.define(self, 'foo', (bar) => bar + 1);
});
console.log(app.foo(2)); // => 3
```
On the other side, if you want to access the AST of the parser, you should return a function
from that plugin, which function is passed with `(node, result)` signature.
This function is lazy plugin, it is called only when the [.parse](#parse) method is called.
```js
const parseFunction = require('parse-function');
const app = parseFunction();
app.use((self) => {
console.log('immediately called');
return (node, result) => {
console.log('called only when .parse is invoked');
console.log(node);
console.log(result);
};
});
```
Where **1)** the `node` argument is an object - actual and real AST Node coming from the parser
and **2)** the `result` is an object too - the end [Result](#result), on which
you can add more properties if you want.
**[back to top](#readme)**
<!-- docks-start -->
## API
_Generated using [jest-runner-docs](https://npmjs.com/package/jest-runner-docs)._
### [parseFunction](./src/index.js#L52)
> Initializes with optional `opts` object which is passed directly
> to the desired parser and returns an object
> with `.use` and `.parse` methods. The default parse which
> is used is [babylon][]'s `.parseExpression` method from `v7`.
**Signature**
```ts
function(opts)
```
**Params**
- `opts` - optional, merged with options passed to `.parse` method
- `returns` - app object with `.use` and `.parse` methods
**Example**
```js
const parseFunction = require('parse-function');
const app = parseFunction({
ecmaVersion: 2017,
});
const fixtureFn = (a, b, c) => {
a = b + c;
return a + 2;
};
const result = app.parse(fixtureFn);
console.log(result);
// see more
console.log(result.name); // => null
console.log(result.isNamed); // => false
console.log(result.isArrow); // => true
console.log(result.isAnonymous); // => true
// array of names of the arguments
console.log(result.args); // => ['a', 'b', 'c']
// comma-separated names of the arguments
console.log(result.params); // => 'a, b, c'
```
### [.parse](./src/index.js#L117)
> Parse a given `code` and returns a `result` object
> with useful properties - such as `name`, `body` and `args`.
> By default it uses Babylon parser, but you can switch it by
> passing `options.parse` - for example `options.parse: acorn.parse`.
> In the below example will show how to use `acorn` parser, instead
> of the default one.
**Params**
- `code` - any kind of function or string to be parsed
- `options` - directly passed to the parser babylon, acorn, espree
- `options.parse` - by default `babylon.parseExpression`,
all `options` are passed as second argument
- `returns` - result see [result section](#result) for more info
**Example**
```js
const acorn = require('acorn');
const parseFn = require('parse-function');
const app = parseFn();
const fn = function foo(bar, baz) {
return bar * baz;
};
const result = app.parse(fn, {
parse: acorn.parse,
ecmaVersion: 2017,
});
console.log(result.name); // => 'foo'
console.log(result.args); // => ['bar', 'baz']
console.log(result.body); // => ' return bar * baz '
console.log(result.isNamed); // => true
console.log(result.isArrow); // => false
console.log(result.isAnonymous); // => false
console.log(result.isGenerator); // => false
```
### [.use](./src/index.js#L170)
> 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.
**Params**
- `fn` - plugin to be called
- `returns` - app instance for chaining
_See [Plugins Architecture](#plugins-architecture) section._
**Example**
```js
// plugin extending the `app`
app.use((app) => {
app.define(app, 'hello', (place) => `Hello ${place}!`);
});
const hi = app.hello('World');
console.log(hi); // => 'Hello World!'
// or plugin that works on AST nodes
app.use((app) => (node, result) => {
if (node.type === 'ArrowFunctionExpression') {
result.thatIsArrow = true;
}
return result;
});
const result = app.parse((a, b) => a + b + 123);
console.log(result.name); // => null
console.log(result.isArrow); // => true
console.log(result.thatIsArrow); // => true
const result = app.parse(function foo() {
return 123;
});
console.log(result.name); // => 'foo'
console.log(result.isArrow); // => false
console.log(result.thatIsArrow); // => undefined
```
### [.define](./src/index.js#L228)
> Define a non-enumerable property on an object. Just
> a convenience mirror of the [define-property][] library,
> so check out its docs. Useful to be used in plugins.
**Params**
- `obj` - the object on which to define the property
- `prop` - the name of the property to be defined or modified
- `val` - the descriptor for the property being defined or modified
- `returns` - obj the passed object, but modified
**Example**
```js
const parseFunction = require('parse-function');
const app = parseFunction();
// use it like `define-property` lib
const obj = {};
app.define(obj, 'hi', 'world');
console.log(obj); // => { hi: 'world' }
// or define a custom plugin that adds `.foo` property
// to the end result, returned from `app.parse`
app.use((app) => {
return (node, result) => {
// this function is called
// only when `.parse` is called
app.define(result, 'foo', 123);
return result;
};
});
// fixture function to be parsed
const asyncFn = async (qux) => {
const bar = await Promise.resolve(qux);
return bar;
};
const result = app.parse(asyncFn);
console.log(result.name); // => null
console.log(result.foo); // => 123
console.log(result.args); // => ['qux']
console.log(result.isAsync); // => true
console.log(result.isArrow); // => true
console.log(result.isNamed); // => false
console.log(result.isAnonymous); // => true
```
<!-- docks-end -->
## Result
> In the result object you have `name`, `args`, `params`, `body` and few hidden properties
> that can be useful to determine what the function is - arrow, regular, async/await or generator.
- `name` **{String|null}**: name of the passed function or `null` if anonymous
- `args` **{Array}**: arguments of the function
- `params` **{String}**: comma-separated list representing the `args`
- `defaults` **{Object}**: key/value pairs, useful when use ES2015 default arguments
- `body` **{String}**: actual body of the function, respects trailing newlines and whitespaces
- `isValid` **{Boolean}**: is the given value valid or not, that's because it never throws!
- `isAsync` **{Boolean}**: `true` if function is ES2015 async/await function
- `isArrow` **{Boolean}**: `true` if the function is arrow function
- `isNamed` **{Boolean}**: `true` if function has name, or `false` if is anonymous
- `isGenerator` **{Boolean}**: `true` if the function is ES2015 generator function
- `isAnonymous` **{Boolean}**: `true` if the function don't have name
**[back to top](#readme)**
**[back to top](#readme)**
## Contributing

@@ -572,5 +214,1 @@

[tunnckocore_newsletter]: https://badgen.net/https/liam-badge-daknys6gadky.runkit.sh/com/newsletter/tunnckocore?label&color=5199FF&icon=https://svgshare.com/i/Dt6.svg
[acorn]: https://github.com/acornjs/acorn
[babylon]: https://babeljs.io/
[define-property]: https://github.com/jonschlinkert/define-property
[espree]: https://github.com/eslint/espree

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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