Skip to content

Commit

Permalink
Require Node.js 8
Browse files Browse the repository at this point in the history
  • Loading branch information
sindresorhus committed Apr 6, 2019
1 parent 5dbf51c commit a19fd41
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 99 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,3 @@ language: node_js
node_js:
- '10'
- '8'
- '6'
53 changes: 23 additions & 30 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
declare const dotProp: {
/**
@param obj - Object to get the `path` value.
@param path - Path of the property in the object, using `.` to separate each nested key.
Use `\\.` if you have a `.` in the key.
@param object - Object to get the `path` value.
@param path - Path of the property in the object, using `.` to separate each nested key. Use `\\.` if you have a `.` in the key.
@param defaultValue - Default value.
@example
Expand All @@ -24,47 +22,44 @@ declare const dotProp: {
```
*/
get<T = unknown>(
obj: {[key: string]: unknown},
object: {[key: string]: unknown},
path: string,
defaultValue?: T
): T;

/**
@param obj - Object to set the `path` value.
@param path - Path of the property in the object, using `.` to separate each nested key.
Use `\\.` if you have a `.` in the key.
@param object - Object to set the `path` value.
@param path - Path of the property in the object, using `.` to separate each nested key. Use `\\.` if you have a `.` in the key.
@param value - Value to set at `path`.
@example
```
import dotProp = require('dot-prop');
const obj = {foo: {bar: 'a'}};
dotProp.set(obj, 'foo.bar', 'b');
console.log(obj);
const object = {foo: {bar: 'a'}};
dotProp.set(object, 'foo.bar', 'b');
console.log(object);
//=> {foo: {bar: 'b'}}
const foo = dotProp.set({}, 'foo.bar', 'c');
console.log(foo);
//=> {foo: {bar: 'c'}}
dotProp.set(obj, 'foo.baz', 'x');
console.log(obj);
dotProp.set(object, 'foo.baz', 'x');
console.log(object);
//=> {foo: {bar: 'b', baz: 'x'}}
```
*/
set<T extends {[key: string]: unknown}>(
obj: T,
object: T,
path: string,
value: unknown
): T;

/**
@param obj - Object to test the `path` value.
@param path - Path of the property in the object, using `.` to separate each nested key.
@param object - Object to test the `path` value.
@param path - Path of the property in the object, using `.` to separate each nested key. Use `\\.` if you have a `.` in the key.
Use `\\.` if you have a `.` in the key.
@example
```
import dotProp = require('dot-prop');
Expand All @@ -73,30 +68,28 @@ declare const dotProp: {
//=> true
```
*/
has(obj: {[key: string]: unknown}, path: string): boolean;
has(object: {[key: string]: unknown}, path: string): boolean;

/**
@param obj Object to delete the `path` value.
@param path - Path of the property in the object, using `.` to separate each nested key.
Use `\\.` if you have a `.` in the key.
@param object Object to delete the `path` value.
@param path - Path of the property in the object, using `.` to separate each nested key. Use `\\.` if you have a `.` in the key.
@example
```
import dotProp = require('dot-prop');
const obj = {foo: {bar: 'a'}};
dotProp.delete(obj, 'foo.bar');
console.log(obj);
const object = {foo: {bar: 'a'}};
dotProp.delete(object, 'foo.bar');
console.log(object);
//=> {foo: {}}
obj.foo.bar = {x: 'y', y: 'x'};
dotProp.delete(obj, 'foo.bar.x');
console.log(obj);
object.foo.bar = {x: 'y', y: 'x'};
dotProp.delete(object, 'foo.bar.x');
console.log(object);
//=> {foo: {bar: {y: 'x'}}}
```
*/
delete(obj: {[key: string]: unknown}, path: string): void;
delete(object: {[key: string]: unknown}, path: string): void;
};

export = dotProp;
90 changes: 45 additions & 45 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
const isObj = require('is-obj');

