Skip to content

Commit

Permalink
Require Node.js 12.20 and move to ESM
Browse files Browse the repository at this point in the history
  • Loading branch information
sindresorhus committed Aug 24, 2021
1 parent 579ff4f commit 62a47ef
Show file tree
Hide file tree
Showing 9 changed files with 51 additions and 98 deletions.
7 changes: 2 additions & 5 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,10 @@ jobs:
fail-fast: false
matrix:
node-version:
- 14
- 12
- 10
- 8
- 16
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- run: npm install
Expand Down
8 changes: 3 additions & 5 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Get the arguments of a function, arrow function, generator function, async funct
@example
```
import functionArguments = require('fn-args');
import functionArguments from 'fn-args';
functionArguments(function (foo, bar) {});
//=> ['foo', 'bar']
Expand All @@ -18,8 +18,6 @@ functionArguments(async function (foo, bar) {});
//=> ['foo', 'bar']
```
*/
declare function functionArguments(
fn: (...arguments: any[]) => unknown
export default function functionArguments(
function_: (...arguments: any[]) => any
): string[];

export = functionArguments;
55 changes: 27 additions & 28 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,42 +1,41 @@
'use strict';
module.exports = fn => {
if (typeof fn !== 'function') {
export default function functionArguments(function_) {
if (typeof function_ !== 'function') {
throw new TypeError('Expected a function');
}

const commentRegex = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg;
const commentRegex = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/gm;
const quotes = ['`', '"', '\''];

const functionSource = fn.toString().replace(commentRegex, ''); // Function with no comments
const functionSource = function_.toString().replace(commentRegex, ''); // Function with no comments

let functionWithNoDefaults = '';
let depth = 0; // () [] {}
let fnNoDefaults = ''; // Function with no default values
let i = 0;
let index = 0;

// To remove default values we can not use regexp because finite automaton can not handle such
// things as (potential) infinity-nested blocks (), [], {}

// Remove default values
for (; i < functionSource.length && functionSource.charAt(i) !== ')'; i += 1) {
for (; index < functionSource.length && functionSource.charAt(index) !== ')'; index += 1) {
// Exiting if an arrow occurs. Needed when arrow function without '()'.
if (functionSource.startsWith('=>', i)) {
fnNoDefaults = functionSource;
i = functionSource.length;
if (functionSource.startsWith('=>', index)) {
functionWithNoDefaults = functionSource;
index = functionSource.length;
break;
}

// If we found a default value - skip it
if (functionSource.charAt(i) === '=') {
for (; i < functionSource.length && ((functionSource.charAt(i) !== ',' && functionSource.charAt(i) !== ')') || depth !== 0); i += 1) {
if (functionSource.charAt(index) === '=') {
for (; index < functionSource.length && ((functionSource.charAt(index) !== ',' && functionSource.charAt(index) !== ')') || depth !== 0); index += 1) {
// Skip all quotes
let wasQuote = false;

for (let j = 0; j < quotes.length; j += 1) {
if (functionSource.charAt(i) === quotes[j]) {
i += 1;
for (const quote of quotes) {
if (functionSource.charAt(index) === quote) {
index += 1;

for (; i < functionSource.length && functionSource.charAt(i) !== quotes[j];) {
i += 1;
for (; index < functionSource.length && functionSource.charAt(index) !== quote;) {
index += 1;
}

wasQuote = true;
Expand All @@ -49,7 +48,7 @@ module.exports = fn => {
continue;
}

switch (functionSource.charAt(i)) { // Keeps correct depths of all types of parenthesises
switch (functionSource.charAt(index)) { // Keeps correct depths of all types of parenthesises
case '(':
case '[':
case '{':
Expand All @@ -64,28 +63,28 @@ module.exports = fn => {
}
}

if (functionSource.charAt(i) === ',') {
fnNoDefaults += ',';
if (functionSource.charAt(index) === ',') {
functionWithNoDefaults += ',';
}

if (functionSource.charAt(i) === ')') { // Quits from the cycle immediately
fnNoDefaults += ')';
if (functionSource.charAt(index) === ')') { // Quits from the cycle immediately
functionWithNoDefaults += ')';
break;
}
} else {
fnNoDefaults += functionSource.charAt(i);
functionWithNoDefaults += functionSource.charAt(index);
}
}

if (i < functionSource.length && functionSource.charAt(i) === ')') {
fnNoDefaults += ')';
if (index < functionSource.length && functionSource.charAt(index) === ')') {
functionWithNoDefaults += ')';
}

// The first part matches parens-less arrow functions
// The second part matches the rest
const regexFnArguments = /^(?:async)?([^=()]+)=|\(([^)]+)\)/;

const match = regexFnArguments.exec(fnNoDefaults);
const match = regexFnArguments.exec(functionWithNoDefaults);

return match ? (match[1] || match[2]).split(',').map(x => x.trim()).filter(Boolean) : [];
};
}
16 changes: 6 additions & 10 deletions index.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
import {expectType} from 'tsd';
import functionArguments = require('.');
import functionArguments from './index.js';

expectType<string[]>(
functionArguments(function(foo: string, bar: number) {
return true;
})
functionArguments((_foo: string, _bar: number) => true),
);
expectType<string[]>(functionArguments((foo: string, bar: number) => true));
expectType<string[]>(functionArguments((_foo: string, _bar: number) => true));
expectType<string[]>(
functionArguments(function * (foo: string, bar: number) {
functionArguments(function * (_foo: string, _bar: number) { // eslint-disable-line require-yield
return true;
})
}),
);
expectType<string[]>(
functionArguments(async function(foo: string, bar: number) {
return true;
})
functionArguments(async (_foo: string, _bar: number) => true),
);
2 changes: 1 addition & 1 deletion license
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) Sindre Sorhus <[email protected]> (sindresorhus.com)
Copyright (c) Sindre Sorhus <[email protected]> (https://sindresorhus.com)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

Expand Down
24 changes: 10 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
"description": "Get the arguments of a function, arrow function, generator function, async function",
"license": "MIT",
"repository": "sindresorhus/fn-args",
"funding": "https://github.com/sponsors/sindresorhus",
"author": {
"name": "Sindre Sorhus",
"email": "[email protected]",
"url": "sindresorhus.com"
"url": "https://sindresorhus.com"
},
"type": "module",
"exports": "./index.js",
"engines": {
"node": ">=8"
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"scripts": {
"test": "xo && ava test.js && tsd"
Expand All @@ -30,22 +33,15 @@
"arrow"
],
"devDependencies": {
"ava": "^1.4.1",
"esm": "^3.2.22",
"semver": "^6.0.0",
"tsd": "^0.7.2",
"xo": "^0.24.0"
"ava": "^3.15.0",
"esm": "^3.2.25",
"semver": "^7.3.5",
"tsd": "^0.17.0",
"xo": "^0.44.0"
},
"xo": {
"ignores": [
"test*.js"
]
},
"ava": {
"babel": false,
"compileEnhancements": false,
"require": [
"esm"
]
}
}
9 changes: 1 addition & 8 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,16 @@

> Get the arguments of a function, arrow function, generator function, async function

## Install

```
$ npm install fn-args
```


## Usage

```js
const functionArguments = require('fn-args');
import functionArguments from 'fn-args';

functionArguments(function (foo, bar) {});
//=> ['foo', 'bar']
Expand All @@ -27,8 +25,3 @@ functionArguments(function * (foo, bar) {});
functionArguments(async function (foo, bar) {});
//=> ['foo', 'bar']
```


## License

MIT © [Sindre Sorhus](https://sindresorhus.com)
25 changes: 0 additions & 25 deletions test-newer.js

This file was deleted.

3 changes: 1 addition & 2 deletions test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import test from 'ava';
import semver from 'semver';
import functionArguments from '.';
import functionArguments from './index.js';

test('function', t => {
t.deepEqual(functionArguments(function (foo, bar) {}), ['foo', 'bar']);
Expand Down

0 comments on commit 62a47ef

Please sign in to comment.