@blakek/deep
Advanced tools
Comparing version 2.1.1 to 2.2.0
@@ -15,2 +15,43 @@ 'use strict'; | ||
const NotFound = Symbol('curriable placeholder'); | ||
function clone(value) { | ||
if (value instanceof Date) { | ||
return new Date(value.getTime()); | ||
} | ||
if (value instanceof Map) { | ||
const result = new Map(); | ||
value.forEach((value, key) => { | ||
result.set(key, clone(value)); | ||
}); | ||
return result; | ||
} | ||
if (value instanceof RegExp) { | ||
return new RegExp(value.source, value.flags); | ||
} | ||
if (value instanceof Set) { | ||
const result = new Set(); | ||
value.forEach(x => { | ||
result.add(clone(x)); | ||
}); | ||
return result; | ||
} | ||
if (typeof value === 'object') { | ||
if (value === null) { | ||
return null; | ||
} | ||
const result = Array.isArray(value) ? [] : {}; | ||
for (const key in value) { | ||
result[key] = clone(value[key]); | ||
} | ||
return result; | ||
} | ||
return value; | ||
} | ||
function traverseObject(object, path) { | ||
@@ -66,2 +107,8 @@ // If the path has been exhausted, return the current object | ||
function _omit(properties, object) { | ||
const cloned = clone(object); | ||
properties.forEach(property => remove(property, cloned)); | ||
return cloned; | ||
} | ||
function _pluck(properties, object) { | ||
@@ -92,2 +139,3 @@ return properties.reduce((subset, property) => _set(_get(property, object), property, subset), {}); | ||
const has = curry.curry(_has); | ||
const omit = curry.curry(_omit); | ||
const pluck = curry.curry(_pluck); | ||
@@ -97,5 +145,7 @@ const remove = curry.curry(_remove); | ||
exports.clone = clone; | ||
exports.get = get; | ||
exports.getOr = getOr; | ||
exports.has = has; | ||
exports.omit = omit; | ||
exports.pluck = pluck; | ||
@@ -102,0 +152,0 @@ exports.remove = remove; |
export declare type Path = Array<number | string> | string; | ||
export declare type ObjectLike = Record<keyof unknown, unknown>; | ||
export declare type WithProperties = ObjectLike | unknown[]; | ||
export declare function clone<T extends unknown>(value: T): T; | ||
export declare function traverseObject(object: any, path: string[]): any; | ||
@@ -6,4 +9,5 @@ export declare const get: import("@blakek/curry").Curry2<Path, any, any>; | ||
export declare const has: import("@blakek/curry").Curry2<Path, any, boolean>; | ||
export declare const omit: import("@blakek/curry").Curry2<Path[], WithProperties, WithProperties>; | ||
export declare const pluck: import("@blakek/curry").Curry2<Path[], any, any>; | ||
export declare const remove: import("@blakek/curry").Curry2<Path, any, any>; | ||
export declare const set: import("@blakek/curry").Curry3<any, Path, any, any>; |
@@ -11,2 +11,43 @@ import { curry } from '@blakek/curry'; | ||
const NotFound = Symbol('curriable placeholder'); | ||
function clone(value) { | ||
if (value instanceof Date) { | ||
return new Date(value.getTime()); | ||
} | ||
if (value instanceof Map) { | ||
const result = new Map(); | ||
value.forEach((value, key) => { | ||
result.set(key, clone(value)); | ||
}); | ||
return result; | ||
} | ||
if (value instanceof RegExp) { | ||
return new RegExp(value.source, value.flags); | ||
} | ||
if (value instanceof Set) { | ||
const result = new Set(); | ||
value.forEach(x => { | ||
result.add(clone(x)); | ||
}); | ||
return result; | ||
} | ||
if (typeof value === 'object') { | ||
if (value === null) { | ||
return null; | ||
} | ||
const result = Array.isArray(value) ? [] : {}; | ||
for (const key in value) { | ||
result[key] = clone(value[key]); | ||
} | ||
return result; | ||
} | ||
return value; | ||
} | ||
function traverseObject(object, path) { | ||
@@ -62,2 +103,8 @@ // If the path has been exhausted, return the current object | ||
function _omit(properties, object) { | ||
const cloned = clone(object); | ||
properties.forEach(property => remove(property, cloned)); | ||
return cloned; | ||
} | ||
function _pluck(properties, object) { | ||
@@ -88,2 +135,3 @@ return properties.reduce((subset, property) => _set(_get(property, object), property, subset), {}); | ||
const has = curry(_has); | ||
const omit = curry(_omit); | ||
const pluck = curry(_pluck); | ||
@@ -93,2 +141,2 @@ const remove = curry(_remove); | ||
export { get, getOr, has, pluck, remove, set, traverseObject }; | ||
export { clone, get, getOr, has, omit, pluck, remove, set, traverseObject }; |
@@ -1,2 +0,2 @@ | ||
!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):r((e=e||self).deep={})}(this,(function(e){"use strict";function r(e,r){return void 0===r&&(r=e.length),function n(){for(var t=arguments.length,u=new Array(t),i=0;i<t;i++)u[i]=arguments[i];return u.length>=r?e.apply(void 0,u.slice(0,r)):function(){for(var e=arguments.length,r=new Array(e),t=0;t<e;t++)r[t]=arguments[t];return n.apply(void 0,u.concat(r))}}}var n={clear:function(){n.results={},n.size=0},results:{},size:0},t=/"[^"]+"|`[^`]+`|'[^']+'|[^.[\]]+/g,u=/^\d+$/i,i=/^"[^"]+"|`[^`]+`|'[^']+'$/,o=function(e,r){for(var n=e.length,t=[],u=0;u<n;u++)t[u]=r(e[u]);return t},f=function(e){var r=function(e){return i.test(e)}(e)?e.slice(1,e.length-1):e;return function(e){return!(!e||!e.length)&&u.test(e)}(r)?+r:r},c=Array.isArray,l=function(e){if("string"==typeof e)return function(e){return n.results[e]||(n.size>500&&n.clear(),n.results[e]=e?o(e.match(t),f):[e],n.size++),n.results[e]}(e);if(c(e))return o(e,f);var r=f(e);return["number"==typeof r?r:""+r]};function s(e){if(null===e)return!1;var r=typeof e;return"object"===r||"function"===r}var a=Symbol("curriable placeholder");function v(e,r){if(0===r.length)return e;if(!s(e))return a;var n=r[0],t=r.slice(1);return n in e?v(e[n],t):a}function d(e,r,n){if(void 0===r)return n;var t=v(n,l(r));return t===a||void 0===t?e:t}var p=function(e,r){return d(void 0,e,r)};function h(e,r,n){var t=l(r),u=n;return t.forEach((function(r,n){n!==t.length-1?(s(u[r])||(u[r]={}),u=u[r]):u[r]=e})),n}var g=r(p),y=r(d),b=r((function(e,r){return v(r,l(e))!==a})),m=r((function(e,r){return e.reduce((function(e,n){return h(p(n,r),n,e)}),{})})),j=r((function(e,r){if(void 0===e)return r;var n=l(e),t=n.slice(0,-1),u=n[n.length-1],i=v(r,l(t));return i?(delete i[u],r):r})),z=r(h);e.get=g,e.getOr=y,e.has=b,e.pluck=m,e.remove=j,e.set=z,e.traverseObject=v,Object.defineProperty(e,"__esModule",{value:!0})})); | ||
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).deep={})}(this,(function(e){"use strict";function n(e,n){return void 0===n&&(n=e.length),function r(){for(var t=arguments.length,u=new Array(t),i=0;i<t;i++)u[i]=arguments[i];return u.length>=n?e.apply(void 0,u.slice(0,n)):function(){for(var e=arguments.length,n=new Array(e),t=0;t<e;t++)n[t]=arguments[t];return r.apply(void 0,u.concat(n))}}}var r={clear:function(){r.results={},r.size=0},results:{},size:0},t=/"[^"]+"|`[^`]+`|'[^']+'|[^.[\]]+/g,u=/^\d+$/i,i=/^"[^"]+"|`[^`]+`|'[^']+'$/,o=function(e,n){for(var r=e.length,t=[],u=0;u<r;u++)t[u]=n(e[u]);return t},f=function(e){var n=function(e){return i.test(e)}(e)?e.slice(1,e.length-1):e;return function(e){return!(!e||!e.length)&&u.test(e)}(n)?+n:n},c=Array.isArray,a=function(e){if("string"==typeof e)return function(e){return r.results[e]||(r.size>500&&r.clear(),r.results[e]=e?o(e.match(t),f):[e],r.size++),r.results[e]}(e);if(c(e))return o(e,f);var n=f(e);return["number"==typeof n?n:""+n]};function l(e){if(null===e)return!1;var n=typeof e;return"object"===n||"function"===n}var s=Symbol("curriable placeholder");function v(e){if(e instanceof Date)return new Date(e.getTime());if(e instanceof Map){var n=new Map;return e.forEach((function(e,r){n.set(r,v(e))})),n}if(e instanceof RegExp)return new RegExp(e.source,e.flags);if(e instanceof Set){var r=new Set;return e.forEach((function(e){r.add(v(e))})),r}if("object"==typeof e){if(null===e)return null;var t=Array.isArray(e)?[]:{};for(var u in e)t[u]=v(e[u]);return t}return e}function d(e,n){if(0===n.length)return e;if(!l(e))return s;var r=n[0],t=n.slice(1);return r in e?d(e[r],t):s}function p(e,n,r){if(void 0===n)return r;var t=d(r,a(n));return t===s||void 0===t?e:t}var g=function(e,n){return p(void 0,e,n)};function h(e,n,r){var t=a(n),u=r;return t.forEach((function(n,r){r!==t.length-1?(l(u[n])||(u[n]={}),u=u[n]):u[n]=e})),r}var y=n(g),b=n(p),m=n((function(e,n){return d(n,a(e))!==s})),w=n((function(e,n){var r=v(n);return e.forEach((function(e){return E(e,r)})),r})),A=n((function(e,n){return e.reduce((function(e,r){return h(g(r,n),r,e)}),{})})),E=n((function(e,n){if(void 0===e)return n;var r=a(e),t=r.slice(0,-1),u=r[r.length-1],i=d(n,a(t));return i?(delete i[u],n):n})),j=n(h);e.clone=v,e.get=y,e.getOr=b,e.has=m,e.omit=w,e.pluck=A,e.remove=E,e.set=j,e.traverseObject=d,Object.defineProperty(e,"__esModule",{value:!0})})); | ||
//# sourceMappingURL=index.umd.js.map |
{ | ||
"name": "@blakek/deep", | ||
"version": "2.1.1", | ||
"version": "2.2.0", | ||
"main": "dist/index.cjs.js", | ||
@@ -39,4 +39,3 @@ "module": "dist/index.esm.js", | ||
"files": [ | ||
"src/**/*.test.js", | ||
"src/**/*.test.ts" | ||
"tests/**/*.test.ts" | ||
], | ||
@@ -60,22 +59,22 @@ "ignoredByWatcher": [ | ||
"devDependencies": { | ||
"@babel/core": "^7.10.2", | ||
"@babel/plugin-proposal-class-properties": "^7.10.1", | ||
"@babel/plugin-transform-runtime": "^7.10.1", | ||
"@babel/preset-env": "^7.10.2", | ||
"@babel/preset-typescript": "^7.10.1", | ||
"@rollup/plugin-babel": "^5.0.3", | ||
"@rollup/plugin-commonjs": "^13.0.0", | ||
"@rollup/plugin-node-resolve": "^8.0.1", | ||
"@typescript-eslint/eslint-plugin": "^3.2.0", | ||
"@typescript-eslint/parser": "^3.2.0", | ||
"amper-scripts": "^1.0.0-0", | ||
"@babel/core": "^7.14.3", | ||
"@babel/plugin-proposal-class-properties": "^7.13.0", | ||
"@babel/plugin-transform-runtime": "^7.14.3", | ||
"@babel/preset-env": "^7.14.4", | ||
"@babel/preset-typescript": "^7.13.0", | ||
"@rollup/plugin-babel": "^5.3.0", | ||
"@rollup/plugin-commonjs": "^19.0.0", | ||
"@rollup/plugin-node-resolve": "^13.0.0", | ||
"@typescript-eslint/eslint-plugin": "^4.26.1", | ||
"@typescript-eslint/parser": "^4.26.1", | ||
"amper-scripts": "^1.0.0", | ||
"ava": "^3.9.0", | ||
"nodemon": "^2.0.4", | ||
"nodemon": "^2.0.7", | ||
"npm-run-all": "^4.1.5", | ||
"prettier": "^2.0.5", | ||
"prettier": "^2.3.1", | ||
"rimraf": "^3.0.2", | ||
"rollup": "^2.16.1", | ||
"rollup-plugin-terser": "^6.1.0", | ||
"ts-node": "^8.10.2", | ||
"typescript": "^3.9.5" | ||
"rollup": "^2.51.1", | ||
"rollup-plugin-terser": "^7.0.2", | ||
"ts-node": "^10.0.0", | ||
"typescript": "^4.3.2" | ||
}, | ||
@@ -91,5 +90,5 @@ "peerDependencies": {}, | ||
"lint": "amper-scripts lint --config ./.eslintrc.js 'src/**/*.{js,ts,tsx}'", | ||
"prepublish": "yarn build", | ||
"prepack": "yarn build", | ||
"test": "ava" | ||
} | ||
} |
116
README.md
@@ -7,6 +7,2 @@ # deep | ||
Note: `set()` and `remove()` modify the passed-in object rather than creating a | ||
copy. If you'd rather return a new object each time, there are several other | ||
solutions ([unchanged] is really good). | ||
## Install | ||
@@ -29,3 +25,3 @@ | ||
```js | ||
import { get, getOr, has, pluck remove, set } from '@blakek/deep'; | ||
import { clone, get, getOr, has, omit, pluck, remove, set } from '@blakek/deep'; | ||
@@ -42,2 +38,9 @@ const user = { | ||
// 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 | ||
@@ -56,2 +59,5 @@ get('sites.github.username', user); //» 'blakek' | ||
// Clone an object and omit properties | ||
omit(['roles', 'sites'], user); //» { id: 'abf87de' } | ||
// Pluck a subset of properties | ||
@@ -61,6 +67,6 @@ pluck(['id', 'roles'], user); | ||
// Remove a property value | ||
// Remove a property value, modifying the current object | ||
remove('a', { a: 42, b: 123 }); //» { b: 123 } | ||
// Set a property value | ||
// Set a property value, modifying the current object | ||
set(123, 'a.b.c', { a: 42 }); //» { a: { b: { c: 123 } } } | ||
@@ -76,4 +82,22 @@ ``` | ||
### `clone` | ||
Returns a deep clone / deep copy of most values: primitive values, objects, arrays, Map, Set, Date, etc. | ||
```ts | ||
function clone<T extends unknown>(value: T): T; | ||
``` | ||
```js | ||
const object = { value: 'yep' }; | ||
const cloned = clone(object); | ||
cloned === object; //» false | ||
cloned.value === object.value; //» true | ||
``` | ||
### `get` | ||
Gets the value for a given path with an optional fallback value. | ||
```ts | ||
@@ -83,4 +107,2 @@ function get(path: Path, object: any): any; | ||
Gets the value for a given path with an optional fallback value. | ||
```js | ||
@@ -109,2 +131,5 @@ const user = { | ||
Like `get`, gets a value from an object. Will return a fallback other than | ||
`undefined` if the value was not found equal to `undefined`. | ||
```ts | ||
@@ -114,5 +139,2 @@ function getOr(defaultValue: any, path: Path, object: any): any; | ||
Like `get`, gets a value from an object. Will return a fallback other than | ||
`undefined` if the value was not found equal to `undefined`. | ||
```js | ||
@@ -138,2 +160,5 @@ const user = { | ||
Returns `true` if a value was found at the given path or `false` if nothing was | ||
found. | ||
```ts | ||
@@ -143,5 +168,2 @@ function has(path: Path, object: any): boolean; | ||
Returns `true` if a value was found at the given path or `false` if nothing was | ||
found. | ||
```js | ||
@@ -165,19 +187,27 @@ const product = { | ||
### `remove` | ||
### `omit` | ||
Returns a clone of an object with some 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 remove(path: Path, object: any): any; | ||
function omit(properties: Path[], object: any): any; | ||
``` | ||
Removes a value at a path and returns the object. | ||
```js | ||
const user = { | ||
username: 'blakek', | ||
password: 'wouldntyouliketoknow' | ||
roles: ['alert:create', 'alert:read'], | ||
sites: { | ||
github: { | ||
username: 'blakek' | ||
} | ||
} | ||
}; | ||
remove('password', user); //» { username: 'blakek' } | ||
remove('property.does.not.exist', user); | ||
//» { username: 'blakek' } (same object from previous line) | ||
omit(['roles', 'sites'], user); //» { username: 'blakek' } | ||
omit(['username', 'roles', 'sites.doesnt.exist'], user); | ||
//» { sites: { github: { username: 'blakek' } } } | ||
``` | ||
@@ -187,2 +217,4 @@ | ||
Gets a subset of properties from an object. | ||
```ts | ||
@@ -192,4 +224,2 @@ function pluck(properties: Path[], object: any): any; | ||
Gets a subset of properties from an object. | ||
```js | ||
@@ -211,4 +241,38 @@ const user = { | ||
### `remove` | ||
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; | ||
``` | ||
```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) | ||
``` | ||
### `set` | ||
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 | ||
@@ -218,4 +282,2 @@ function set(value: any, path: Path, object: any): any; | ||
Sets a value at a path and returns the object. | ||
```js | ||
@@ -222,0 +284,0 @@ const user = { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
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
252
310
51428