├── .gitattributes ├── .gitignore ├── .jshintrc ├── .travis.yml ├── .verb.md ├── LICENSE ├── README.md ├── bower.json ├── index.js ├── package.json └── test.js /.gitattributes: -------------------------------------------------------------------------------- 1 | # Enforce Unix newlines 2 | * text eol=lf 3 | 4 | # binaries 5 | *.ai binary 6 | *.psd binary 7 | *.jpg binary 8 | *.gif binary 9 | *.png binary 10 | *.jpeg binary -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Numerous always-ignore extensions 2 | *.DS_Store 3 | *.csv 4 | *.dat 5 | *.diff 6 | *.err 7 | *.gz 8 | *.log 9 | *.orig 10 | *.out 11 | *.pid 12 | *.rar 13 | *.rej 14 | *.seed 15 | *.swo 16 | *.swp 17 | *.vi 18 | *.yo-rc.json 19 | *.zip 20 | *~ 21 | .ruby-version 22 | lib-cov 23 | npm-debug.log 24 | 25 | # Always-ignore dirs 26 | /bower_components/ 27 | /node_modules/ 28 | /temp/ 29 | /tmp/ 30 | /vendor/ 31 | _gh_pages 32 | 33 | # OS or Editor folders 34 | *.esproj 35 | *.komodoproject 36 | .komodotools 37 | *.sublime-* 38 | ._* 39 | .cache 40 | .DS_Store 41 | .idea 42 | .project 43 | .settings 44 | .tmproj 45 | nbproject 46 | Thumbs.db 47 | 48 | # grunt-html-validation 49 | validation-status.json 50 | validation-report.json 51 | 52 | # misc 53 | TODO.md -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "asi": false, 3 | "boss": true, 4 | "curly": true, 5 | "eqeqeq": true, 6 | "eqnull": true, 7 | "esnext": true, 8 | "immed": true, 9 | "latedef": false, 10 | "laxcomma": false, 11 | "mocha": true, 12 | "newcap": true, 13 | "noarg": true, 14 | "node": true, 15 | "sub": true, 16 | "undef": true, 17 | "unused": true 18 | } -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | os: 3 | - linux 4 | - osx 5 | language: node_js 6 | node_js: 7 | - node 8 | - '9' 9 | - '8' 10 | - '6' 11 | - '4' 12 | - '0.12' 13 | - '0.10' 14 | -------------------------------------------------------------------------------- /.verb.md: -------------------------------------------------------------------------------- 1 | # {%= name %} {%= badge("fury") %} {%= badge("travis") %} 2 | 3 | > {%= description %} 4 | 5 | ## Install 6 | {%= include("install-npm", {save: true}) %} 7 | {%= include("install-bower", {save: true}) %} 8 | 9 | ## Usage 10 | 11 | ```js 12 | var defaults = require('{%= name %}'); 13 | 14 | defaults({a: {one: 'one'}}, {a: {two: 'two'}}) 15 | //=> {a: {one: 'one', two: 'two'}}; 16 | ``` 17 | 18 | ## Related projects 19 | {%= related(['merge-deep', 'mixin-deep', 'extend-shallow', 'assign-deep', 'defaults-deep', 'omit-deep'], {remove: name}) %} 20 | 21 | ## Running tests 22 | {%= include("tests") %} 23 | 24 | ## Contributing 25 | {%= include("contributing") %} 26 | 27 | ## Author 28 | {%= include("author") %} 29 | 30 | ## License 31 | {%= copyright() %} 32 | {%= license() %} 33 | 34 | *** 35 | 36 | {%= include("footer") %} -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014-2015, Jon Schlinkert. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # defaults-deep [![NPM version](https://badge.fury.io/js/defaults-deep.svg)](http://badge.fury.io/js/defaults-deep) [![Build Status](https://travis-ci.org/jonschlinkert/defaults-deep.svg)](https://travis-ci.org/jonschlinkert/defaults-deep) 2 | 3 | > Like `extend` but recursively copies only the missing properties/values to the target object. 4 | 5 | ## Install 6 | 7 | Install with [npm](https://www.npmjs.com/) 8 | 9 | ```sh 10 | $ npm i defaults-deep --save 11 | ``` 12 | 13 | Install with [bower](http://bower.io/) 14 | 15 | ```sh 16 | $ bower install defaults-deep --save 17 | ``` 18 | 19 | ## Usage 20 | 21 | ```js 22 | var defaults = require('defaults-deep'); 23 | 24 | defaults({a: {one: 'one'}}, {a: {two: 'two'}}) 25 | //=> {a: {one: 'one', two: 'two'}}; 26 | ``` 27 | 28 | ## Related projects 29 | 30 | * [assign-deep](https://github.com/jonschlinkert/assign-deep): Deeply assign the enumerable properties of source objects to a destination object. If a callback… [more](https://github.com/jonschlinkert/assign-deep) 31 | * [extend-shallow](https://github.com/jonschlinkert/extend-shallow): Extend an object with the properties of additional objects. node.js/javascript util. 32 | * [merge-deep](https://github.com/jonschlinkert/merge-deep): Recursively merge values in a javascript object. 33 | * [mixin-deep](https://github.com/jonschlinkert/mixin-deep): Deeply mix the properties of objects into the first object. Like merge-deep, but doesn't clone. 34 | * [omit-deep](https://github.com/jonschlinkert/omit-deep): Recursively omit the given keys from an object. 35 | 36 | ## Running tests 37 | 38 | Install dev dependencies: 39 | 40 | ```sh 41 | $ npm i -d && npm test 42 | ``` 43 | 44 | ## Contributing 45 | 46 | Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/defaults-deep/issues/new) 47 | 48 | ## Author 49 | 50 | **Jon Schlinkert** 51 | 52 | + [github/jonschlinkert](https://github.com/jonschlinkert) 53 | + [twitter/jonschlinkert](http://twitter.com/jonschlinkert) 54 | 55 | ## License 56 | 57 | Copyright © 2015 Jon Schlinkert 58 | Released under the MIT license. 59 | 60 | *** 61 | 62 | _This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on May 28, 2015._ 63 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "defaults-deep", 3 | "description": "Like `extend` but recursively copies only the missing properties/values to the target object.", 4 | "repository": "jonschlinkert/defaults-deep", 5 | "license": "MIT", 6 | "homepage": "https://github.com/jonschlinkert/defaults-deep", 7 | "authors": [ 8 | "Jon Schlinkert (https://github.com/jonschlinkert)" 9 | ], 10 | "main": [ 11 | "index.js" 12 | ], 13 | "dependencies": { 14 | "for-own": "^0.1.3", 15 | "is-plain-object": "^2.0.0" 16 | }, 17 | "devDependencies": { 18 | "mocha": "*", 19 | "should": "^4.0.4" 20 | }, 21 | "keywords": [ 22 | "copy", 23 | "default", 24 | "defaults", 25 | "extend", 26 | "merge", 27 | "object", 28 | "properties", 29 | "property", 30 | "value", 31 | "values", 32 | "javascript", 33 | "js", 34 | "util", 35 | "utils" 36 | ] 37 | } -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * defaults-deep 3 | * 4 | * Copyright (c) 2014-2015, Jon Schlinkert. 5 | * Licensed under the MIT License. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | var lazy = require('lazy-cache')(require); 11 | lazy('is-extendable', 'isObject'); 12 | lazy('for-own', 'forOwn'); 13 | 14 | function defaultsDeep(target, objects) { 15 | target = target || {}; 16 | 17 | function copy(target, current) { 18 | lazy.forOwn(current, function (value, key) { 19 | if (key === '__proto__') { 20 | return; 21 | } 22 | 23 | var val = target[key]; 24 | // add the missing property, or allow a null property to be updated 25 | if (val == null) { 26 | target[key] = value; 27 | } else if (lazy.isObject(val) && lazy.isObject(value)) { 28 | defaultsDeep(val, value); 29 | } 30 | }); 31 | } 32 | 33 | var len = arguments.length, i = 0; 34 | while (i < len) { 35 | var obj = arguments[i++]; 36 | if (obj) { 37 | copy(target, obj); 38 | } 39 | } 40 | return target; 41 | }; 42 | 43 | /** 44 | * Expose `defaultsDeep` 45 | */ 46 | 47 | module.exports = defaultsDeep; 48 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "defaults-deep", 3 | "description": "Like `extend` but recursively copies only the missing properties/values to the target object.", 4 | "version": "0.2.4", 5 | "homepage": "https://github.com/jonschlinkert/defaults-deep", 6 | "author": "Jon Schlinkert (https://github.com/jonschlinkert)", 7 | "repository": "jonschlinkert/defaults-deep", 8 | "bugs": { 9 | "url": "https://github.com/jonschlinkert/defaults-deep/issues" 10 | }, 11 | "license": "MIT", 12 | "files": [ 13 | "index.js" 14 | ], 15 | "main": "index.js", 16 | "engines": { 17 | "node": ">=0.10.0" 18 | }, 19 | "scripts": { 20 | "test": "mocha" 21 | }, 22 | "dependencies": { 23 | "for-own": "^0.1.3", 24 | "is-extendable": "^0.1.1", 25 | "lazy-cache": "^0.2.3" 26 | }, 27 | "devDependencies": { 28 | "mocha": "^3.5.3", 29 | "should": "^13.2.1" 30 | }, 31 | "keywords": [ 32 | "copy", 33 | "default", 34 | "defaults", 35 | "extend", 36 | "merge", 37 | "object", 38 | "properties", 39 | "property", 40 | "value", 41 | "values", 42 | "javascript", 43 | "js", 44 | "util", 45 | "utils" 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * defaults-deep 3 | * 4 | * Copyright (c) 2014-2015 Jon Schlinkert. 5 | * Licensed under the MIT License 6 | */ 7 | 8 | 'use strict'; 9 | 10 | /* deps: mocha */ 11 | require('should'); 12 | var deepDefaults = require('./'); 13 | 14 | describe('deep-defaults', function () { 15 | it('should copy only missing properties defaults', function () { 16 | deepDefaults({a: 'c'}, {a: 'bbb', d: 'c'}).should.eql({a: 'c', d: 'c'}); 17 | }); 18 | 19 | it('should copy properties from multiple objects', function () { 20 | deepDefaults({a: 'b'}, {c: 'd'}, {e: 'f'}).should.eql({a: 'b', c: 'd', e: 'f'}); 21 | }); 22 | 23 | it('should fill in values that are null', function () { 24 | deepDefaults({a: null}, {a: 'c', d: 'c'}).should.eql({a: 'c', d: 'c'}); 25 | }); 26 | 27 | it('should copy nested values.', function () { 28 | deepDefaults({a: {b: 'c'}}, {a: {d: 'e'}}).should.eql({a: {b: 'c', d: 'e'}}); 29 | }); 30 | 31 | it('should clone when an empty object is passed as the first arg.', function () { 32 | var obj = {}; 33 | deepDefaults(obj, {a: {b: 'c'}}, {a: {d: 'e'}}); 34 | obj.should.eql({a: {b: 'c', d: 'e'}}); 35 | }); 36 | 37 | it('should return an empty object when the first arg is null.', function () { 38 | deepDefaults(null).should.eql({}); 39 | }); 40 | }); 41 | --------------------------------------------------------------------------------