pax_global_header00006660000000000000000000000064130521106550014510gustar00rootroot0000000000000052 comment=49f0809db1201f2cf13735de4f3631191a692658 dot-prop-4.1.1/000077500000000000000000000000001305211065500132575ustar00rootroot00000000000000dot-prop-4.1.1/.editorconfig000066400000000000000000000002761305211065500157410ustar00rootroot00000000000000root = true [*] indent_style = tab end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true [{package.json,*.yml}] indent_style = space indent_size = 2 dot-prop-4.1.1/.gitattributes000066400000000000000000000000141305211065500161450ustar00rootroot00000000000000* text=auto dot-prop-4.1.1/.gitignore000066400000000000000000000000151305211065500152430ustar00rootroot00000000000000node_modules dot-prop-4.1.1/.travis.yml000066400000000000000000000000671305211065500153730ustar00rootroot00000000000000sudo: false language: node_js node_js: - '6' - '4' dot-prop-4.1.1/bench.js000066400000000000000000000060071305211065500146770ustar00rootroot00000000000000'use strict'; /* globals bench */ const m = require('./'); bench('get', () => { const f1 = {foo: {bar: 1}}; m.get(f1); f1[''] = 'foo'; m.get(f1, ''); m.get(f1, 'foo'); m.get({foo: 1}, 'foo'); m.get({foo: null}, 'foo'); m.get({foo: undefined}, 'foo'); m.get({foo: {bar: true}}, 'foo.bar'); m.get({foo: {bar: {baz: true}}}, 'foo.bar.baz'); m.get({foo: {bar: {baz: null}}}, 'foo.bar.baz'); m.get({foo: {bar: 'a'}}, 'foo.fake'); m.get({foo: {bar: 'a'}}, 'foo.fake.fake2'); m.get({'\\': true}, '\\'); m.get({'\\foo': true}, '\\foo'); m.get({'bar\\': true}, 'bar\\'); m.get({'foo\\bar': true}, 'foo\\bar'); m.get({'\\.foo': true}, '\\\\.foo'); m.get({'bar\\.': true}, 'bar\\\\.'); m.get({'foo\\.bar': true}, 'foo\\\\.bar'); const f2 = {}; Object.defineProperty(f2, 'foo', { value: 'bar', enumerable: false }); m.get(f2, 'foo'); m.get({}, 'hasOwnProperty'); function fn() {} fn.foo = {bar: 1}; m.get(fn); m.get(fn, 'foo'); m.get(fn, 'foo.bar'); const f3 = {foo: null}; m.get(f3, 'foo.bar'); m.get({'foo.baz': {bar: true}}, 'foo\\.baz.bar'); m.get({'fo.ob.az': {bar: true}}, 'fo\\.ob\\.az.bar'); m.get(null, 'foo.bar', false); m.get('foo', 'foo.bar', false); m.get([], 'foo.bar', false); m.get(undefined, 'foo.bar', false); }); bench('set', () => { const func = () => 'test'; let f1 = {}; m.set(f1, 'foo', 2); f1 = {foo: {bar: 1}}; m.set(f1, 'foo.bar', 2); m.set(f1, 'foo.bar.baz', 3); m.set(f1, 'foo.bar', 'test'); m.set(f1, 'foo.bar', null); m.set(f1, 'foo.bar', false); m.set(f1, 'foo.bar', undefined); m.set(f1, 'foo.fake.fake2', 'fake'); m.set(f1, 'foo.function', func); function fn() {} m.set(fn, 'foo.bar', 1); f1.fn = fn; m.set(f1, 'fn.bar.baz', 2); const f2 = {foo: null}; m.set(f2, 'foo.bar', 2); const f3 = {}; m.set(f3, '', 3); m.set(f1, 'foo\\.bar.baz', true); m.set(f1, 'fo\\.ob\\.ar.baz', true); }); bench('delete', () => { const func = () => 'test'; func.foo = 'bar'; const inner = { a: 'a', b: 'b', c: 'c', func }; const f1 = { foo: { bar: { baz: inner } }, top: { dog: 'sindre' } }; m.delete(f1, 'foo.bar.baz.c'); m.delete(f1, 'top'); m.delete(f1, 'foo.bar.baz.func.foo'); m.delete(f1, 'foo.bar.baz.func'); m.set(f1, 'foo\\.bar.baz', true); m.delete(f1, 'foo\\.bar.baz'); const f2 = {}; m.set(f2, 'foo.bar\\.baz', true); m.delete(f2, 'foo.bar\\.baz'); f2.dotted = { sub: { 'dotted.prop': 'foo', other: 'prop' } }; m.delete(f2, 'dotted.sub.dotted\\.prop'); }); bench('has', () => { const f1 = {foo: {bar: 1}}; m.has(f1); m.has(f1, 'foo'); m.has({foo: 1}, 'foo'); m.has({foo: null}, 'foo'); m.has({foo: undefined}, 'foo'); m.has({foo: {bar: true}}, 'foo.bar'); m.has({foo: {bar: {baz: true}}}, 'foo.bar.baz'); m.has({foo: {bar: {baz: null}}}, 'foo.bar.baz'); m.has({foo: {bar: 'a'}}, 'foo.fake.fake2'); function fn() {} fn.foo = {bar: 1}; m.has(fn); m.has(fn, 'foo'); m.has(fn, 'foo.bar'); m.has({'foo.baz': {bar: true}}, 'foo\\.baz.bar'); m.has({'fo.ob.az': {bar: true}}, 'fo\\.ob\\.az.bar'); }); dot-prop-4.1.1/index.js000066400000000000000000000042341305211065500147270ustar00rootroot00000000000000'use strict'; const isObj = require('is-obj'); function getPathSegments(path) { const pathArr = path.split('.'); const parts = []; for (let i = 0; i < pathArr.length; i++) { let p = pathArr[i]; while (p[p.length - 1] === '\\' && pathArr[i + 1] !== undefined) { p = p.slice(0, -1) + '.'; p += pathArr[++i]; } parts.push(p); } return parts; } module.exports = { get(obj, path, value) { if (!isObj(obj) || typeof path !== 'string') { return value === undefined ? obj : value; } const pathArr = getPathSegments(path); for (let i = 0; i < pathArr.length; i++) { if (!Object.prototype.propertyIsEnumerable.call(obj, pathArr[i])) { return value; } obj = obj[pathArr[i]]; if (obj === undefined || obj === null) { // `obj` is either `undefined` or `null` so we want to stop the loop, and // if this is not the last bit of the path, and // if it did't return `undefined` // it would return `null` if `obj` is `null` // but we want `get({foo: null}, 'foo.bar')` to equal `undefined`, or the supplied value, not `null` if (i !== pathArr.length - 1) { return value; } break; } } return obj; }, set(obj, path, value) { if (!isObj(obj) || typeof path !== 'string') { return; } const pathArr = getPathSegments(path); for (let i = 0; i < pathArr.length; i++) { const p = pathArr[i]; if (!isObj(obj[p])) { obj[p] = {}; } if (i === pathArr.length - 1) { obj[p] = value; } obj = obj[p]; } }, delete(obj, path) { if (!isObj(obj) || typeof path !== 'string') { return; } const pathArr = getPathSegments(path); for (let i = 0; i < pathArr.length; i++) { const p = pathArr[i]; if (i === pathArr.length - 1) { delete obj[p]; return; } obj = obj[p]; if (!isObj(obj)) { return; } } }, has(obj, path) { if (!isObj(obj) || typeof path !== 'string') { return false; } const pathArr = getPathSegments(path); for (let i = 0; i < pathArr.length; i++) { if (isObj(obj)) { if (!(pathArr[i] in obj)) { return false; } obj = obj[pathArr[i]]; } else { return false; } } return true; } }; dot-prop-4.1.1/license000066400000000000000000000021371305211065500146270ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) Sindre Sorhus (sindresorhus.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. dot-prop-4.1.1/package.json000066400000000000000000000014531305211065500155500ustar00rootroot00000000000000{ "name": "dot-prop", "version": "4.1.1", "description": "Get, set, or delete a property from a nested object using a dot path", "license": "MIT", "repository": "sindresorhus/dot-prop", "author": { "name": "Sindre Sorhus", "email": "sindresorhus@gmail.com", "url": "sindresorhus.com" }, "engines": { "node": ">=4" }, "scripts": { "test": "xo && ava", "bench": "matcha bench.js" }, "files": [ "index.js" ], "keywords": [ "obj", "object", "prop", "property", "dot", "path", "get", "set", "delete", "del", "access", "notation", "dotty" ], "dependencies": { "is-obj": "^1.0.0" }, "devDependencies": { "ava": "*", "matcha": "^0.7.0", "xo": "*" }, "xo": { "esnext": true } } dot-prop-4.1.1/readme.md000066400000000000000000000031271305211065500150410ustar00rootroot00000000000000# dot-prop [![Build Status](https://travis-ci.org/sindresorhus/dot-prop.svg?branch=master)](https://travis-ci.org/sindresorhus/dot-prop) > Get, set, or delete a property from a nested object using a dot path ## Install ``` $ npm install --save dot-prop ``` ## Usage ```js const dotProp = require('dot-prop'); // getter dotProp.get({foo: {bar: 'unicorn'}}, 'foo.bar'); //=> 'unicorn' dotProp.get({foo: {bar: 'a'}}, 'foo.notDefined.deep'); //=> undefined dotProp.get({foo: {bar: 'a'}}, 'foo.notDefined.deep', 'default value'); //=> 'default value' dotProp.get({foo: {'dot.dot': 'unicorn'}}, 'foo.dot\\.dot'); //=> 'unicorn' // setter const obj = {foo: {bar: 'a'}}; dotProp.set(obj, 'foo.bar', 'b'); console.log(obj); //=> {foo: {bar: 'b'}} dotProp.set(obj, 'foo.baz', 'x'); console.log(obj); //=> {foo: {bar: 'b', baz: 'x'}} // has dotProp.has({foo: {bar: 'unicorn'}}, 'foo.bar'); //=> true // deleter const obj = {foo: {bar: 'a'}}; dotProp.delete(obj, 'foo.bar'); console.log(obj); //=> {foo: {}} obj.foo.bar = {x: 'y', y: 'x'}; dotProp.delete(obj, 'foo.bar.x'); console.log(obj); //=> {foo: {bar: {y: 'x'}}} ``` ## API ### get(obj, path, [defaultValue]) ### set(obj, path, value) ### has(obj, path) ### delete(obj, path) #### obj Type: `Object` Object to get, set, or delete the `path` value. #### path Type: `string` Path of the property in the object, using `.` to separate each nested key. Use `\\.` if you have a `.` in the key. #### value Type: `any` Value to set at `path`. #### defaultValue Type: `any` Default value. ## License MIT © [Sindre Sorhus](https://sindresorhus.com) dot-prop-4.1.1/test.js000066400000000000000000000113701305211065500145760ustar00rootroot00000000000000import test from 'ava'; import m from './'; test('get', t => { const f1 = {foo: {bar: 1}}; t.is(m.get(f1), f1); f1[''] = 'foo'; t.is(m.get(f1, ''), 'foo'); t.is(m.get(f1, 'foo'), f1.foo); t.is(m.get({foo: 1}, 'foo'), 1); t.is(m.get({foo: null}, 'foo'), null); t.is(m.get({foo: undefined}, 'foo'), undefined); t.is(m.get({foo: {bar: true}}, 'foo.bar'), true); t.is(m.get({foo: {bar: {baz: true}}}, 'foo.bar.baz'), true); t.is(m.get({foo: {bar: {baz: null}}}, 'foo.bar.baz'), null); t.is(m.get({foo: {bar: 'a'}}, 'foo.fake'), undefined); t.is(m.get({foo: {bar: 'a'}}, 'foo.fake.fake2'), undefined); t.is(m.get({foo: {bar: 'a'}}, 'foo.fake.fake2', 'some value'), 'some value'); t.is(m.get({'\\': true}, '\\'), true); t.is(m.get({'\\foo': true}, '\\foo'), true); t.is(m.get({'bar\\': true}, 'bar\\'), true); t.is(m.get({'foo\\bar': true}, 'foo\\bar'), true); t.is(m.get({'\\.foo': true}, '\\\\.foo'), true); t.is(m.get({'bar\\.': true}, 'bar\\\\.'), true); t.is(m.get({'foo\\.bar': true}, 'foo\\\\.bar'), true); t.is(m.get({foo: 1}, 'foo.bar'), undefined); const f2 = {}; Object.defineProperty(f2, 'foo', { value: 'bar', enumerable: false }); t.is(m.get(f2, 'foo'), undefined); t.is(m.get({}, 'hasOwnProperty'), undefined); function fn() {} fn.foo = {bar: 1}; t.is(m.get(fn), fn); t.is(m.get(fn, 'foo'), fn.foo); t.is(m.get(fn, 'foo.bar'), 1); const f3 = {foo: null}; t.is(m.get(f3, 'foo.bar'), undefined); t.is(m.get(f3, 'foo.bar', 'some value'), 'some value'); t.is(m.get({'foo.baz': {bar: true}}, 'foo\\.baz.bar'), true); t.is(m.get({'fo.ob.az': {bar: true}}, 'fo\\.ob\\.az.bar'), true); t.is(m.get(null, 'foo.bar', false), false); t.is(m.get('foo', 'foo.bar', false), false); t.is(m.get([], 'foo.bar', false), false); t.is(m.get(undefined, 'foo.bar', false), false); }); test('set', t => { const func = () => 'test'; let f1 = {}; m.set(f1, 'foo', 2); t.is(f1.foo, 2); f1 = {foo: {bar: 1}}; m.set(f1, 'foo.bar', 2); t.is(f1.foo.bar, 2); m.set(f1, 'foo.bar.baz', 3); t.is(f1.foo.bar.baz, 3); m.set(f1, 'foo.bar', 'test'); t.is(f1.foo.bar, 'test'); m.set(f1, 'foo.bar', null); t.is(f1.foo.bar, null); m.set(f1, 'foo.bar', false); t.is(f1.foo.bar, false); m.set(f1, 'foo.bar', undefined); t.is(f1.foo.bar, undefined); m.set(f1, 'foo.fake.fake2', 'fake'); t.is(f1.foo.fake.fake2, 'fake'); m.set(f1, 'foo.function', func); t.is(f1.foo.function, func); function fn() {} m.set(fn, 'foo.bar', 1); t.is(fn.foo.bar, 1); f1.fn = fn; m.set(f1, 'fn.bar.baz', 2); t.is(f1.fn.bar.baz, 2); const f2 = {foo: null}; m.set(f2, 'foo.bar', 2); t.is(f2.foo.bar, 2); const f3 = {}; m.set(f3, '', 3); t.is(f3[''], 3); m.set(f1, 'foo\\.bar.baz', true); t.is(f1['foo.bar'].baz, true); m.set(f1, 'fo\\.ob\\.ar.baz', true); t.is(f1['fo.ob.ar'].baz, true); }); test('delete', t => { const func = () => 'test'; func.foo = 'bar'; const inner = { a: 'a', b: 'b', c: 'c', func }; const f1 = { foo: { bar: { baz: inner } }, top: { dog: 'sindre' } }; t.is(f1.foo.bar.baz.c, 'c'); m.delete(f1, 'foo.bar.baz.c'); t.is(f1.foo.bar.baz.c, undefined); t.is(f1.top.dog, 'sindre'); m.delete(f1, 'top'); t.is(f1.top, undefined); t.is(f1.foo.bar.baz.func.foo, 'bar'); m.delete(f1, 'foo.bar.baz.func.foo'); t.is(f1.foo.bar.baz.func.foo, undefined); t.is(f1.foo.bar.baz.func, func); m.delete(f1, 'foo.bar.baz.func'); t.is(f1.foo.bar.baz.func, undefined); m.set(f1, 'foo\\.bar.baz', true); t.is(f1['foo.bar'].baz, true); m.delete(f1, 'foo\\.bar.baz'); t.is(f1['foo.bar'].baz, undefined); const f2 = {}; m.set(f2, 'foo.bar\\.baz', true); t.is(f2.foo['bar.baz'], true); m.delete(f2, 'foo.bar\\.baz'); t.is(f2.foo['bar.baz'], undefined); f2.dotted = { sub: { 'dotted.prop': 'foo', other: 'prop' } }; m.delete(f2, 'dotted.sub.dotted\\.prop'); t.is(f2.dotted.sub['dotted.prop'], undefined); t.is(f2.dotted.sub.other, 'prop'); const f3 = {foo: null}; m.delete(f3, 'foo.bar'); t.deepEqual(f3, {foo: null}); }); test('has', t => { const f1 = {foo: {bar: 1}}; t.is(m.has(f1), false); t.is(m.has(f1, 'foo'), true); t.is(m.has({foo: 1}, 'foo'), true); t.is(m.has({foo: null}, 'foo'), true); t.is(m.has({foo: undefined}, 'foo'), true); t.is(m.has({foo: {bar: true}}, 'foo.bar'), true); t.is(m.has({foo: {bar: {baz: true}}}, 'foo.bar.baz'), true); t.is(m.has({foo: {bar: {baz: null}}}, 'foo.bar.baz'), true); t.is(m.has({foo: {bar: 'a'}}, 'foo.fake.fake2'), false); t.is(m.has({foo: null}, 'foo.bar'), false); t.is(m.has({foo: ''}, 'foo.bar'), false); function fn() {} fn.foo = {bar: 1}; t.is(m.has(fn), false); t.is(m.has(fn, 'foo'), true); t.is(m.has(fn, 'foo.bar'), true); t.is(m.has({'foo.baz': {bar: true}}, 'foo\\.baz.bar'), true); t.is(m.has({'fo.ob.az': {bar: true}}, 'fo\\.ob\\.az.bar'), true); });