Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix deepkeys to work with empty arrays and objects #105

Merged
merged 1 commit into from Apr 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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