UNPKG

23.9 kBMarkdownView Raw
1# parse-function [![npm version][npmv-img]][npmv-url] [![License][license-img]][license-url]
2
3> Parse a function into an object using espree, acorn or babylon parsers. Extensible through Smart Plugins
4
5Please consider following this project's author, [Charlike Mike Reagent](https://github.com/tunnckoCore), and :star: the project to show your :heart: and support.
6
7<div id="readme"></div>
8
9[![Code style][codestyle-img]][codestyle-url]
10[![CircleCI linux build][linuxbuild-img]][linuxbuild-url]
11[![CodeCov coverage status][codecoverage-img]][codecoverage-url]
12[![DavidDM dependency status][dependencies-img]][dependencies-url]
13[![Renovate App Status][renovateapp-img]][renovateapp-url]
14[![Time Since Last Commit][last-commit-img]][last-commit-url]
15[![Make A Pull Request][prs-welcome-img]][prs-welcome-url]
16
17<!-- [![Semantically Released][standard-release-img]][standard-release-url] -->
18
19If you have any _how-to_ kind of questions, please read the [Contributing Guide][contributing-url] and [Code of Conduct][code_of_conduct-url] documents.
20For bugs reports and feature requests, [please create an issue][open-issue-url] or ping
21[@tunnckoCore](https://twitter.com/tunnckoCore) at Twitter.
22
23[![Conventional Commits][ccommits-img]][ccommits-url]
24[![Minimum Required Nodejs][nodejs-img]][npmv-url]
25[![NPM Downloads Monthly][downloads-monthly-img]][npmv-url]
26[![NPM Downloads Total][downloads-total-img]][npmv-url]
27[![Share Love Tweet][twitter-share-img]][twitter-share-url]
28[![Twitter][twitter-img]][twitter-url]
29
30Project is [semantically](https://semver.org) versioned & automatically released from [GitHub Actions](https://github.com/features/actions) with [Lerna](https://github.com/lerna/lerna).
31
32[![Become a Patron][patreon-img]][patreon-url]
33[![Buy me a Kofi][kofi-img]][kofi-url]
34[![PayPal Donation][paypal-img]][paypal-url]
35[![Bitcoin Coinbase][bitcoin-img]][bitcoin-url]
36[![Keybase PGP][keybase-img]][keybase-url]
37
38| Topic | Contact |
39| :--------------------------------------------------------------- | ------------------------------------------------: |
40| Any legal or licensing questions, like private or commerical use | ![tunnckocore_legal][tunnckocore_legal] |
41| For any critical problems and security reports | ![tunnckocore_security][tunnckocore_security] |
42| Consulting, professional support, personal or team training | ![tunnckocore_consulting][tunnckocore_consulting] |
43| For any questions about Open Source, partnerships and sponsoring | ![tunnckocore_opensource][tunnckocore_opensource] |
44
45<!-- Logo when needed:
46
47<p align="center">
48 <a href="https://github.com/tunnckoCore/opensource">
49 <img src="./media/logo.png" width="85%">
50 </a>
51</p>
52
53-->
54
55## Features
56
57- **Always up-to-date:** auto-publish new version when new version of dependency is out, [Renovate](https://renovateapp.com)
58- **Standard:** using StandardJS, Prettier, SemVer, Semantic Release and conventional commits
59- **Smart Plugins:** for extending the core API or the end [Result](#result), see [.use](#use) method and [Plugins Architecture](#plugins-architecture)
60- **Extensible:** using plugins for working directly on AST nodes, see the [Plugins Architecture](#plugins-architecture)
61- **ES2020+ Ready:** by using `.parseExpression` method of the Babel `v7.x` parser
62- **Customization:** allows switching the parser, through `options.parse`
63- **Support for:** arrow functions, default parameters, generators and async/await functions
64- **Stable:** battle-tested in production and against all parsers - [espree][], [acorn][], [@babel/parser](https://npmjs.com/packages/@babel/parser)
65- **Tested:** with [450+ tests](./test/index.js) for _200%_ coverage
66
67## Table of Contents
68
69- [Install](#install)
70- [Which version to use?](#which-version-to-use)
71- [Notes](#notes)
72 - [Throws in one specific case](#throws-in-one-specific-case)
73 - [Function named _"anonymous"_](#function-named-_anonymous_)
74 - [Real anonymous function](#real-anonymous-function)
75 - [Plugins Architecture](#plugins-architecture)
76- [API](#api)
77 - [parseFunction](#parsefunction)
78 - [.parse](#parse)
79 - [.use](#use)
80 - [.define](#define)
81- [Result](#result)
82- [Contributing](#contributing)
83 - [Guides and Community](#guides-and-community)
84 - [Support the project](#support-the-project)
85 - [OPEN Open Source](#open-open-source)
86 - [Wonderful Contributors](#wonderful-contributors)
87- [License](#license)
88
89_(TOC generated by [verb](https://github.com/verbose/verb) using [markdown-toc](https://github.com/jonschlinkert/markdown-toc))_
90
91## Install
92
93This project requires [**Node.js**](https://nodejs.org) **>=8.11** _(see [Support & Release Policy](https://github.com/tunnckoCoreLabs/support-release-policy))_. Install it using
94[**yarn**](https://yarnpkg.com) or [**npm**](https://npmjs.com).<br>
95_We highly recommend to use Yarn when you think to contribute to this project._
96
97```bash
98$ yarn add parse-function
99```
100
101## Which version to use?
102
103There's no breaking changes between the `v2.x` version. The only breaking is `v2.1` which also is not
104working properly, so no use it.
105
106**Use v2.0.x**
107
108When you don't need support for `arrow functions` and `es6 default params`. This version
109uses a RegExp expression to work.
110
111**Use v2.2.x**
112
113Only when you need a _basic_ support for `es6 features` like arrow functions. This version
114uses a RegExp expression to work.
115
116**Use v2.3.x**
117
118When you want _full\*_ support for `arrow functions` and `es6 default params`. Where this "full",
119means "almost full", because it has bugs. This version also uses (`acorn.parse`) real parser
120to do the parsing.
121
122**Use v3.x**
123
124When you want to use different parser instead of the default `babylon.parse`, by passing custom
125parse function to the `options.parse` option. **From this version we require `node >= 4`**.
126
127**Use v4.x**
128
129When you want full customization and most stable support for old and modern features. This version
130uses `babylon.parseExpression` for parsing and provides a [Plugins API](#plugins-architecture).
131See the [Features](#features) section for more info.
132
133**Use v5.x**
134
135It is basically the same as `v4`, but requires Node 6 & npm 5. Another is boilerplate stuff.
136
137**[back to top](#readme)**
138
139## Notes
140
141### Throws in one specific case
142
143> _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)_
144
145It may throw in one specific case, otherwise it won't throw, so you should
146relay on the `result.isValid` for sure.
147
148### Function named _"anonymous"_
149
150> _see: [test/index.js#L319-L324](https://github.com/tunnckoCore/parse-function/blob/master/test/index.js#L319-L324) and [Result](#result) section_
151
152If you pass a function which is named _"anonymous"_ the `result.name` will be `'anonymous'`,
153but the `result.isAnonymous` will be `false` and `result.isNamed` will be `true`, because
154in fact it's a named function.
155
156### Real anonymous function
157
158> _see: [test/index.js#L326-L331](https://github.com/tunnckoCore/parse-function/blob/master/test/index.js#L326-L331) and [Result](#result) section_
159
160Only if you pass really an anonymous function you will get `result.name` equal to `null`,
161`result.isAnonymous` equal to `true` and `result.isNamed` equal to `false`.
162
163**[back to top](#readme)**
164
165### Plugins Architecture
166
167> _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)_
168
169A more human description of the plugin mechanism. Plugins are **synchronous** - no support
170and no need for **async** plugins here, but notice that you can do that manually, because
171that exact architecture.
172
173The first function that is passed to the [.use](#use) method is used for extending the core API,
174for example adding a new method to the `app` instance. That function is immediately invoked.
175
176```js
177const parseFunction = require('parse-function');
178const app = parseFunction();
179
180app.use((self) => {
181 // self is same as `app`
182 console.log(self.use);
183 console.log(self.parse);
184 console.log(self.define);
185
186 self.define(self, 'foo', (bar) => bar + 1);
187});
188
189console.log(app.foo(2)); // => 3
190```
191
192On the other side, if you want to access the AST of the parser, you should return a function
193from that plugin, which function is passed with `(node, result)` signature.
194
195This function is lazy plugin, it is called only when the [.parse](#parse) method is called.
196
197```js
198const parseFunction = require('parse-function');
199const app = parseFunction();
200
201app.use((self) => {
202 console.log('immediately called');
203
204 return (node, result) => {
205 console.log('called only when .parse is invoked');
206 console.log(node);
207 console.log(result);
208 };
209});
210```
211
212Where **1)** the `node` argument is an object - actual and real AST Node coming from the parser
213and **2)** the `result` is an object too - the end [Result](#result), on which
214you can add more properties if you want.
215
216**[back to top](#readme)**
217
218<!-- docks-start -->
219
220## API
221
222_Generated using [jest-runner-docs](https://npmjs.com/package/jest-runner-docs)._
223
224### [parseFunction](./src/index.js#L52)
225
226> Initializes with optional `opts` object which is passed directly
227> to the desired parser and returns an object
228> with `.use` and `.parse` methods. The default parse which
229> is used is [babylon][]'s `.parseExpression` method from `v7`.
230
231**Signature**
232
233```ts
234function(opts)
235```
236
237**Params**
238
239- `opts` - optional, merged with options passed to `.parse` method
240- `returns` - app object with `.use` and `.parse` methods
241
242**Example**
243
244```js
245const parseFunction = require('parse-function');
246
247const app = parseFunction({
248 ecmaVersion: 2017,
249});
250
251const fixtureFn = (a, b, c) => {
252 a = b + c;
253 return a + 2;
254};
255
256const result = app.parse(fixtureFn);
257console.log(result);
258
259// see more
260console.log(result.name); // => null
261console.log(result.isNamed); // => false
262console.log(result.isArrow); // => true
263console.log(result.isAnonymous); // => true
264
265// array of names of the arguments
266console.log(result.args); // => ['a', 'b', 'c']
267
268// comma-separated names of the arguments
269console.log(result.params); // => 'a, b, c'
270```
271
272### [.parse](./src/index.js#L117)
273
274> Parse a given `code` and returns a `result` object
275> with useful properties - such as `name`, `body` and `args`.
276> By default it uses Babylon parser, but you can switch it by
277> passing `options.parse` - for example `options.parse: acorn.parse`.
278> In the below example will show how to use `acorn` parser, instead
279> of the default one.
280
281**Params**
282
283- `code` - any kind of function or string to be parsed
284- `options` - directly passed to the parser babylon, acorn, espree
285- `options.parse` - by default `babylon.parseExpression`,
286 all `options` are passed as second argument
287- `returns` - result see [result section](#result) for more info
288
289**Example**
290
291```js
292const acorn = require('acorn');
293const parseFn = require('parse-function');
294const app = parseFn();
295
296const fn = function foo(bar, baz) {
297 return bar * baz;
298};
299const result = app.parse(fn, {
300 parse: acorn.parse,
301 ecmaVersion: 2017,
302});
303
304console.log(result.name); // => 'foo'
305console.log(result.args); // => ['bar', 'baz']
306console.log(result.body); // => ' return bar * baz '
307console.log(result.isNamed); // => true
308console.log(result.isArrow); // => false
309console.log(result.isAnonymous); // => false
310console.log(result.isGenerator); // => false
311```
312
313### [.use](./src/index.js#L170)
314
315> Add a plugin `fn` function for extending the API or working on the
316> AST nodes. The `fn` is immediately invoked and passed
317> with `app` argument which is instance of `parseFunction()` call.
318> That `fn` may return another function that
319> accepts `(node, result)` signature, where `node` is an AST node
320> and `result` is an object which will be returned [result](#result)
321> from the `.parse` method. This retuned function is called on each
322> node only when `.parse` method is called.
323
324**Params**
325
326- `fn` - plugin to be called
327- `returns` - app instance for chaining
328
329_See [Plugins Architecture](#plugins-architecture) section._
330
331**Example**
332
333```js
334// plugin extending the `app`
335app.use((app) => {
336 app.define(app, 'hello', (place) => `Hello ${place}!`);
337});
338
339const hi = app.hello('World');
340console.log(hi); // => 'Hello World!'
341
342// or plugin that works on AST nodes
343app.use((app) => (node, result) => {
344 if (node.type === 'ArrowFunctionExpression') {
345 result.thatIsArrow = true;
346 }
347 return result;
348});
349
350const result = app.parse((a, b) => a + b + 123);
351console.log(result.name); // => null
352console.log(result.isArrow); // => true
353console.log(result.thatIsArrow); // => true
354
355const result = app.parse(function foo() {
356 return 123;
357});
358console.log(result.name); // => 'foo'
359console.log(result.isArrow); // => false
360console.log(result.thatIsArrow); // => undefined
361```
362
363### [.define](./src/index.js#L228)
364
365> Define a non-enumerable property on an object. Just
366> a convenience mirror of the [define-property][] library,
367> so check out its docs. Useful to be used in plugins.
368
369**Params**
370
371- `obj` - the object on which to define the property
372- `prop` - the name of the property to be defined or modified
373- `val` - the descriptor for the property being defined or modified
374- `returns` - obj the passed object, but modified
375
376**Example**
377
378```js
379const parseFunction = require('parse-function');
380const app = parseFunction();
381
382// use it like `define-property` lib
383const obj = {};
384app.define(obj, 'hi', 'world');
385console.log(obj); // => { hi: 'world' }
386
387// or define a custom plugin that adds `.foo` property
388// to the end result, returned from `app.parse`
389app.use((app) => {
390 return (node, result) => {
391 // this function is called
392 // only when `.parse` is called
393
394 app.define(result, 'foo', 123);
395
396 return result;
397 };
398});
399
400// fixture function to be parsed
401const asyncFn = async (qux) => {
402 const bar = await Promise.resolve(qux);
403 return bar;
404};
405
406const result = app.parse(asyncFn);
407
408console.log(result.name); // => null
409console.log(result.foo); // => 123
410console.log(result.args); // => ['qux']
411
412console.log(result.isAsync); // => true
413console.log(result.isArrow); // => true
414console.log(result.isNamed); // => false
415console.log(result.isAnonymous); // => true
416```
417
418<!-- docks-end -->
419
420## Result
421
422> In the result object you have `name`, `args`, `params`, `body` and few hidden properties
423> that can be useful to determine what the function is - arrow, regular, async/await or generator.
424
425- `name` **{String|null}**: name of the passed function or `null` if anonymous
426- `args` **{Array}**: arguments of the function
427- `params` **{String}**: comma-separated list representing the `args`
428- `defaults` **{Object}**: key/value pairs, useful when use ES2015 default arguments
429- `body` **{String}**: actual body of the function, respects trailing newlines and whitespaces
430- `isValid` **{Boolean}**: is the given value valid or not, that's because it never throws!
431- `isAsync` **{Boolean}**: `true` if function is ES2015 async/await function
432- `isArrow` **{Boolean}**: `true` if the function is arrow function
433- `isNamed` **{Boolean}**: `true` if function has name, or `false` if is anonymous
434- `isGenerator` **{Boolean}**: `true` if the function is ES2015 generator function
435- `isAnonymous` **{Boolean}**: `true` if the function don't have name
436
437**[back to top](#readme)**
438
439**[back to top](#readme)**
440
441## Contributing
442
443### Guides and Community
444
445Please read the [Contributing Guide][contributing-url] and [Code of Conduct][code_of_conduct-url] documents for advices.
446
447For bug reports and feature requests, please join our [community][community-url] forum and open a thread there with prefixing the title of the thread with the name of the project if there's no separate channel for it.
448
449Consider reading the [Support and Release Policy](https://github.com/tunnckoCoreLabs/support-release-policy) guide if you are interested in what are the supported Node.js versions and how we proceed. In short, we support latest two even-numbered Node.js release lines.
450
451### Support the project
452
453[Become a Partner or Sponsor?][patreon-url] :dollar: Check the **Partner**, **Sponsor** or **Omega-level** tiers! :tada: You can get your company logo, link & name on this file. It's also rendered on package page in [npmjs.com][npmv-url] and [yarnpkg.com](https://yarnpkg.com/en/package/parse-function) sites too! :rocket:
454
455Not financial support? Okey! [Pull requests](https://github.com/tunnckoCoreLabs/contributing#opening-a-pull-request), stars and all kind of [contributions](https://opensource.guide/how-to-contribute/#what-it-means-to-contribute) are always
456welcome. :sparkles:
457
458<!--
459### OPEN Open Source
460
461This project is following [OPEN Open Source](http://openopensource.org) model
462
463> Individuals making significant and valuable contributions are given commit-access to the project to contribute as they see fit. This project is built on collective efforts and it's not strongly guarded by its founders.
464
465There are a few basic ground-rules for its contributors
466
4671. Any **significant modifications** must be subject to a pull request to get feedback from other contributors.
4682. [Pull requests](https://github.com/tunnckoCoreLabs/contributing#opening-a-pull-request) to get feedback are _encouraged_ for any other trivial contributions, but are not required.
4693. Contributors should attempt to adhere to the prevailing code-style and development workflow.
470-->
471
472### Wonderful Contributors
473
474Thanks to the hard work of these wonderful people this project is alive! It follows the
475[all-contributors](https://github.com/kentcdodds/all-contributors) specification.
476Don't hesitate to add yourself to that list if you have made any contribution! ;) [See how,
477here](https://github.com/jfmengels/all-contributors-cli#usage).
478
479<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
480<!-- prettier-ignore -->
481| [<img src="https://avatars3.githubusercontent.com/u/5038030?v=4" width="120px;"/><br /><sub><b>Charlike Mike Reagent</b></sub>](https://tunnckocore.com)<br />[💻](https://github.com/tunnckoCore/opensource/commits?author=tunnckoCore "Code") [📖](https://github.com/tunnckoCore/opensource/commits?author=tunnckoCore "Documentation") [💬](#question-tunnckoCore "Answering Questions") [👀](#review-tunnckoCore "Reviewed Pull Requests") [🔍](#fundingFinding-tunnckoCore "Funding Finding") |
482| :---: |
483
484<!-- ALL-CONTRIBUTORS-LIST:END -->
485
486Consider showing your [support](#support-the-project) to them. :sparkling_heart:
487
488**[back to top](#readme)**
489
490## License
491
492Copyright (c) 2016-present, [Charlike Mike Reagent](https://tunnckocore.com) `<opensource@tunnckocore.com>` & [contributors](#wonderful-contributors).<br>
493Released under the [MPL-2.0 License][license-url].
494
495[contributing-url]: https://github.com/tunnckoCore/opensource/blob/master/CONTRIBUTING.md
496[code_of_conduct-url]: https://github.com/tunnckoCore/opensource/blob/master/CODE_OF_CONDUCT.md
497
498<!-- Heading badges -->
499
500[npmv-url]: https://www.npmjs.com/package/parse-function
501[npmv-img]: https://badgen.net/npm/v/parse-function?icon=npm
502[nodejs-img]: https://badgen.net/npm/node/parse-function
503
504<!--
505[ghrelease-url]: https://github.com/tunnckoCore/opensource/releases/latest
506[ghrelease-img]: https://badgen.net/github/release/tunnckoCore/opensource?icon=github
507-->
508
509[license-url]: https://github.com/tunnckoCore/opensource/blob/master/packages/parse-function/LICENSE
510[license-img]: https://badgen.net/npm/license/parse-function
511
512<!-- Front line badges -->
513
514[codestyle-url]: https://github.com/airbnb/javascript
515[codestyle-img]: https://badgen.net/badge/code%20style/airbnb/ff5a5f?icon=airbnb
516[linuxbuild-url]: https://github.com/tunnckocore/opensource/actions
517[linuxbuild-img]: https://badgen.net/github/status/tunnckoCore/opensource/master?label=build&icon=github
518[codecoverage-url]: https://codecov.io/gh/tunnckoCore/opensource
519[codecoverage-img]: https://badgen.net/codecov/c/github/tunnckoCore/opensource?icon=codecov
520[dependencies-url]: https://david-dm.org/tunnckoCore/opensource
521[dependencies-img]: https://badgen.net/david/dep/tunnckoCore/opensource?label=deps
522[ccommits-url]: https://conventionalcommits.org/
523[ccommits-img]: https://badgen.net/badge/conventional%20commits/v1.0.0/green
524[standard-release-url]: https://github.com/standard-release/standard-release
525[standard-release-img]: https://badgen.net/badge/semantically/released/05c5ff
526[community-img]: https://badgen.net/badge/join/community/7b16ff
527[community-url]: https://github.com/tunnckocorehq/community
528[last-commit-img]: https://badgen.net/github/last-commit/tunnckoCore/opensource/master
529[last-commit-url]: https://github.com/tunnckoCore/opensource/commits/master
530[downloads-weekly-img]: https://badgen.net/npm/dw/parse-function?icon=npm
531[downloads-monthly-img]: https://badgen.net/npm/dm/parse-function?icon=npm
532[downloads-total-img]: https://badgen.net/npm/dt/parse-function?icon=npm
533[renovateapp-url]: https://renovatebot.com
534[renovateapp-img]: https://badgen.net/badge/renovate/enabled/green
535[prs-welcome-img]: https://badgen.net/badge/PRs/welcome/green
536[prs-welcome-url]: http://makeapullrequest.com
537
538<!-- TODO: update icon -->
539
540[paypal-url]: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=HYJJEZNSGAPGC&source=url
541[paypal-img]: https://badgen.net/badge/PayPal/donate/003087?icon=https://simpleicons.now.sh/paypal/fff
542
543<!-- TODO: update icon -->
544
545[kofi-url]: https://ko-fi.com/tunnckoCore
546[kofi-img]: https://badgen.net/badge/Buy%20me/a%20coffee/29abe0c2?icon=https://rawcdn.githack.com/tunnckoCore/badgen-icons/f8264c6414e0bec449dd86f2241d50a9b89a1203/icons/kofi.svg
547
548<!-- TODO: update icon -->
549
550[bitcoin-url]: https://www.blockchain.com/btc/payment_request?address=3QNHKun1K1SUui1b4Z3KEGPPsWC1TgtnqA&message=Open+Source+Software&amount_local=10&currency=USD
551[bitcoin-img]: https://badgen.net/badge/Bitcoin%20tip/3QNHKun...b4Z3KEGPPsWC1TgtnqA/yellow?icon=https://simpleicons.now.sh/bitcoin/fff
552[keybase-url]: https://keybase.io/tunnckoCore
553[keybase-img]: https://badgen.net/keybase/pgp/tunnckoCore
554[twitter-url]: https://twitter.com/tunnckoCore
555[twitter-img]: https://badgen.net/twitter/follow/tunnckoCore?icon=twitter&color=1da1f2
556[patreon-url]: https://www.patreon.com/bePatron?u=5579781
557[patreon-img]: https://badgen.net/badge/Become/a%20patron/F96854?icon=patreon
558
559<!-- [patreon-img]: https://badgen.net/badge/Patreon/tunnckoCore/F96854?icon=patreon -->
560
561[patreon-sponsor-img]: https://badgen.net/badge/become/a%20sponsor/F96854?icon=patreon
562[twitter-share-url]: https://twitter.com/intent/tweet?text=https://github.com/tunnckoCore/opensource&via=tunnckoCore
563[twitter-share-img]: https://badgen.net/badge/twitter/share/1da1f2?icon=twitter
564[open-issue-url]: https://github.com/tunnckoCore/opensource/issues/new
565[tunnckocore_legal]: https://badgen.net/https/liam-badge-daknys6gadky.runkit.sh/com/legal/tunnckocore?label&color=A56016&icon=https://svgshare.com/i/Dt6.svg
566[tunnckocore_consulting]: https://badgen.net/https/liam-badge-daknys6gadky.runkit.sh/com/consulting/tunnckocore?label&color=07ba96&icon=https://svgshare.com/i/Dt6.svg
567[tunnckocore_security]: https://badgen.net/https/liam-badge-daknys6gadky.runkit.sh/com/security/tunnckocore?label&color=ed1848&icon=https://svgshare.com/i/Dt6.svg
568[tunnckocore_opensource]: https://badgen.net/https/liam-badge-daknys6gadky.runkit.sh/com/opensource/tunnckocore?label&color=ff7a2f&icon=https://svgshare.com/i/Dt6.svg
569[tunnckocore_newsletter]: https://badgen.net/https/liam-badge-daknys6gadky.runkit.sh/com/newsletter/tunnckocore?label&color=5199FF&icon=https://svgshare.com/i/Dt6.svg
570[acorn]: https://github.com/acornjs/acorn
571[babylon]: https://babeljs.io/
572[define-property]: https://github.com/jonschlinkert/define-property
573[espree]: https://github.com/eslint/espree