@thi.ng/paths
Advanced tools
Comparing version 4.0.11 to 4.1.0
@@ -6,2 +6,13 @@ # Change Log | ||
# [4.1.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/paths@4.0.11...@thi.ng/paths@4.1.0) (2020-07-08) | ||
### Features | ||
* **paths:** add isProtoPath/disallowProtoPath() helpers ([2e6a80f](https://github.com/thi-ng/umbrella/commit/2e6a80f31bba67ef5251c3e2da1c5eef6a530419)) | ||
## [4.0.11](https://github.com/thi-ng/umbrella/compare/@thi.ng/paths@4.0.10...@thi.ng/paths@4.0.11) (2020-07-04) | ||
@@ -8,0 +19,0 @@ |
@@ -5,2 +5,3 @@ 'use strict'; | ||
var api = require('@thi.ng/api'); | ||
var checks = require('@thi.ng/checks'); | ||
@@ -35,2 +36,8 @@ var errors = require('@thi.ng/errors'); | ||
}; | ||
const isProtoPath = (path) => checks.isArray(path) | ||
? path.some((x) => x === "__proto__") | ||
: checks.isString(path) | ||
? path.indexOf("__proto__") >= 0 | ||
: false; | ||
const disallowProtoPath = (path) => (api.assert(!isProtoPath(path), `unsafe path: '${path}'`), path); | ||
@@ -249,5 +256,7 @@ const defGetterUnsafe = (path) => defGetter(path); | ||
exports.deleteInUnsafe = deleteInUnsafe; | ||
exports.disallowProtoPath = disallowProtoPath; | ||
exports.exists = exists; | ||
exports.getIn = getIn; | ||
exports.getInUnsafe = getInUnsafe; | ||
exports.isProtoPath = isProtoPath; | ||
exports.mutIn = mutIn; | ||
@@ -254,0 +263,0 @@ exports.mutInManyUnsafe = mutInManyUnsafe; |
@@ -1,1 +0,1 @@ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@thi.ng/checks"),require("@thi.ng/errors")):"function"==typeof define&&define.amd?define(["exports","@thi.ng/checks","@thi.ng/errors"],t):t(((e=e||self).thi=e.thi||{},e.thi.ng=e.thi.ng||{},e.thi.ng.paths={}),e.thi.ng.checks,e.thi.ng.errors)}(this,(function(e,t,n){"use strict";const r=e=>t.isArray(e)?e:t.isString(e)?e.length>0?e.split("."):[]:null!=e?[e]:[];function u(e){const t=r(e),[n,u,l,s]=t;switch(t.length){case 0:return e=>e;case 1:return e=>null!=e?e[n]:void 0;case 2:return e=>null!=e&&null!=(e=e[n])?e[u]:void 0;case 3:return e=>null!=e&&null!=(e=e[n])&&null!=(e=e[u])?e[l]:void 0;case 4:return e=>null!=e&&null!=(e=e[n])&&null!=(e=e[u])&&null!=(e=e[l])?e[s]:void 0;default:return e=>{const n=t.length-1;let r=e;for(let e=0;null!=r&&e<=n;e++)r=r[t[e]];return r}}}function l(e){const t=r(e),[n,u,l,o]=t;switch(t.length){case 0:return(e,t)=>t;case 1:return(e,t)=>((e=s(e))[n]=t,e);case 2:return(e,t)=>{let r;return(e=s(e))[n]=r=s(e[n]),r[u]=t,e};case 3:return(e,t)=>{let r,i;return(e=s(e))[n]=r=s(e[n]),r[u]=i=s(r[u]),i[l]=t,e};case 4:return(e,t)=>{let r,i,f;return(e=s(e))[n]=r=s(e[n]),r[u]=i=s(r[u]),i[l]=f=s(i[l]),f[o]=t,e};default:let e;for(let n=t.length;--n>=0;)e=i(t[n],e);return e}}const s=e=>t.isArray(e)||t.isTypedArray(e)?e.slice():Object.assign({},e),i=(e,t)=>(n,r)=>((n=s(n))[e]=t?t(n[e],r):r,n);function o(e,t,n,...r){return l(t)(e,n.apply(null,(r.unshift(u(t)(e)),r)))}function f(e,t){const n=r(t).slice();if(n.length){const t=n.pop();return o(e,n,e=>(delete(e=Object.assign({},e))[t],e))}}function c(e){const t=r(e);let[n,u,l,s]=t;switch(t.length){case 0:return(e,t)=>t;case 1:return(e,t)=>e?(e[n]=t,e):void 0;case 2:return(e,t)=>{let r;return e&&(r=e[n])?(r[u]=t,e):void 0};case 3:return(e,t)=>{let r;return e&&(r=e[n])&&(r=r[u])?(r[l]=t,e):void 0};case 4:return(e,t)=>{let r;return e&&(r=e[n])&&(r=r[u])&&(r=r[l])?(r[s]=t,e):void 0};default:return(e,n)=>{let r=e;const u=t.length-1;for(let e=0;e<u;e++)if(!(r=r[t[e]]))return;return r[t[u]]=n,e}}}function a(e,t,n){return c(t)(e,n)}function d(e,t,n){return l(t)(e,n)}function h(e,t){const n=u(e),r=l(e);return(e,...u)=>r(e,t.apply(null,(u.unshift(n(e)),u)))}e.copy=s,e.defGetter=u,e.defGetterUnsafe=e=>u(e),e.defMutator=c,e.defMutatorUnsafe=e=>c(e),e.defSetter=l,e.defSetterUnsafe=e=>l(e),e.defUpdater=h,e.defUpdaterUnsafe=(e,t)=>h(e,t),e.deleteIn=f,e.deleteInUnsafe=(e,t)=>f(e,t),e.exists=(e,t)=>{if(null==e)return!1;for(let n=(t=r(t)).length-1,u=0;u<=n;u++){const r=t[u];if(!e.hasOwnProperty(r))return!1;if(null==(e=e[r])&&u<n)return!1}return!0},e.getIn=function(e,t){return u(t)(e)},e.getInUnsafe=(e,t)=>u(t)(e),e.mutIn=a,e.mutInManyUnsafe=function(e,...t){const r=t.length;1&r&&n.illegalArgs(`require even number of args (got ${t.length})`);for(let n=0;n<r&&e;n+=2)e=a(e,t[n],t[n+1]);return e},e.mutInUnsafe=(e,t,n)=>c(t)(e,n),e.setIn=d,e.setInManyUnsafe=function(e,...t){const r=t.length;1&r&&n.illegalArgs(`require even number of KV args (got ${t.length})`);for(let n=0;n<r;n+=2)e=d(e,t[n],t[n+1]);return e},e.setInUnsafe=(e,t,n)=>l(t)(e,n),e.toPath=r,e.updateIn=o,e.updateInUnsafe=(e,t,n,...r)=>o(e,t,n,...r),Object.defineProperty(e,"__esModule",{value:!0})})); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@thi.ng/api"),require("@thi.ng/checks"),require("@thi.ng/errors")):"function"==typeof define&&define.amd?define(["exports","@thi.ng/api","@thi.ng/checks","@thi.ng/errors"],t):t(((e=e||self).thi=e.thi||{},e.thi.ng=e.thi.ng||{},e.thi.ng.paths={}),e.api,e.thi.ng.checks,e.thi.ng.errors)}(this,(function(e,t,n,r){"use strict";const u=e=>n.isArray(e)?e:n.isString(e)?e.length>0?e.split("."):[]:null!=e?[e]:[],s=e=>n.isArray(e)?e.some(e=>"__proto__"===e):!!n.isString(e)&&e.indexOf("__proto__")>=0;function l(e){const t=u(e),[n,r,s,l]=t;switch(t.length){case 0:return e=>e;case 1:return e=>null!=e?e[n]:void 0;case 2:return e=>null!=e&&null!=(e=e[n])?e[r]:void 0;case 3:return e=>null!=e&&null!=(e=e[n])&&null!=(e=e[r])?e[s]:void 0;case 4:return e=>null!=e&&null!=(e=e[n])&&null!=(e=e[r])&&null!=(e=e[s])?e[l]:void 0;default:return e=>{const n=t.length-1;let r=e;for(let e=0;null!=r&&e<=n;e++)r=r[t[e]];return r}}}function i(e){const t=u(e),[n,r,s,l]=t;switch(t.length){case 0:return(e,t)=>t;case 1:return(e,t)=>((e=o(e))[n]=t,e);case 2:return(e,t)=>{let u;return(e=o(e))[n]=u=o(e[n]),u[r]=t,e};case 3:return(e,t)=>{let u,l;return(e=o(e))[n]=u=o(e[n]),u[r]=l=o(u[r]),l[s]=t,e};case 4:return(e,t)=>{let u,i,a;return(e=o(e))[n]=u=o(e[n]),u[r]=i=o(u[r]),i[s]=a=o(i[s]),a[l]=t,e};default:let e;for(let n=t.length;--n>=0;)e=a(t[n],e);return e}}const o=e=>n.isArray(e)||n.isTypedArray(e)?e.slice():Object.assign({},e),a=(e,t)=>(n,r)=>((n=o(n))[e]=t?t(n[e],r):r,n);function f(e,t,n,...r){return i(t)(e,n.apply(null,(r.unshift(l(t)(e)),r)))}function c(e,t){const n=u(t).slice();if(n.length){const t=n.pop();return f(e,n,e=>(delete(e=Object.assign({},e))[t],e))}}function h(e){const t=u(e);let[n,r,s,l]=t;switch(t.length){case 0:return(e,t)=>t;case 1:return(e,t)=>e?(e[n]=t,e):void 0;case 2:return(e,t)=>{let u;return e&&(u=e[n])?(u[r]=t,e):void 0};case 3:return(e,t)=>{let u;return e&&(u=e[n])&&(u=u[r])?(u[s]=t,e):void 0};case 4:return(e,t)=>{let u;return e&&(u=e[n])&&(u=u[r])&&(u=u[s])?(u[l]=t,e):void 0};default:return(e,n)=>{let r=e;const u=t.length-1;for(let e=0;e<u;e++)if(!(r=r[t[e]]))return;return r[t[u]]=n,e}}}function d(e,t,n){return h(t)(e,n)}function g(e,t,n){return i(t)(e,n)}function p(e,t){const n=l(e),r=i(e);return(e,...u)=>r(e,t.apply(null,(u.unshift(n(e)),u)))}e.copy=o,e.defGetter=l,e.defGetterUnsafe=e=>l(e),e.defMutator=h,e.defMutatorUnsafe=e=>h(e),e.defSetter=i,e.defSetterUnsafe=e=>i(e),e.defUpdater=p,e.defUpdaterUnsafe=(e,t)=>p(e,t),e.deleteIn=c,e.deleteInUnsafe=(e,t)=>c(e,t),e.disallowProtoPath=e=>(t.assert(!s(e),`unsafe path: '${e}'`),e),e.exists=(e,t)=>{if(null==e)return!1;for(let n=(t=u(t)).length-1,r=0;r<=n;r++){const u=t[r];if(!e.hasOwnProperty(u))return!1;if(null==(e=e[u])&&r<n)return!1}return!0},e.getIn=function(e,t){return l(t)(e)},e.getInUnsafe=(e,t)=>l(t)(e),e.isProtoPath=s,e.mutIn=d,e.mutInManyUnsafe=function(e,...t){const n=t.length;1&n&&r.illegalArgs(`require even number of args (got ${t.length})`);for(let r=0;r<n&&e;r+=2)e=d(e,t[r],t[r+1]);return e},e.mutInUnsafe=(e,t,n)=>h(t)(e,n),e.setIn=g,e.setInManyUnsafe=function(e,...t){const n=t.length;1&n&&r.illegalArgs(`require even number of KV args (got ${t.length})`);for(let r=0;r<n;r+=2)e=g(e,t[r],t[r+1]);return e},e.setInUnsafe=(e,t,n)=>i(t)(e,n),e.toPath=u,e.updateIn=f,e.updateInUnsafe=(e,t,n,...r)=>f(e,t,n,...r),Object.defineProperty(e,"__esModule",{value:!0})})); |
{ | ||
"name": "@thi.ng/paths", | ||
"version": "4.0.11", | ||
"version": "4.1.0", | ||
"description": "Immutable, optimized and optionally typed path-based object property / array accessors with structural sharing", | ||
@@ -83,3 +83,3 @@ "module": "./index.js", | ||
"sideEffects": false, | ||
"gitHead": "415fcbd5b35c1041044d9f17d89718faa9999906" | ||
"gitHead": "9966e103d7dc816ac8e6989d250bfb1a57da51a4" | ||
} |
@@ -1,2 +0,2 @@ | ||
import type { NumOrString, Path } from "@thi.ng/api"; | ||
import { NumOrString, Path } from "@thi.ng/api"; | ||
/** | ||
@@ -29,2 +29,19 @@ * Converts the given key path to canonical form (array). | ||
export declare const exists: (obj: any, path: Path) => boolean; | ||
/** | ||
* Helper function to analyze given lookup path for presence of | ||
* `__proto__`. Returns true if the case. | ||
* | ||
* @remarks | ||
* Also see {@link disallowProtoPath} | ||
* | ||
* @param path | ||
*/ | ||
export declare const isProtoPath: (path: Path) => boolean; | ||
/** | ||
* Helper function to analyze given path using {@link isProtoPath}. | ||
* Throws error if path contains `__proto__`. | ||
* | ||
* @param path | ||
*/ | ||
export declare const disallowProtoPath: (path: Path) => Path; | ||
//# sourceMappingURL=path.d.ts.map |
22
path.js
@@ -0,1 +1,2 @@ | ||
import { assert } from "@thi.ng/api"; | ||
import { isArray, isString } from "@thi.ng/checks"; | ||
@@ -53,1 +54,22 @@ /** | ||
}; | ||
/** | ||
* Helper function to analyze given lookup path for presence of | ||
* `__proto__`. Returns true if the case. | ||
* | ||
* @remarks | ||
* Also see {@link disallowProtoPath} | ||
* | ||
* @param path | ||
*/ | ||
export const isProtoPath = (path) => isArray(path) | ||
? path.some((x) => x === "__proto__") | ||
: isString(path) | ||
? path.indexOf("__proto__") >= 0 | ||
: false; | ||
/** | ||
* Helper function to analyze given path using {@link isProtoPath}. | ||
* Throws error if path contains `__proto__`. | ||
* | ||
* @param path | ||
*/ | ||
export const disallowProtoPath = (path) => (assert(!isProtoPath(path), `unsafe path: '${path}'`), path); |
@@ -27,2 +27,3 @@ <!-- This file is generated - DO NOT EDIT! --> | ||
- [Deletions](#deletions) | ||
- [PPP - Prototype pollution potential](#ppp---prototype-pollution-potential) | ||
- [Structural sharing](#structural-sharing) | ||
@@ -79,3 +80,3 @@ - [Mutable setter](#mutable-setter) | ||
Package sizes (gzipped, pre-treeshake): ESM: 1.09 KB / CJS: 1.19 KB / UMD: 1.14 KB | ||
Package sizes (gzipped, pre-treeshake): ESM: 1.18 KB / CJS: 1.29 KB / UMD: 1.23 KB | ||
@@ -191,3 +192,4 @@ ## Dependencies | ||
Paths can also be defined as dot-separated strings, however cannot be type checked and MUST use the `Unsafe` version of each operation: | ||
Paths can also be defined as dot-separated strings, however cannot be | ||
type checked and MUST use the `Unsafe` version of each operation: | ||
@@ -274,2 +276,16 @@ ```ts | ||
### PPP - Prototype pollution potential | ||
Mainly a potential concern for the non-typechecked versions - currently, | ||
none of the setter/update/mutation functions explicitly disallow | ||
updating an object's `__proto__` property. However, the package provides | ||
the `isProtoPath()` and `disallowProtoPath()` helpers which can & should be | ||
used in conjunction with the setters in situations where it's advisable | ||
to do so. | ||
```ts | ||
setIn({}, disallowProtoPath("__proto__.foo", true)); | ||
// Uncaught Error: unsafe path: '__proto__.foo' | ||
``` | ||
### Structural sharing | ||
@@ -276,0 +292,0 @@ |
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
109070
1407
358