From 62a47efb159f4c3e567da0a1c5713998bdf59dca Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 24 Aug 2021 02:05:09 +0200 Subject: [PATCH] Require Node.js 12.20 and move to ESM --- .github/workflows/main.yml | 7 ++--- index.d.ts | 8 +++--- index.js | 55 +++++++++++++++++++------------------- index.test-d.ts | 16 +++++------ license | 2 +- package.json | 24 +++++++---------- readme.md | 9 +------ test-newer.js | 25 ----------------- test.js | 3 +-- 9 files changed, 51 insertions(+), 98 deletions(-) delete mode 100644 test-newer.js diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 18531b3..441975c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -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 diff --git a/index.d.ts b/index.d.ts index 2fa279e..bfa4fcf 100644 --- a/index.d.ts +++ b/index.d.ts @@ -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'] @@ -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; diff --git a/index.js b/index.js index 9d36320..03d8e47 100644 --- a/index.js +++ b/index.js @@ -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; @@ -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 '{': @@ -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) : []; -}; +} diff --git a/index.test-d.ts b/index.test-d.ts index 5c7c9d1..9c07d58 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -1,19 +1,15 @@ import {expectType} from 'tsd'; -import functionArguments = require('.'); +import functionArguments from './index.js'; expectType( - functionArguments(function(foo: string, bar: number) { - return true; - }) + functionArguments((_foo: string, _bar: number) => true), ); -expectType(functionArguments((foo: string, bar: number) => true)); +expectType(functionArguments((_foo: string, _bar: number) => true)); expectType( - functionArguments(function * (foo: string, bar: number) { + functionArguments(function * (_foo: string, _bar: number) { // eslint-disable-line require-yield return true; - }) + }), ); expectType( - functionArguments(async function(foo: string, bar: number) { - return true; - }) + functionArguments(async (_foo: string, _bar: number) => true), ); diff --git a/license b/license index e7af2f7..fa7ceba 100644 --- a/license +++ b/license @@ -1,6 +1,6 @@ MIT License -Copyright (c) Sindre Sorhus (sindresorhus.com) +Copyright (c) Sindre Sorhus (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: diff --git a/package.json b/package.json index 7e122ac..2e482da 100644 --- a/package.json +++ b/package.json @@ -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": "sindresorhus@gmail.com", - "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" @@ -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" - ] } } diff --git a/readme.md b/readme.md index 2b1d5d5..748a951 100644 --- a/readme.md +++ b/readme.md @@ -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'] @@ -27,8 +25,3 @@ functionArguments(function * (foo, bar) {}); functionArguments(async function (foo, bar) {}); //=> ['foo', 'bar'] ``` - - -## License - -MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/test-newer.js b/test-newer.js deleted file mode 100644 index cc8d0e3..0000000 --- a/test-newer.js +++ /dev/null @@ -1,25 +0,0 @@ -'use strict'; -const test = require('ava'); -const functionArguments = require('.'); - -test('async function', t => { - t.deepEqual(functionArguments(async function (foo, bar) {}), ['foo', 'bar']); - t.deepEqual(functionArguments(async (foo, bar) => {}), ['foo', 'bar']); - t.deepEqual(functionArguments(async foo => {}), ['foo']); - - t.deepEqual(functionArguments(async ( - trailing, - comma, - ) => {}), ['trailing', 'comma']); - - t.deepEqual(functionArguments(async function /* something */may( - // go, - go, - /* wrong, */ - here - // (when, using, comments) {} - ){}), ['go', 'here']); - - t.deepEqual(functionArguments(async function () {}), []); - t.deepEqual(functionArguments(async function(){console.log('hello')}), []); -}); diff --git a/test.js b/test.js index 1ec0248..976bad5 100644 --- a/test.js +++ b/test.js @@ -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']);