https://github.com/blakek/deep
๐ก Get, set, remove, and test for deeply nested properties
https://github.com/blakek/deep
deep get getters javascript nested-properties properties setter typescript
Last synced: 29 days ago
JSON representation
๐ก Get, set, remove, and test for deeply nested properties
- Host: GitHub
- URL: https://github.com/blakek/deep
- Owner: blakek
- License: mit
- Created: 2020-06-02T15:04:49.000Z (almost 5 years ago)
- Default Branch: main
- Last Pushed: 2023-01-06T07:42:37.000Z (over 2 years ago)
- Last Synced: 2025-04-18T09:34:21.478Z (about 1 month ago)
- Topics: deep, get, getters, javascript, nested-properties, properties, setter, typescript
- Language: TypeScript
- Homepage:
- Size: 643 KB
- Stars: 2
- Watchers: 2
- Forks: 3
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# deep
> ๐ก Get, set, remove, and test for deeply nested properties
Helps you safely work with nested properties.
## Install
Using [Yarn]:
```bash
$ yarn add @blakek/deep
```โฆor using [npm]:
```bash
$ npm i --save @blakek/deep
```## Usage
```js
import {
clone,
createGetter,
get,
has,
omit,
pluck,
remove,
set
// also available:
// - createHas
// - createOmit
// - createPluck
// - createRemove
// - createSetter
// - isObject
// - traverseObject
} from '@blakek/deep';const user = {
id: 'abf87de',
roles: ['alert:create', 'alert:read'],
sites: {
github: {
username: 'blakek'
}
}
};// Deeply clone most values
const userCopy = clone(user);
user === userCopy; //ยป false
user.id === userCopy.id; //ยป true
user.roles === userCopy.roles; //ยป false
user.roles[0] === userCopy.roles[0]; //ยป true// Get a property value
get('sites.github.username', user); //ยป 'blakek'// Get a property value with a fallback other than `undefined`
get('sites.facebook.username', user, 'no-account'); //ยป 'no-account'// Create a function to get a property value later
const getUsername = createGetter('sites.github.username');
getUsername(user); //ยป 'blakek'// Test for a property value
has('sites.github', user); //ยป true// Clone an object and omit properties
omit(['roles', 'sites'], user); //ยป { id: 'abf87de' }// Pluck a subset of properties
pluck(['id', 'roles'], user);
//ยป { id: 'abf87de', roles: [ 'alert:create', 'alert:read' ] }// Remove a property value, modifying the current object
remove('a', { a: 42, b: 123 }); //ยป { b: 123 }// Set a property value, modifying the current object
set(123, 'a.b.c', { a: 42 }); //ยป { a: { b: { c: 123 } } }
```## API
For all these:
- `path` can be either a dot-notation string or array of path parts
### `clone`
Returns a deep clone / deep copy of most values: primitive values, objects, arrays, Map, Set, Date, etc.
```ts
function clone(value: T): T;
``````js
const object = { value: 'yep' };
const cloned = clone(object);cloned === object; //ยป false
cloned.value === object.value; //ยป true
```### `get` / `createGetter`
Gets the value for a given path with an optional fallback value.
```ts
function get(path: Path, object: object, fallbackValue?: any): unknown;function createGetter(
path: Path,
fallbackValue?: any
): (object: object) => unknown;
``````js
const user = {
id: 'abf87de',
roles: ['alert:create', 'alert:read'],
sites: {
github: {
username: 'blakek'
}
}
};get('id', user); //ยป 'abf87de'
get('roles.0', user); //ยป 'alert:create'
get('roles[0]', user); //ยป 'alert:create'
get(['roles', 1], user); //ยป 'alert:read'
get('sites.github.username', user); //ยป 'blakek'
get('sites.github.avatar.src', user, 'default.png'); //ยป 'default.png'const getID = get('id');
getID(user); //ยป 'abf87de'const getRoles = createGetter('roles');
getRoles(user); //ยป ['alert:create', 'alert:read']
```### `has` / `createHas`
Returns `true` if a value was found at the given path or `false` if nothing was
found.```ts
function has(path: Path, object: any): boolean;function createHas(path: Path): (object: any) => boolean;
``````js
const product = {
id: 'abf87de',
name: 'Logo T-Shirt',
attributes: {
isCool: undefined,
materials: ['cotton']
}
};has('attributes.materials', product); //ยป true
has(['avability', 'sizes'], product); //ยป false
has('attributes.isCool', product); //ยป true; property exists but is undefinedconst hasMaterials = createHas('attributes.materials');
hasMaterials(product); //ยป true// NOTE: `get()` should be used if you want to ensure a value is not `undefined`
get('attributes.isCool', product, false); //ยป false
```### `omit` / `createOmit`
Returns a clone of an object with a list of properties removed.
Note: `omit()` returns a clone with properties removed. If you'd rather modify
the existing object for performance, consider using `remove()`.```ts
function omit(properties: Path[], object: any): any;function createOmit(properties: Path[]): (object: any) => any;
``````js
const user = {
username: 'blakek',
roles: ['alert:create', 'alert:read'],
sites: {
github: {
username: 'blakek'
}
}
};omit(['roles', 'sites'], user); //ยป { username: 'blakek' }
omit(['username', 'roles', 'sites.doesnt.exist'], user);
//ยป { sites: { github: { username: 'blakek' } } }const omitExtra = createOmit(['roles, sites']);
omitExtra(user); //ยป { username: 'blakek' }
```### `pluck` / `createPluck`
Gets a subset of properties from an object.
```ts
function pluck(properties: Path[], object: any): any;
``````js
const user = {
username: 'blakek',
roles: ['alert:create', 'alert:read'],
sites: {
github: {
username: 'blakek'
}
}
};pluck(['username'], user); //ยป { username: 'blakek' }
pluck(['username', 'roles'], user);
//ยป { username: 'blakek', roles: [ 'alert:create', 'alert:read' ] }const permissionInfo = pluck(['roles', 'username']);
permissionInfo(user); //ยป { roles: [ 'alert:create', 'alert:read' ], username: 'blakek' }
```### `remove` / `createRemove`
Removes a value at a path and returns the object.
Note: `remove()` modifies the passed-in object rather than creating a copy. If
you'd rather return a new object:- use `omit()`; `omit()` returns a clone with a list of properties removed
- use `clone()` before `remove()`
- consider another solution ([unchanged] is really good)```ts
function remove(path: Path, object: any): any;function createRemove(path: Path): (object: any) => any;
``````js
const user = {
username: 'blakek',
password: 'wouldntyouliketoknow'
};remove('password', user); //ยป { username: 'blakek' }
remove('property.does.not.exist', user);
//ยป { username: 'blakek' } (same object from previous line)const removePassword = createRemove('password');
removePassword({ username: 'bob', password: 'laskjfl' }); //ยป { username: 'bob' }
```### `set` / `createSetter`
Sets a value at a path and returns the object.
Note: `set()` modifies the passed-in object rather than creating a copy. If
you'd rather return a new object:- use `clone()` before `set()`
- consider another solution ([unchanged] is really good)```ts
function set(value: any, path: Path, object: any): any;function createSetter(path: Path, object: any): (value: any) => any;
``````js
const user = {
profile: {
bgColor: '#639'
}
};set('tomato', 'profile.bgColor', user); //ยป { profile: { bgColor: 'tomato' } }
set('/images/user.png', 'profile.bgImage', user);
//ยป { profile: { bgColor: 'tomato', bgImage: '/images/user.png' } }const logout = set(null, 'profile');
logout(user); //ยป { profile: null }const setUsername = createSetter('username', user);
setUsername('blakek'); //ยป { profile: { bgColor: 'tomato', bgImage: '/images/user.png' }, username: 'blakek' }
```## Contributing
[Node.js] and [Yarn] are required to work with this project.
To install all dependencies, run:
```bash
yarn
```### Useful Commands
| | |
| ------------------- | ----------------------------------------------- |
| `yarn build` | Builds the project to `./dist` |
| `yarn format` | Format the source following the Prettier styles |
| `yarn test` | Run project tests |
| `yarn test --watch` | Run project tests, watching for file changes |## License
MIT
[node.js]: https://nodejs.org/
[npm]: https://npmjs.com/
[unchanged]: https://github.com/planttheidea/unchanged
[yarn]: https://yarnpkg.com/en/docs/