function getPathSegments(path) {
const pathArr = path.split('.');
const pathArray = path.split('.');
const parts = [];

for (let i = 0; i < pathArr.length; i++) {
let p = pathArr[i];
for (let i = 0; i < pathArray.length; i++) {
let p = pathArray[i];

while (p[p.length - 1] === '\\' && pathArr[i + 1] !== undefined) {
while (p[p.length - 1] === '\\' && pathArray[i + 1] !== undefined) {
p = p.slice(0, -1) + '.';
p += pathArr[++i];
p += pathArray[++i];
}

parts.push(p);
Expand All @@ -20,99 +20,99 @@ function getPathSegments(path) {
}

module.exports = {
get(obj, path, value) {
if (!isObj(obj) || typeof path !== 'string') {
return value === undefined ? obj : value;
get(object, path, value) {
if (!isObj(object) || typeof path !== 'string') {
return value === undefined ? object : value;
}

const pathArr = getPathSegments(path);
const pathArray = getPathSegments(path);

for (let i = 0; i < pathArr.length; i++) {
if (!Object.prototype.propertyIsEnumerable.call(obj, pathArr[i])) {
for (let i = 0; i < pathArray.length; i++) {
if (!Object.prototype.propertyIsEnumerable.call(object, pathArray[i])) {
return value;
}

obj = obj[pathArr[i]];
object = object[pathArray[i]];

if (obj === undefined || obj === null) {
// `obj` is either `undefined` or `null` so we want to stop the loop, and
if (object === undefined || object === null) {
// `object` is either `undefined` or `null` so we want to stop the loop, and
// if this is not the last bit of the path, and
// if it did't return `undefined`
// it would return `null` if `obj` is `null`
// it would return `null` if `object` is `null`
// but we want `get({foo: null}, 'foo.bar')` to equal `undefined`, or the supplied value, not `null`
if (i !== pathArr.length - 1) {
if (i !== pathArray.length - 1) {
return value;
}

break;
}
}

return obj;
return object;
},

set(obj, path, value) {
if (!isObj(obj) || typeof path !== 'string') {
return obj;
set(object, path, value) {
if (!isObj(object) || typeof path !== 'string') {
return object;
}

const root = obj;
const pathArr = getPathSegments(path);
const root = object;
const pathArray = getPathSegments(path);

for (let i = 0; i < pathArr.length; i++) {
const p = pathArr[i];
for (let i = 0; i < pathArray.length; i++) {
const p = pathArray[i];

if (!isObj(obj[p])) {
obj[p] = {};
if (!isObj(object[p])) {
object[p] = {};
}

if (i === pathArr.length - 1) {
obj[p] = value;
if (i === pathArray.length - 1) {
object[p] = value;
}

obj = obj[p];
object = object[p];
}

return root;
},

delete(obj, path) {
if (!isObj(obj) || typeof path !== 'string') {
delete(object, path) {
if (!isObj(object) || typeof path !== 'string') {
return;
}

const pathArr = getPathSegments(path);
const pathArray = getPathSegments(path);

for (let i = 0; i < pathArr.length; i++) {
const p = pathArr[i];
for (let i = 0; i < pathArray.length; i++) {
const p = pathArray[i];

if (i === pathArr.length - 1) {
delete obj[p];
if (i === pathArray.length - 1) {
delete object[p];
return;
}

obj = obj[p];
object = object[p];

if (!isObj(obj)) {
if (!isObj(object)) {
return;
}
}
},

has(obj, path) {
if (!isObj(obj) || typeof path !== 'string') {
has(object, path) {
if (!isObj(object) || typeof path !== 'string') {
return false;
}

const pathArr = getPathSegments(path);
const pathArray = getPathSegments(path);

for (let i = 0; i < pathArr.length; i++) {
if (isObj(obj)) {
if (!(pathArr[i] in obj)) {
for (let i = 0; i < pathArray.length; i++) {
if (isObj(object)) {
if (!(pathArray[i] in object)) {
return false;
}

obj = obj[pathArr[i]];
object = object[pathArray[i]];
} else {
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions index.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ expectType<unknown>(
dotProp.get({foo: {'dot.dot': 'unicorn'}}, 'foo.dot\\.dot')
);

const obj = {foo: {bar: 'a'}};
expectType<typeof obj>(dotProp.set(obj, 'foo.bar', 'b'));
const object = {foo: {bar: 'a'}};
expectType<typeof object>(dotProp.set(object, 'foo.bar', 'b'));

expectType<boolean>(dotProp.has({foo: {bar: 'unicorn'}}, 'foo.bar'));

Expand Down
4 changes: 1 addition & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"url": "sindresorhus.com"
},
"engines": {
"node": ">=6"
"node": ">=8"
},
"scripts": {
"test": "xo && ava && tsd",
Expand All @@ -21,7 +21,6 @@
"index.d.ts"
],
"keywords": [
"obj",
"object",
"prop",
"property",
Expand All @@ -30,7 +29,6 @@
"get",
"set",
"delete",
"del",
"access",
"notation",
"dotty"
Expand Down
36 changes: 18 additions & 18 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,49 +29,49 @@ dotProp.get({foo: {'dot.dot': 'unicorn'}}, 'foo.dot\\.dot');
//=> 'unicorn'

// Setter
const obj = {foo: {bar: 'a'}};
dotProp.set(obj, 'foo.bar', 'b');
console.log(obj);
const object = {foo: {bar: 'a'}};
dotProp.set(object, 'foo.bar', 'b');
console.log(object);
//=> {foo: {bar: 'b'}}

const foo = dotProp.set({}, 'foo.bar', 'c');
console.log(foo);
//=> {foo: {bar: 'c'}}

dotProp.set(obj, 'foo.baz', 'x');
console.log(obj);
dotProp.set(object, 'foo.baz', 'x');
console.log(object);
//=> {foo: {bar: 'b', baz: 'x'}}

// Has
dotProp.has({foo: {bar: 'unicorn'}}, 'foo.bar');
//=> true

// Deleter
const obj = {foo: {bar: 'a'}};
dotProp.delete(obj, 'foo.bar');
console.log(obj);
const object = {foo: {bar: 'a'}};
dotProp.delete(object, 'foo.bar');
console.log(object);
//=> {foo: {}}

obj.foo.bar = {x: 'y', y: 'x'};
dotProp.delete(obj, 'foo.bar.x');
console.log(obj);
object.foo.bar = {x: 'y', y: 'x'};
dotProp.delete(object, 'foo.bar.x');
console.log(object);
//=> {foo: {bar: {y: 'x'}}}
```


## API

### get(obj, path, [defaultValue])
### get(object, path, [defaultValue])

### set(obj, path, value)
### set(object, path, value)

Returns the object.

### has(obj, path)
### has(object, path)

### delete(obj, path)
### delete(object, path)

#### obj
#### object

Type: `Object`

Expand All @@ -87,13 +87,13 @@ Use `\\.` if you have a `.` in the key.

#### value

Type: `any`
Type: `unknown`

Value to set at `path`.

#### defaultValue

Type: `any`
Type: `unknown`

Default value.

Expand Down

0 comments on commit a19fd41

Please sign in to comment.