Skip to content

Commit

Permalink
fix deepkeys to work with empty arrays and objects
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex Kostyukov committed Apr 20, 2023
1 parent 7cfa81f commit 434c09f
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 3 deletions.
6 changes: 5 additions & 1 deletion index.d.ts
Expand Up @@ -133,7 +133,7 @@ console.log(getProperty(object, escapedPath));
export function escapePath(path: string): string;

/**
Returns an array of every path. Plain objects are deeply recursed and are not themselves included.
Returns an array of every path. Non-empty plain objects and arrays are deeply recursed and are not themselves included.
This can be useful to help flatten an object for an API that only accepts key-value pairs or for a tagged template literal.
Expand All @@ -148,12 +148,16 @@ const user = {
first: 'Richie',
last: 'Bendall',
},
activeTasks: [],
currentProject: null
};
for (const property of deepKeys(user)) {
console.log(`${property}: ${getProperty(user, property)}`);
//=> name.first: Richie
//=> name.last: Bendall
//=> activeTasks: []
//=> currentProject: null
}
```
*/
Expand Down
4 changes: 3 additions & 1 deletion index.js
Expand Up @@ -3,6 +3,8 @@ const isObject = value => {
return value !== null && (type === 'object' || type === 'function');
};

const isEmptyObject = value => isObject(value) && Object.keys(value).length === 0;

const disallowedKeys = new Set([
'__proto__',
'prototype',
Expand Down Expand Up @@ -316,7 +318,7 @@ function stringifyPath(pathSegments) {
}

function * deepKeysIterator(object, currentPath = []) {
if (!isObject(object)) {
if (!isObject(object) || isEmptyObject(object)) {
if (currentPath.length > 0) {
yield stringifyPath(currentPath);
}
Expand Down
6 changes: 5 additions & 1 deletion readme.md
Expand Up @@ -110,7 +110,7 @@ console.log(getProperty(object, escapedPath));

### deepKeys(object)

Returns an array of every path. Plain objects are deeply recursed and are not themselves included.
Returns an array of every path. Non-empty plain objects and arrays are deeply recursed and are not themselves included.

This can be useful to help flatten an object for an API that only accepts key-value pairs or for a tagged template literal.

Expand All @@ -122,12 +122,16 @@ const user = {
first: 'Richie',
last: 'Bendall',
},
activeTasks: [],
currentProject: null
};

for (const property of deepKeys(user)) {
console.log(`${property}: ${getProperty(user, property)}`);
//=> name.first: Richie
//=> name.last: Bendall
//=> activeTasks: []
//=> currentProject: null
}
```

Expand Down
14 changes: 14 additions & 0 deletions test.js
Expand Up @@ -413,13 +413,20 @@ test('escapePath', t => {

test('deepKeys', t => {
const object = {
eo: {},
ea: [],
'a.b': {
c: {
d: [1, 2, {
g: 3,
}],
e: '🦄',
f: 0,
h: {},
i: [],
nu: null,
na: Number.NaN,
un: undefined,
},
'': {
a: 0,
Expand All @@ -432,11 +439,18 @@ test('deepKeys', t => {
const keys = deepKeys(object);

t.deepEqual(keys, [
'eo',
'ea',
'a\\.b.c.d[0]',
'a\\.b.c.d[1]',
'a\\.b.c.d[2].g',
'a\\.b.c.e',
'a\\.b.c.f',
'a\\.b.c.h',
'a\\.b.c.i',
'a\\.b.c.nu',
'a\\.b.c.na',
'a\\.b.c.un',
'a\\.b..a',
'.a',
]);
Expand Down

0 comments on commit 434c09f

Please sign in to comment.