Socket
Socket
Sign inDemoInstall

is-callable

Package Overview
Dependencies
0
Maintainers
1
Versions
18
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.1.5 to 1.2.0

.github/workflows/lint.yml

8

CHANGELOG.md

@@ -0,1 +1,9 @@

1.2.0 / 2020-06-02
=================
* [New] use `Reflect.apply`‑based callability detection
* [readme] add install instructions (#55)
* [meta] only run `aud` on prod deps
* [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `tape`, `make-arrow-function`, `make-generator-function`; add `aud`, `safe-publish-latest`, `make-async-function`
* [Tests] add tests for function proxies (#53, #25)
1.1.5 / 2019-12-18

@@ -2,0 +10,0 @@ =================

47

index.js
'use strict';
var fnToStr = Function.prototype.toString;
var reflectApply = typeof Reflect === 'object' && Reflect !== null && Reflect.apply;
var badArrayLike;
var isCallableMarker;
if (typeof reflectApply === 'function' && typeof Object.defineProperty === 'function') {
try {
badArrayLike = Object.defineProperty({}, 'length', {
get: function () {
throw isCallableMarker;
}
});
isCallableMarker = {};
} catch (_) {
reflectApply = null;
}
} else {
reflectApply = null;
}

@@ -29,10 +46,22 @@ var constructorRegex = /^\s*class\b/;

module.exports = function isCallable(value) {
if (!value) { return false; }
if (typeof value !== 'function' && typeof value !== 'object') { return false; }
if (typeof value === 'function' && !value.prototype) { return true; }
if (hasToStringTag) { return tryFunctionObject(value); }
if (isES6ClassFn(value)) { return false; }
var strClass = toStr.call(value);
return strClass === fnClass || strClass === genClass;
};
module.exports = reflectApply
? function isCallable(value) {
if (!value) { return false; }
if (typeof value !== 'function' && typeof value !== 'object') { return false; }
if (typeof value === 'function' && !value.prototype) { return true; }
try {
reflectApply(value, null, badArrayLike);
} catch (e) {
if (e !== isCallableMarker) { return false; }
}
return !isES6ClassFn(value);
}
: function isCallable(value) {
if (!value) { return false; }
if (typeof value !== 'function' && typeof value !== 'object') { return false; }
if (typeof value === 'function' && !value.prototype) { return true; }
if (hasToStringTag) { return tryFunctionObject(value); }
if (isES6ClassFn(value)) { return false; }
var strClass = toStr.call(value);
return strClass === fnClass || strClass === genClass;
};

23

package.json
{
"name": "is-callable",
"version": "1.1.5",
"version": "1.2.0",
"author": {

@@ -23,5 +23,6 @@ "name": "Jordan Harband",

"scripts": {
"prepublish": "safe-publish-latest",
"pretest": "npm run --silent lint",
"test": "npm run --silent tests-only",
"posttest": "npx aud",
"posttest": "npx aud --production",
"tests-only": "npm run --silent test:stock && npm run --silent test:staging",

@@ -59,13 +60,16 @@ "test:stock": "node test",

"devDependencies": {
"@ljharb/eslint-config": "^15.0.2",
"@ljharb/eslint-config": "^17.1.0",
"aud": "^1.1.2",
"covert": "^1.1.1",
"eclint": "^2.8.1",
"eslint": "^6.7.2",
"eslint": "^7.1.0",
"foreach": "^2.0.5",
"istanbul": "1.1.0-alpha.1",
"istanbul-merge": "^1.1.1",
"make-arrow-function": "^1.1.0",
"make-generator-function": "^1.1.0",
"make-arrow-function": "^1.2.0",
"make-async-function": "^1.0.0",
"make-generator-function": "^2.0.0",
"rimraf": "^2.7.1",
"tape": "^4.12.0"
"safe-publish-latest": "^1.1.4",
"tape": "^5.0.1"
},

@@ -92,3 +96,8 @@ "testling": {

"node": ">= 0.4"
},
"greenkeeper": {
"ignore": [
"rimraf"
]
}
}

@@ -42,3 +42,12 @@ # is-callable <sup>[![Version Badge][2]][1]</sup>

## Install
Install with
```
npm install is-callable
```
## Tests
Simply clone the repo, `npm install`, and run `npm test`

@@ -45,0 +54,0 @@

'use strict';
/* globals Proxy */
/* eslint no-magic-numbers: 1 */

@@ -8,12 +9,9 @@

var hasSymbols = typeof Symbol === 'function' && typeof Symbol('foo') === 'symbol';
var genFn = require('make-generator-function');
var arrowFn = require('make-arrow-function')();
var generators = require('make-generator-function')();
var arrows = require('make-arrow-function').list();
var asyncs = require('make-async-function').list();
var weirdlyCommentedArrowFn;
var asyncFn;
var asyncArrowFn;
try {
/* eslint-disable no-new-func */
weirdlyCommentedArrowFn = Function('return cl/*/**/=>/**/ass - 1;')();
asyncFn = Function('return async function foo() {};')();
asyncArrowFn = Function('return async () => {};')();
/* eslint-enable no-new-func */

@@ -34,2 +32,18 @@ } catch (e) { /**/ }

var proxy;
if (typeof Proxy === 'function') {
try {
proxy = new Proxy(function () {}, {});
// for coverage
proxy();
String(proxy);
} catch (_) {
// If `Reflect` is supported, then `Function.prototype.toString` isn't used for callability detection.
if (typeof Reflect !== 'object') {
// Older engines throw a `TypeError` when `Function.prototype.toString` is called on a Proxy object.
proxy = null;
}
}
}
var invokeFunction = function invokeFunctionString(str) {

@@ -137,9 +151,13 @@ var result;

test('Generators', { skip: !genFn }, function (t) {
t.ok(isCallable(genFn), 'generator function is callable');
test('Generators', { skip: generators.length === 0 }, function (t) {
forEach(generators, function (genFn) {
t.ok(isCallable(genFn), 'generator function ' + genFn + ' is callable');
});
t.end();
});
test('Arrow functions', { skip: !arrowFn }, function (t) {
t.ok(isCallable(arrowFn), 'arrow function is callable');
test('Arrow functions', { skip: arrows.length === 0 }, function (t) {
forEach(arrows, function (arrowFn) {
t.ok(isCallable(arrowFn), 'arrow function ' + arrowFn + ' is callable');
});
t.ok(isCallable(weirdlyCommentedArrowFn), 'weirdly commented arrow functions are callable');

@@ -158,6 +176,12 @@ t.end();

test('`async function`s', { skip: !asyncFn }, function (t) {
t.ok(isCallable(asyncFn), '`async function`s are callable');
t.ok(isCallable(asyncArrowFn), '`async` arrow functions are callable');
test('`async function`s', { skip: asyncs.length === 0 }, function (t) {
forEach(asyncs, function (asyncFn) {
t.ok(isCallable(asyncFn), '`async function` ' + asyncFn + ' is callable');
});
t.end();
});
test('proxies of functions', { skip: !proxy }, function (t) {
t.ok(isCallable(proxy), 'proxies of functions are callable');
t.end();
});

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc