Comparing version 1.5.0 to 2.1.0
@@ -64,5 +64,5 @@ /** | ||
if (error instanceof TypeError) { | ||
if (isNullPropertyAccessError(error)) { | ||
if (nullPattern.test(error)) { | ||
return null; | ||
} else if (isUndefinedPropertyAccessError(error)) { | ||
} else if (undefinedPattern.test(error)) { | ||
return undefined; | ||
@@ -75,28 +75,16 @@ } | ||
var nullPattern = void 0; | ||
function isNullPropertyAccessError(_ref) { | ||
var message = _ref.message; | ||
if (!nullPattern) { | ||
nullPattern = getInvalidPropertyAccessErrorPattern(null); | ||
} | ||
return nullPattern.test(message); | ||
} | ||
var undefinedPattern = void 0; | ||
function isUndefinedPropertyAccessError(_ref2) { | ||
var message = _ref2.message; | ||
if (!undefinedPattern) { | ||
undefinedPattern = getInvalidPropertyAccessErrorPattern(undefined); | ||
} | ||
return undefinedPattern.test(message); | ||
} | ||
/** | ||
* Use `new Function(...)` to avoid minifying "$object$" and "$property$". | ||
* Some actual error messages for null: | ||
* | ||
* TypeError: Cannot read property 'bar' of null | ||
* TypeError: Cannot convert null value to object | ||
* TypeError: foo is null | ||
* TypeError: null has no properties | ||
* TypeError: null is not an object (evaluating 'foo.bar') | ||
* TypeError: null is not an object (evaluating '(" undefined ", null).bar') | ||
*/ | ||
// eslint-disable-next-line no-new-func, flowtype/no-weak-types | ||
var getInvalidPropertyAccessErrorPattern = new Function('$object$', '\n try {\n $object$.$property$;\n } catch (error) {\n return new RegExp(\n error.message\n .replace(/[-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\\^\\$\\|]/g, \'\\\\$&\')\n .replace(\'\\\\$object\\\\$\', \'.+\')\n .replace(\'\\\\$property\\\\$\', \'.+\')\n );\n }\n throw new Error(\'Expected property access on \' + $object$ + \' to throw.\');\n'); | ||
var nullPattern = /^null | null$|^[^\(]* null /; | ||
var undefinedPattern = /^undefined | undefined$|^[^\(]* undefined /; | ||
idx.default = idx; | ||
module.exports = idx; |
{ | ||
"name": "idx", | ||
"version": "1.5.0", | ||
"version": "2.1.0", | ||
"description": "Utility function for traversing properties on objects and arrays.", | ||
@@ -5,0 +5,0 @@ "main": "lib/idx.js", |
@@ -9,8 +9,11 @@ # idx [![Circle Status](https://circleci.com/gh/facebookincubator/idx/tree/master.svg?style=shield&circle-token=da61f3cf105f22309c8ca0ba4482daa538bf5349)](https://circleci.com/gh/facebookincubator/idx) | ||
This module exists as a stop-gap solution because JavaScript does not currently | ||
support [optional chaining](https://github.com/tc39/proposal-optional-chaining). | ||
## Usage | ||
Consider the following type: | ||
Consider the following type for `props`: | ||
```javascript | ||
const props: { | ||
type User = { | ||
user: ?{ | ||
@@ -41,2 +44,16 @@ name: string, | ||
## Flow Type | ||
[Flow](https://flow.org/) understands the `idx` idiom: | ||
```javascript | ||
// @flow | ||
import idx from 'idx'; | ||
function getName(props: User): ?string { | ||
return idx(props, _ => _.user.name); | ||
} | ||
``` | ||
## Babel Transform | ||
@@ -46,14 +63,41 @@ | ||
behavior and is not meant to be executed. The `idx` function is used in | ||
conjunction with a Babel plugin that replaces it with better performing code: | ||
conjunction with a Babel plugin that replaces it with better performing code. | ||
This babel plugin searches for requires or imports to the `idx` module and | ||
replaces all its usages, so this code: | ||
```javascript | ||
props.user == null ? props.user : | ||
props.user.friends == null ? props.user.friends : | ||
props.user.friends[0] == null ? props.user.friends[0] : | ||
props.user.friends[0].friends | ||
import idx from 'idx'; | ||
function getFriends() { | ||
return idx(props, _ => _.user.friends[0].friends) | ||
}; | ||
``` | ||
All this machinery exists due to the fact that an existential operator does not | ||
currently exist in JavaScript. | ||
gets transformed to something like: | ||
```javascript | ||
function getFriends() { | ||
props.user == null ? props.user : | ||
props.user.friends == null ? props.user.friends : | ||
props.user.friends[0] == null ? props.user.friends[0] : | ||
return props.user.friends[0].friends | ||
} | ||
``` | ||
(note that the original `import` gets also removed). | ||
It's possible to customize the name of the import/require, so code that is not | ||
directly requiring the `idx` npm package can also get transformed: | ||
```javascript | ||
{ | ||
plugins: [ | ||
["babel-plugin-idx", { | ||
importName: './idx', | ||
}] | ||
] | ||
} | ||
``` | ||
## License | ||
@@ -60,0 +104,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
6154
104
83
1