├── .eslintignore ├── test ├── mocha.opts ├── utils │ └── document.js └── index.spec.js ├── imgs └── ddm.png ├── .npmignore ├── .editorconfig ├── .travis.yml ├── .codeclimate.yml ├── dist ├── ddm.d.ts ├── ddm.min.js ├── ddm.js.map └── ddm.js ├── tsconfig.json ├── bower.json ├── .gitignore ├── webpack.config.js ├── LICENSE ├── package.json ├── README.md ├── src ├── ddm.ts └── index.js ├── .eslintrc └── lib └── index.js /.eslintignore: -------------------------------------------------------------------------------- 1 | **/*{.,-}min.js 2 | -------------------------------------------------------------------------------- /test/mocha.opts: -------------------------------------------------------------------------------- 1 | --compilers js:babel/register 2 | --recursive 3 | -------------------------------------------------------------------------------- /imgs/ddm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/ddm/master/imgs/ddm.png -------------------------------------------------------------------------------- /test/utils/document.js: -------------------------------------------------------------------------------- 1 | if (typeof document === 'undefined') { 2 | global.document = {}; 3 | } 4 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .codeclimate.yml 2 | .editorconfig 3 | .eslintignore 4 | .eslintrc 5 | .travis.yml 6 | webpack.config.js 7 | LICENSE 8 | test/ 9 | src/ 10 | imgs/ 11 | coverage/ 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | end_of_line = lf 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [*.md] 13 | insert_final_newline = false 14 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.10" 4 | - "4.0" 5 | - "5.0" 6 | - "6.0" 7 | 8 | notifications: 9 | email: false 10 | 11 | before_install: npm install -g codeclimate-test-reporter 12 | install: npm install 13 | script: npm run test:cov 14 | after_success: codeclimate < coverage/lcov.info 15 | -------------------------------------------------------------------------------- /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | --- 2 | engines: 3 | duplication: 4 | enabled: true 5 | config: 6 | languages: 7 | - javascript 8 | eslint: 9 | enabled: true 10 | fixme: 11 | enabled: true 12 | ratings: 13 | paths: 14 | - "src/*.js" 15 | exclude_paths: 16 | - test/ 17 | - examples/ 18 | - lib/*.js 19 | - dist/*.js 20 | -------------------------------------------------------------------------------- /dist/ddm.d.ts: -------------------------------------------------------------------------------- 1 | export declare class DDM { 2 | constructor(); 3 | from(originObject: any): this; 4 | get(keyArray: any): this; 5 | to(newObject: any): this; 6 | add(field: any, value: any): this; 7 | remove(field: any): this; 8 | handle(field: any, handle: any): this; 9 | replace(originField: any, newField: any): this; 10 | replaceWithHandle(originField: any, newField: any, handle: any): this; 11 | } 12 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "removeComments": false, 4 | "preserveConstEnums": true, 5 | "sourceMap": true, 6 | "declaration": true, 7 | "noImplicitAny": true, 8 | "noImplicitReturns": true, 9 | "suppressImplicitAnyIndexErrors": true, 10 | "target": "es6", 11 | "outDir": "dist" 12 | }, 13 | "formatCodeOptions": { 14 | "indentSize": 2, 15 | "tabSize": 2 16 | }, 17 | "files": [ 18 | "src/ddm.ts" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ddm", 3 | "description": "Domain Double Model", 4 | "main": "lib/index.js", 5 | "authors": [ 6 | "Phodal" 7 | ], 8 | "license": "MIT", 9 | "keywords": [ 10 | "Model", 11 | "ddd", 12 | "model", 13 | "design", 14 | "double" 15 | ], 16 | "homepage": "https://github.com/phodal/ddm", 17 | "ignore": [ 18 | "**/.*", 19 | "node_modules", 20 | "bower_components", 21 | "test", 22 | "imgs", 23 | "src", 24 | "webpack.config.js", 25 | "tests" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # nyc test coverage 18 | .nyc_output 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | 29 | # Dependency directories 30 | node_modules 31 | jspm_packages 32 | 33 | # Optional npm cache directory 34 | .npm 35 | 36 | # Optional REPL history 37 | .node_repl_history 38 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var webpack = require('webpack'); 4 | 5 | var plugins = [ 6 | new webpack.optimize.OccurenceOrderPlugin(), 7 | new webpack.DefinePlugin({ 8 | 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) 9 | }) 10 | ]; 11 | 12 | if (process.env.NODE_ENV === 'production') { 13 | plugins.push( 14 | new webpack.optimize.UglifyJsPlugin({ 15 | compressor: { 16 | screw_ie8: true, 17 | warnings: false 18 | } 19 | }) 20 | ); 21 | } 22 | 23 | module.exports = { 24 | module: { 25 | loaders: [{ 26 | test: /\.js$/, 27 | loaders: ['babel-loader'], 28 | exclude: /node_modules/ 29 | }] 30 | }, 31 | output: { 32 | libraryTarget: 'umd' 33 | }, 34 | plugins: plugins, 35 | resolve: { 36 | extensions: ['', '.js'] 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Fengda Huang 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 all 13 | 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 THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ddm", 3 | "version": "0.1.3", 4 | "description": "Domain Double Model", 5 | "main": "lib/index.js", 6 | "scripts": { 7 | "clean": "rimraf lib dist", 8 | "build": "babel src --out-dir lib", 9 | "build:umd": "webpack src/index.js dist/ddm.js && NODE_ENV=production webpack src/index.js dist/ddm.min.js", 10 | "lint": "eslint src", 11 | "test": "NODE_ENV=test mocha", 12 | "test:watch": "NODE_ENV=test mocha --watch", 13 | "test:cov": "babel-node ./node_modules/.bin/isparta cover ./node_modules/.bin/_mocha", 14 | "prepublish": "npm run lint && npm run test && npm run clean && npm run build && npm run build:umd" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "https://github.com/phodal/ddm.git" 19 | }, 20 | "keywords": [ 21 | "Model", 22 | "ddd", 23 | "model", 24 | "design", 25 | "double" 26 | ], 27 | "author": "Phodal", 28 | "license": "MIT", 29 | "bugs": { 30 | "url": "https://github.com/phodal/ddm/issues" 31 | }, 32 | "homepage": "https://github.com/phodal/ddm", 33 | "devDependencies": { 34 | "babel": "^5.5.8", 35 | "babel-core": "^5.6.18", 36 | "babel-eslint": "^3.1.15", 37 | "babel-loader": "^5.1.4", 38 | "eslint": "^0.23", 39 | "eslint-config-airbnb": "0.0.6", 40 | "eslint-plugin-react": "^2.3.0", 41 | "expect": "^1.6.0", 42 | "isparta": "^3.0.3", 43 | "mocha": "^2.2.5", 44 | "rimraf": "^2.3.4", 45 | "webpack": "^1.9.6", 46 | "webpack-dev-server": "^1.8.2" 47 | }, 48 | "dependencies": { 49 | "invariant": "^2.0.0" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /dist/ddm.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var n=t();for(var i in n)("object"==typeof exports?exports:e)[i]=n[i]}}(this,function(){return function(e){function t(i){if(n[i])return n[i].exports;var o=n[i]={exports:{},id:i,loaded:!1};return e[i].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e){if(!(e instanceof Object))return e;var t,n=e.constructor;t=new n;for(var o in e)t[o]=i(e[o]);return t}Object.defineProperty(t,"__esModule",{value:!0});var o=function(){function e(e,t){for(var n=0;n0,h=this.objectKeyForRemove.length>0,s=this.handleFunction.length>0;return t.call(this),u?n.call(this):o.call(this),h&&r.call(this),s&&c.call(this),this}},{key:"add",value:function(e,t){return this.objectForAdd[e]=t,this}},{key:"remove",value:function(e){return this.objectKeyForRemove.push(e),this}},{key:"handle",value:function(e,t){return this.handleFunction.push({field:e,handle:t}),this}},{key:"replace",value:function(e,t){return this.objectForAdd[t]=this.originObject[e],this.objectKeyForRemove.push(e),this}},{key:"replaceWithHandle",value:function(e,t,n){return this.objectForAdd[t]=this.originObject[e],this.objectKeyForRemove.push(e),this.handleFunction.push({field:t,handle:n}),this}}]),e}();t.DDM=r}])}); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Domain Double Model 2 | === 3 | 4 | [![Build Status](https://travis-ci.org/phodal/ddm.svg?branch=master)](https://travis-ci.org/phodal/ddm) 5 | [![Test Coverage](https://codeclimate.com/github/phodal/ddm/badges/coverage.svg)](https://codeclimate.com/github/phodal/ddm/coverage) 6 | [![Code Climate](https://codeclimate.com/github/phodal/ddm/badges/gpa.svg)](https://codeclimate.com/github/phodal/ddm) 7 | 8 | > A simple library for Front-End to create Bounded Context Model. 9 | 10 | Install 11 | --- 12 | 13 | Bower: 14 | 15 | ```bash 16 | bower install ddm 17 | ``` 18 | 19 | NPM: 20 | 21 | ```bash 22 | npm install ddm 23 | ``` 24 | 25 | Usage 26 | --- 27 | 28 | Usage: 29 | 30 | ```javascript 31 | var ddm = new DDM(); 32 | 33 | originObject = { 34 | title: 'hello', 35 | blog: 'fdsf asdf fadsf ', 36 | author: 'phodal' 37 | }; 38 | var newObject = {}; 39 | ``` 40 | 41 | Basic Example: 42 | 43 | 44 | ```javascript 45 | ddm.get(['title']).from(originObject).to(newObject); 46 | ``` 47 | 48 | Result 49 | 50 | > {title: "hello"} 51 | 52 | With Remove: 53 | 54 | ```javascript 55 | ddm.get(['title', 'blog', 'author']) 56 | .from(originObject) 57 | .remove('title') 58 | .to(newObject); 59 | ``` 60 | 61 | Result: 62 | 63 | > {blog: "fdsf asdf fadsf ", author: "phodal"} 64 | 65 | With Add: 66 | 67 | ```javascript 68 | ddm.get(['title']) 69 | .from(originObject) 70 | .add('tag', 'hello,world,linux') 71 | .to(newObject); 72 | ``` 73 | 74 | Result: 75 | 76 | > {tag: "hello,world,linux", title: "hello"} 77 | 78 | With Custom Handle: 79 | 80 | ```javascript 81 | function handler(blog) { 82 | return blog[0]; 83 | } 84 | 85 | ddm.get(['title', 'blog', 'author']) 86 | .from(originObject) 87 | .handle("blog", handler) 88 | .to(newObject); 89 | ``` 90 | 91 | Result: 92 | 93 | > {title: "hello", blog: "A", author: "phodal"} 94 | 95 | With Replace: 96 | 97 | ```javascript 98 | ddm.get(['title', 'blog', 'author']) 99 | .from(originObject) 100 | .replace("blog", "description") 101 | .to(newObject); 102 | ``` 103 | 104 | Result: 105 | 106 | > {description: "fdsf asdf fadsf ", title: "hello", author: "phodal"} 107 | 108 | DDM 109 | --- 110 | 111 | 112 | 对于我们的几个不同业务情景下,我们只使用同一个后台API的情形。如下图所示: 113 | 114 | ![Domain Double Model](./imgs/ddm.png) 115 | 116 | 在我们的Blog Model里,我们有``Author``、``Title``、``Slug``、``Content``、``Data``几个字段。 117 | 118 | 而在我们使用的时候,我们需要依据这个模型应用到不同的场景下: 119 | 120 | - 面向读者的Model,只有``Tag``、``Title``、``Author``、``Date``、``Content``五个字段。 121 | - 面向SEO时,只有``Tag``、``Title``、``Date``、基于``Content``的``Description``四个字段。 122 | - 面向RSS时,则有``Title``、``Author``、``Date``、``Content``、``Slug``五个字段。 123 | 124 | 如果我们使用的是同一个模型,那么我们就很难做到分离上下文。并且在三种不同的场景下,Blog Model的含义都是不一样的。 125 | 126 | 于是,我们就需要想办法去区分不同的模型——这在后台来说是一件很容易的事。但是在前台谁想这样做?在这其中使用复杂的OO思想? 127 | 128 | 所以,我们有了DDM。 129 | 130 | License 131 | --- 132 | 133 | [![Phodal's Idea](http://brand.phodal.com/shields/idea-small.svg)](http://ideas.phodal.com/) 134 | 135 | © 2016 [Phodal Huang](https://www.phodal.com). This code is distributed under the MIT License. See `LICENSE` in this directory. 136 | 137 | [![待我代码编成,娶你为妻可好](http://brand.phodal.com/slogan/slogan.svg)](http://www.xuntayizhan.com/person/ji-ke-ai-qing-zhi-er-shi-dai-wo-dai-ma-bian-cheng-qu-ni-wei-qi-ke-hao-wan/) 138 | 139 | -------------------------------------------------------------------------------- /dist/ddm.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"ddm.js","sourceRoot":"","sources":["../src/ddm.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,eAAe,gBAAgB;IAC7B,SAAS;IACT,EAAE,CAAC,CAAC,CAAC,CAAC,gBAAgB,YAAY,MAAM,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,gBAAgB,CAAC;IAC1B,CAAC;IAED,IAAI,WAAW,CAAC;IAEhB,8BAA8B;IAC9B,IAAI,WAAW,GAAG,gBAAgB,CAAC,WAAW,CAAC;IAC/C,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;IAEhC,uBAAuB;IACvB,GAAG,CAAC,CAAC,IAAI,IAAI,IAAI,gBAAgB,CAAC,CAAC,CAAC;QAClC,WAAW,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC;IACpD,CAAC;IAED,MAAM,CAAC,WAAW,CAAC;AACrB,CAAC;AAED;IACE;QACE,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,kBAAkB,GAAG,EAAE,CAAC;QAC7B,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;QACzB,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;IACzB,CAAC;IAED,IAAI,CAAC,YAAY;QACf,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC;QACxC,MAAM,CAAC,IAAI,CAAC;IACd,CAAC;;IAED,GAAG,CAAC,QAAQ;QACV,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;YACb,IAAI,CAAC,mBAAmB,GAAG,QAAQ,CAAC;QACtC,CAAC;QAAC,IAAI,CAAC,CAAC;YACN,IAAI,CAAC,mBAAmB,GAAG,EAAE,CAAC;QAChC,CAAC;QACD,MAAM,CAAC,IAAI,CAAC;IACd,CAAC;;IAED,EAAE,CAAC,SAAS;QACV;YACE,GAAG,CAAC,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;gBACnC,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC;QAED;YACE,GAAG,CAAC,CAAC,IAAI,GAAG,IAAI,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;gBACzC,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC;oBACzC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;gBAC1C,CAAC;gBAAC,IAAI,CAAC,CAAC;oBACN,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;gBACtB,CAAC;YACH,CAAC;QACH,CAAC;QAED;YACE,GAAG,CAAC,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;gBACnC,SAAS,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;YACnD,CAAC;QACH,CAAC;QAED;YACE,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACxD,OAAO,SAAS,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC;QAED;YACE,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACpD,IAAI,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;gBACzC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAA;YACpE,CAAC;QACH,CAAC;QAED,IAAI,oBAAoB,GAAG,IAAI,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC,CAAC;QAC/D,IAAI,iBAAiB,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC,CAAC;QAC3D,IAAI,eAAe,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC;QAErD,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1B,EAAE,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;YACzB,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,IAAI,CAAC,CAAC;YACN,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChC,CAAC;QAED,EAAE,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC;YACtB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;QAED,EAAE,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;YACpB,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;QAED,MAAM,CAAC,IAAI,CAAC;IACd,CAAC;;IAED,GAAG,CAAC,KAAK,EAAE,KAAK;QACd,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC;QACjC,MAAM,CAAC,IAAI,CAAC;IACd,CAAC;;IAED,MAAM,CAAC,KAAK;QACV,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC;IACd,CAAC;;IAED,MAAM,CAAC,KAAK,EAAE,MAAM;QAClB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;YACvB,KAAK,EAAE,KAAK;YACZ,MAAM,EAAE,MAAM;SACf,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CAAC,WAAW,EAAE,QAAQ;QAC3B,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;QAC7D,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC;IACd,CAAC;IAED,iBAAiB,CAAC,WAAW,EAAE,QAAQ,EAAE,MAAM;QAC7C,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;QAC7D,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC1C,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;YACvB,KAAK,EAAE,QAAQ;YACf,MAAM,EAAE,MAAM;SACf,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAAA"} -------------------------------------------------------------------------------- /src/ddm.ts: -------------------------------------------------------------------------------- 1 | // https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm 2 | function clone(objectToBeCloned) { 3 | // Basis. 4 | if (!(objectToBeCloned instanceof Object)) { 5 | return objectToBeCloned; 6 | } 7 | 8 | var objectClone; 9 | 10 | // Filter out special objects. 11 | var Constructor = objectToBeCloned.constructor; 12 | objectClone = new Constructor(); 13 | 14 | // Clone each property. 15 | for (var prop in objectToBeCloned) { 16 | objectClone[prop] = clone(objectToBeCloned[prop]); 17 | } 18 | 19 | return objectClone; 20 | } 21 | 22 | export class DDM { 23 | constructor() { 24 | this.objectForAdd = {}; 25 | this.objectKeyForRemove = []; 26 | this.handleFunction = []; 27 | this.originObject = {}; 28 | } 29 | 30 | from(originObject) { 31 | this.originObject = clone(originObject); 32 | return this; 33 | }; 34 | 35 | get(keyArray) { 36 | if (keyArray) { 37 | this.objectKeyFromOrigin = keyArray; 38 | } else { 39 | this.objectKeyFromOrigin = []; 40 | } 41 | return this; 42 | }; 43 | 44 | to(newObject) { 45 | function cloneAddObject() { 46 | for (var prop in this.objectForAdd) { 47 | newObject[prop] = this.objectForAdd[prop]; 48 | } 49 | } 50 | 51 | function cloneObjectByKey() { 52 | for (var key of this.objectKeyFromOrigin) { 53 | if (this.originObject[key] !== undefined) { 54 | newObject[key] = this.originObject[key]; 55 | } else { 56 | newObject[key] = ""; 57 | } 58 | } 59 | } 60 | 61 | function deepCloneAllObject() { 62 | for (var prop in this.originObject) { 63 | newObject[prop] = clone(this.originObject[prop]); 64 | } 65 | } 66 | 67 | function removeObject() { 68 | for (var i = 0; i < this.objectKeyForRemove.length; i++) { 69 | delete newObject[this.objectKeyForRemove[i]]; 70 | } 71 | } 72 | 73 | function addExtendHandle() { 74 | for (var i = 0; i < this.handleFunction.length; i++) { 75 | var field = this.handleFunction[i].field; 76 | newObject[field] = this.handleFunction[i].handle(newObject[field]) 77 | } 78 | } 79 | 80 | var haveObjectFromOrigin = this.objectKeyFromOrigin.length > 0; 81 | var hasRemovingObject = this.objectKeyForRemove.length > 0; 82 | var hasExtendHandle = this.handleFunction.length > 0; 83 | 84 | cloneAddObject.call(this); 85 | if (haveObjectFromOrigin) { 86 | cloneObjectByKey.call(this); 87 | } else { 88 | deepCloneAllObject.call(this); 89 | } 90 | 91 | if (hasRemovingObject) { 92 | removeObject.call(this); 93 | } 94 | 95 | if (hasExtendHandle) { 96 | addExtendHandle.call(this); 97 | } 98 | 99 | return this; 100 | }; 101 | 102 | add(field, value) { 103 | this.objectForAdd[field] = value; 104 | return this; 105 | }; 106 | 107 | remove(field) { 108 | this.objectKeyForRemove.push(field); 109 | return this; 110 | }; 111 | 112 | handle(field, handle) { 113 | this.handleFunction.push({ 114 | field: field, 115 | handle: handle 116 | }); 117 | return this; 118 | } 119 | 120 | replace(originField, newField) { 121 | this.objectForAdd[newField] = this.originObject[originField]; 122 | this.objectKeyForRemove.push(originField); 123 | return this; 124 | } 125 | 126 | replaceWithHandle(originField, newField, handle) { 127 | this.objectForAdd[newField] = this.originObject[originField]; 128 | this.objectKeyForRemove.push(originField); 129 | this.handleFunction.push({ 130 | field: newField, 131 | handle: handle 132 | }); 133 | return this; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | // https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm 2 | function clone(objectToBeCloned) { 3 | // Basis. 4 | if (!(objectToBeCloned instanceof Object)) { 5 | return objectToBeCloned; 6 | } 7 | 8 | var objectClone; 9 | 10 | // Filter out special objects. 11 | var Constructor = objectToBeCloned.constructor; 12 | objectClone = new Constructor(); 13 | 14 | // Clone each property. 15 | for (var prop in objectToBeCloned) { 16 | objectClone[prop] = clone(objectToBeCloned[prop]); 17 | } 18 | 19 | return objectClone; 20 | } 21 | 22 | export class DDM { 23 | constructor() { 24 | this.objectForAdd = {}; 25 | this.objectKeyForRemove = []; 26 | this.handleFunction = []; 27 | this.originObject = {}; 28 | } 29 | 30 | from(originObject) { 31 | this.originObject = clone(originObject); 32 | return this; 33 | }; 34 | 35 | get(keyArray) { 36 | if (keyArray) { 37 | this.objectKeyFromOrigin = keyArray; 38 | } else { 39 | this.objectKeyFromOrigin = []; 40 | } 41 | return this; 42 | }; 43 | 44 | to(newObject) { 45 | function cloneAddObject() { 46 | for (var prop in this.objectForAdd) { 47 | newObject[prop] = this.objectForAdd[prop]; 48 | } 49 | } 50 | 51 | function cloneObjectByKey() { 52 | for (var key of this.objectKeyFromOrigin) { 53 | if (this.originObject[key] !== undefined) { 54 | newObject[key] = this.originObject[key]; 55 | } else { 56 | newObject[key] = ""; 57 | } 58 | } 59 | } 60 | 61 | function deepCloneAllObject() { 62 | for (var prop in this.originObject) { 63 | newObject[prop] = clone(this.originObject[prop]); 64 | } 65 | } 66 | 67 | function removeObject() { 68 | for (var i = 0; i < this.objectKeyForRemove.length; i++) { 69 | delete newObject[this.objectKeyForRemove[i]]; 70 | } 71 | } 72 | 73 | function addExtendHandle() { 74 | for (var i = 0; i < this.handleFunction.length; i++) { 75 | var field = this.handleFunction[i].field; 76 | newObject[field] = this.handleFunction[i].handle(newObject[field]) 77 | } 78 | } 79 | 80 | var haveObjectFromOrigin = this.objectKeyFromOrigin.length > 0; 81 | var hasRemovingObject = this.objectKeyForRemove.length > 0; 82 | var hasExtendHandle = this.handleFunction.length > 0; 83 | 84 | cloneAddObject.call(this); 85 | if (haveObjectFromOrigin) { 86 | cloneObjectByKey.call(this); 87 | } else { 88 | deepCloneAllObject.call(this); 89 | } 90 | 91 | if (hasRemovingObject) { 92 | removeObject.call(this); 93 | } 94 | 95 | if (hasExtendHandle) { 96 | addExtendHandle.call(this); 97 | } 98 | 99 | return this; 100 | }; 101 | 102 | add(field, value) { 103 | this.objectForAdd[field] = value; 104 | return this; 105 | }; 106 | 107 | remove(field) { 108 | this.objectKeyForRemove.push(field); 109 | return this; 110 | }; 111 | 112 | handle(field, handle) { 113 | this.handleFunction.push({ 114 | field: field, 115 | handle: handle 116 | }); 117 | return this; 118 | } 119 | 120 | replace(originField, newField) { 121 | this.objectForAdd[newField] = this.originObject[originField]; 122 | this.objectKeyForRemove.push(originField); 123 | return this; 124 | } 125 | 126 | replaceWithHandle(originField, newField, handle) { 127 | this.objectForAdd[newField] = this.originObject[originField]; 128 | this.objectKeyForRemove.push(originField); 129 | this.handleFunction.push({ 130 | field: newField, 131 | handle: handle 132 | }); 133 | return this; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /dist/ddm.js: -------------------------------------------------------------------------------- 1 | // https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm 2 | function clone(objectToBeCloned) { 3 | // Basis. 4 | if (!(objectToBeCloned instanceof Object)) { 5 | return objectToBeCloned; 6 | } 7 | var objectClone; 8 | // Filter out special objects. 9 | var Constructor = objectToBeCloned.constructor; 10 | objectClone = new Constructor(); 11 | // Clone each property. 12 | for (var prop in objectToBeCloned) { 13 | objectClone[prop] = clone(objectToBeCloned[prop]); 14 | } 15 | return objectClone; 16 | } 17 | export class DDM { 18 | constructor() { 19 | this.objectForAdd = {}; 20 | this.objectKeyForRemove = []; 21 | this.handleFunction = []; 22 | this.originObject = {}; 23 | } 24 | from(originObject) { 25 | this.originObject = clone(originObject); 26 | return this; 27 | } 28 | ; 29 | get(keyArray) { 30 | if (keyArray) { 31 | this.objectKeyFromOrigin = keyArray; 32 | } 33 | else { 34 | this.objectKeyFromOrigin = []; 35 | } 36 | return this; 37 | } 38 | ; 39 | to(newObject) { 40 | function cloneAddObject() { 41 | for (var prop in this.objectForAdd) { 42 | newObject[prop] = this.objectForAdd[prop]; 43 | } 44 | } 45 | function cloneObjectByKey() { 46 | for (var key of this.objectKeyFromOrigin) { 47 | if (this.originObject[key] !== undefined) { 48 | newObject[key] = this.originObject[key]; 49 | } 50 | else { 51 | newObject[key] = ""; 52 | } 53 | } 54 | } 55 | function deepCloneAllObject() { 56 | for (var prop in this.originObject) { 57 | newObject[prop] = clone(this.originObject[prop]); 58 | } 59 | } 60 | function removeObject() { 61 | for (var i = 0; i < this.objectKeyForRemove.length; i++) { 62 | delete newObject[this.objectKeyForRemove[i]]; 63 | } 64 | } 65 | function addExtendHandle() { 66 | for (var i = 0; i < this.handleFunction.length; i++) { 67 | var field = this.handleFunction[i].field; 68 | newObject[field] = this.handleFunction[i].handle(newObject[field]); 69 | } 70 | } 71 | var haveObjectFromOrigin = this.objectKeyFromOrigin.length > 0; 72 | var hasRemovingObject = this.objectKeyForRemove.length > 0; 73 | var hasExtendHandle = this.handleFunction.length > 0; 74 | cloneAddObject.call(this); 75 | if (haveObjectFromOrigin) { 76 | cloneObjectByKey.call(this); 77 | } 78 | else { 79 | deepCloneAllObject.call(this); 80 | } 81 | if (hasRemovingObject) { 82 | removeObject.call(this); 83 | } 84 | if (hasExtendHandle) { 85 | addExtendHandle.call(this); 86 | } 87 | return this; 88 | } 89 | ; 90 | add(field, value) { 91 | this.objectForAdd[field] = value; 92 | return this; 93 | } 94 | ; 95 | remove(field) { 96 | this.objectKeyForRemove.push(field); 97 | return this; 98 | } 99 | ; 100 | handle(field, handle) { 101 | this.handleFunction.push({ 102 | field: field, 103 | handle: handle 104 | }); 105 | return this; 106 | } 107 | replace(originField, newField) { 108 | this.objectForAdd[newField] = this.originObject[originField]; 109 | this.objectKeyForRemove.push(originField); 110 | return this; 111 | } 112 | replaceWithHandle(originField, newField, handle) { 113 | this.objectForAdd[newField] = this.originObject[originField]; 114 | this.objectKeyForRemove.push(originField); 115 | this.handleFunction.push({ 116 | field: newField, 117 | handle: handle 118 | }); 119 | return this; 120 | } 121 | } 122 | //# sourceMappingURL=ddm.js.map -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "ecmaFeatures": { 3 | "modules": true, 4 | "jsx": true 5 | }, 6 | "env": { 7 | "amd": true, 8 | "browser": true, 9 | "es6": true, 10 | "jquery": true, 11 | "node": true 12 | }, 13 | "rules": { 14 | "comma-dangle": [ 15 | 2, 16 | "never" 17 | ], 18 | "no-cond-assign": 2, 19 | "no-console": 0, 20 | "no-constant-condition": 2, 21 | "no-control-regex": 2, 22 | "no-debugger": 2, 23 | "no-dupe-args": 2, 24 | "no-dupe-keys": 2, 25 | "no-duplicate-case": 2, 26 | "no-empty": 2, 27 | "no-empty-character-class": 2, 28 | "no-ex-assign": 2, 29 | "no-extra-boolean-cast": 2, 30 | "no-extra-parens": 0, 31 | "no-extra-semi": 2, 32 | "no-func-assign": 2, 33 | "no-inner-declarations": [ 34 | 2, 35 | "functions" 36 | ], 37 | "no-invalid-regexp": 2, 38 | "no-irregular-whitespace": 2, 39 | "no-negated-in-lhs": 2, 40 | "no-obj-calls": 2, 41 | "no-regex-spaces": 2, 42 | "no-sparse-arrays": 2, 43 | "no-unreachable": 2, 44 | "use-isnan": 2, 45 | "valid-jsdoc": 0, 46 | "valid-typeof": 2, 47 | "accessor-pairs": 2, 48 | "block-scoped-var": 0, 49 | "complexity": [ 50 | 2, 51 | 6 52 | ], 53 | "consistent-return": 0, 54 | "curly": 0, 55 | "default-case": 0, 56 | "dot-location": 0, 57 | "dot-notation": 0, 58 | "eqeqeq": 2, 59 | "no-alert": 2, 60 | "no-caller": 2, 61 | "no-div-regex": 2, 62 | "no-else-return": 0, 63 | "no-empty-label": 2, 64 | "no-eq-null": 2, 65 | "no-eval": 2, 66 | "no-extend-native": 2, 67 | "no-extra-bind": 2, 68 | "no-fallthrough": 2, 69 | "no-floating-decimal": 0, 70 | "no-implicit-coercion": 0, 71 | "no-implied-eval": 2, 72 | "no-invalid-this": 0, 73 | "no-iterator": 2, 74 | "no-labels": 0, 75 | "no-lone-blocks": 2, 76 | "no-loop-func": 2, 77 | "no-magic-number": 0, 78 | "no-multi-spaces": 0, 79 | "no-multi-str": 0, 80 | "no-native-reassign": 2, 81 | "no-new-func": 2, 82 | "no-new-wrappers": 2, 83 | "no-new": 2, 84 | "no-octal-escape": 2, 85 | "no-octal": 2, 86 | "no-proto": 2, 87 | "no-redeclare": 2, 88 | "no-return-assign": 2, 89 | "no-script-url": 2, 90 | "no-self-compare": 2, 91 | "no-sequences": 0, 92 | "no-throw-literal": 0, 93 | "no-unused-expressions": 2, 94 | "no-void": 2, 95 | "no-warning-comments": 0, 96 | "no-with": 2, 97 | "radix": 2, 98 | "vars-on-top": 0, 99 | "wrap-iife": 2, 100 | "yoda": 0, 101 | "strict": 0, 102 | "init-declarations": 0, 103 | "no-catch-shadow": 2, 104 | "no-delete-var": 2, 105 | "no-label-var": 2, 106 | "no-shadow-restricted-names": 2, 107 | "no-shadow": 0, 108 | "no-undef-init": 2, 109 | "no-undef": 0, 110 | "no-undefined": 0, 111 | "no-unused-vars": 0, 112 | "no-use-before-define": 0, 113 | "handle-callback-err": 2, 114 | "no-mixed-requires": 0, 115 | "no-new-require": 0, 116 | "no-path-concat": 2, 117 | "no-process-exit": 2, 118 | "no-restricted-modules": 0, 119 | "no-sync": 0, 120 | "array-bracket-spacing": 0, 121 | "block-spacing": 0, 122 | "brace-style": 0, 123 | "camelcase": 0, 124 | "comma-spacing": 0, 125 | "comma-style": 0, 126 | "computed-property-spacing": 0, 127 | "consistent-this": 0, 128 | "eol-last": 0, 129 | "func-names": 0, 130 | "func-style": 0, 131 | "id-length": 0, 132 | "id-match": 0, 133 | "indent": 0, 134 | "jsx-quotes": 0, 135 | "key-spacing": 0, 136 | "linebreak-style": 0, 137 | "lines-around-comment": 0, 138 | "max-depth": 0, 139 | "max-len": 0, 140 | "max-nested-callbacks": 0, 141 | "max-params": 0, 142 | "max-statements": [ 143 | 2, 144 | 30 145 | ], 146 | "new-cap": 0, 147 | "new-parens": 0, 148 | "newline-after-var": 0, 149 | "no-array-constructor": 0, 150 | "no-bitwise": 0, 151 | "no-continue": 0, 152 | "no-inline-comments": 0, 153 | "no-lonely-if": 0, 154 | "no-mixed-spaces-and-tabs": 0, 155 | "no-multiple-empty-lines": 0, 156 | "no-negated-condition": 0, 157 | "no-nested-ternary": 0, 158 | "no-new-object": 0, 159 | "no-plusplus": 0, 160 | "no-restricted-syntax": 0, 161 | "no-spaced-func": 0, 162 | "no-ternary": 0, 163 | "no-trailing-spaces": 0, 164 | "no-underscore-dangle": 0, 165 | "no-unneeded-ternary": 0, 166 | "object-curly-spacing": 0, 167 | "one-var": 0, 168 | "operator-assignment": 0, 169 | "operator-linebreak": 0, 170 | "padded-blocks": 0, 171 | "quote-props": 0, 172 | "quotes": 0, 173 | "require-jsdoc": 0, 174 | "semi-spacing": 0, 175 | "semi": 0, 176 | "sort-vars": 0, 177 | "space-after-keywords": 0, 178 | "space-before-blocks": 0, 179 | "space-before-function-paren": 0, 180 | "space-before-keywords": 0, 181 | "space-in-parens": 0, 182 | "space-infix-ops": 0, 183 | "space-return-throw-case": 0, 184 | "space-unary-ops": 0, 185 | "spaced-comment": 0, 186 | "wrap-regex": 0, 187 | "arrow-body-style": 0, 188 | "arrow-parens": 0, 189 | "arrow-spacing": 0, 190 | "constructor-super": 0, 191 | "generator-star-spacing": 0, 192 | "no-arrow-condition": 0, 193 | "no-class-assign": 0, 194 | "no-const-assign": 0, 195 | "no-dupe-class-members": 0, 196 | "no-this-before-super": 0, 197 | "no-var": 0, 198 | "object-shorthand": 0, 199 | "prefer-arrow-callback": 0, 200 | "prefer-const": 0, 201 | "prefer-reflect": 0, 202 | "prefer-spread": 0, 203 | "prefer-template": 0, 204 | "require-yield": 0 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | // https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm 2 | "use strict"; 3 | 4 | Object.defineProperty(exports, "__esModule", { 5 | value: true 6 | }); 7 | 8 | var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); 9 | 10 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 11 | 12 | function clone(objectToBeCloned) { 13 | // Basis. 14 | if (!(objectToBeCloned instanceof Object)) { 15 | return objectToBeCloned; 16 | } 17 | 18 | var objectClone; 19 | 20 | // Filter out special objects. 21 | var Constructor = objectToBeCloned.constructor; 22 | objectClone = new Constructor(); 23 | 24 | // Clone each property. 25 | for (var prop in objectToBeCloned) { 26 | objectClone[prop] = clone(objectToBeCloned[prop]); 27 | } 28 | 29 | return objectClone; 30 | } 31 | 32 | var DDM = (function () { 33 | function DDM() { 34 | _classCallCheck(this, DDM); 35 | 36 | this.objectForAdd = {}; 37 | this.objectKeyForRemove = []; 38 | this.handleFunction = []; 39 | this.originObject = {}; 40 | } 41 | 42 | _createClass(DDM, [{ 43 | key: "from", 44 | value: function from(originObject) { 45 | this.originObject = clone(originObject); 46 | return this; 47 | } 48 | }, { 49 | key: "get", 50 | value: function get(keyArray) { 51 | if (keyArray) { 52 | this.objectKeyFromOrigin = keyArray; 53 | } else { 54 | this.objectKeyFromOrigin = []; 55 | } 56 | return this; 57 | } 58 | }, { 59 | key: "to", 60 | value: function to(newObject) { 61 | function cloneAddObject() { 62 | for (var prop in this.objectForAdd) { 63 | newObject[prop] = this.objectForAdd[prop]; 64 | } 65 | } 66 | 67 | function cloneObjectByKey() { 68 | var _iteratorNormalCompletion = true; 69 | var _didIteratorError = false; 70 | var _iteratorError = undefined; 71 | 72 | try { 73 | for (var _iterator = this.objectKeyFromOrigin[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { 74 | var key = _step.value; 75 | 76 | if (this.originObject[key] !== undefined) { 77 | newObject[key] = this.originObject[key]; 78 | } else { 79 | newObject[key] = ""; 80 | } 81 | } 82 | } catch (err) { 83 | _didIteratorError = true; 84 | _iteratorError = err; 85 | } finally { 86 | try { 87 | if (!_iteratorNormalCompletion && _iterator["return"]) { 88 | _iterator["return"](); 89 | } 90 | } finally { 91 | if (_didIteratorError) { 92 | throw _iteratorError; 93 | } 94 | } 95 | } 96 | } 97 | 98 | function deepCloneAllObject() { 99 | for (var prop in this.originObject) { 100 | newObject[prop] = clone(this.originObject[prop]); 101 | } 102 | } 103 | 104 | function removeObject() { 105 | for (var i = 0; i < this.objectKeyForRemove.length; i++) { 106 | delete newObject[this.objectKeyForRemove[i]]; 107 | } 108 | } 109 | 110 | function addExtendHandle() { 111 | for (var i = 0; i < this.handleFunction.length; i++) { 112 | var field = this.handleFunction[i].field; 113 | newObject[field] = this.handleFunction[i].handle(newObject[field]); 114 | } 115 | } 116 | 117 | var haveObjectFromOrigin = this.objectKeyFromOrigin.length > 0; 118 | var hasRemovingObject = this.objectKeyForRemove.length > 0; 119 | var hasExtendHandle = this.handleFunction.length > 0; 120 | 121 | cloneAddObject.call(this); 122 | if (haveObjectFromOrigin) { 123 | cloneObjectByKey.call(this); 124 | } else { 125 | deepCloneAllObject.call(this); 126 | } 127 | 128 | if (hasRemovingObject) { 129 | removeObject.call(this); 130 | } 131 | 132 | if (hasExtendHandle) { 133 | addExtendHandle.call(this); 134 | } 135 | 136 | return this; 137 | } 138 | }, { 139 | key: "add", 140 | value: function add(field, value) { 141 | this.objectForAdd[field] = value; 142 | return this; 143 | } 144 | }, { 145 | key: "remove", 146 | value: function remove(field) { 147 | this.objectKeyForRemove.push(field); 148 | return this; 149 | } 150 | }, { 151 | key: "handle", 152 | value: function handle(field, _handle) { 153 | this.handleFunction.push({ 154 | field: field, 155 | handle: _handle 156 | }); 157 | return this; 158 | } 159 | }, { 160 | key: "replace", 161 | value: function replace(originField, newField) { 162 | this.objectForAdd[newField] = this.originObject[originField]; 163 | this.objectKeyForRemove.push(originField); 164 | return this; 165 | } 166 | }, { 167 | key: "replaceWithHandle", 168 | value: function replaceWithHandle(originField, newField, handle) { 169 | this.objectForAdd[newField] = this.originObject[originField]; 170 | this.objectKeyForRemove.push(originField); 171 | this.handleFunction.push({ 172 | field: newField, 173 | handle: handle 174 | }); 175 | return this; 176 | } 177 | }]); 178 | 179 | return DDM; 180 | })(); 181 | 182 | exports.DDM = DDM; -------------------------------------------------------------------------------- /test/index.spec.js: -------------------------------------------------------------------------------- 1 | import expect from 'expect'; 2 | import {DDM} from '../src'; 3 | 4 | describe('Get', () => { 5 | var originObject; 6 | 7 | beforeEach(function() { 8 | originObject = { 9 | title: 'hello', 10 | blog: 'fdsf asdf fadsf ', 11 | author: 'phodal' 12 | }; 13 | }); 14 | 15 | it('should return 1 object', () => { 16 | let ddm = new DDM(); 17 | 18 | var newObject = {}; 19 | ddm.get(['title']).from(originObject).to(newObject); 20 | expect(newObject.title).toBe("hello"); 21 | expect(newObject.author).toBe(undefined); 22 | }); 23 | 24 | it('should return correct object', () => { 25 | let ddm = new DDM(); 26 | 27 | var newObject = {}; 28 | ddm.get(['title', 'author']).from(originObject).to(newObject); 29 | expect(newObject.title).toBe("hello"); 30 | expect(newObject.author).toBe("phodal"); 31 | }); 32 | 33 | it('should return all objects when get array empty', () => { 34 | let ddm = new DDM(); 35 | 36 | var newObject = {}; 37 | ddm.get().from(originObject).to(newObject); 38 | expect(newObject.title).toBe("hello"); 39 | expect(newObject.author).toBe("phodal"); 40 | expect(newObject.blog).toBe("fdsf asdf fadsf "); 41 | }); 42 | 43 | it('should return empty results when get no exist empty', () => { 44 | let ddm = new DDM(); 45 | 46 | var newObject = {}; 47 | ddm.get(['tag']).from(originObject).to(newObject); 48 | expect(newObject.tag).toBe(""); 49 | }); 50 | }); 51 | 52 | describe('Add', () => { 53 | var originObject; 54 | 55 | beforeEach(function() { 56 | originObject = { 57 | title: 'hello', 58 | blog: 'fdsf asdf fadsf ', 59 | author: 'phodal' 60 | }; 61 | }); 62 | 63 | it('should return 1 object', () => { 64 | let ddm = new DDM(); 65 | 66 | var newObject = {}; 67 | ddm.get(['title']) 68 | .from(originObject) 69 | .add('tag', 'hello,world,linux') 70 | .to(newObject); 71 | expect(newObject.tag).toBe("hello,world,linux"); 72 | expect(newObject.title).toBe("hello"); 73 | expect(newObject.author).toBe(undefined); 74 | }); 75 | 76 | it('should cover origin object when have same key', () => { 77 | let ddm = new DDM(); 78 | 79 | var newObject = {}; 80 | ddm.get(['title']) 81 | .from(originObject) 82 | .add('blog', 'hello,world,linux') 83 | .to(newObject); 84 | expect(newObject.blog).toBe("hello,world,linux"); 85 | }); 86 | }); 87 | 88 | describe('Remove', () => { 89 | var originObject; 90 | 91 | beforeEach(function() { 92 | originObject = { 93 | title: 'hello', 94 | blog: 'fdsf asdf fadsf ', 95 | author: 'phodal' 96 | }; 97 | }); 98 | 99 | it('should return 1 object', () => { 100 | let ddm = new DDM(); 101 | 102 | var newObject = {}; 103 | ddm.get(['title', 'blog', 'author']) 104 | .from(originObject) 105 | .remove('title') 106 | .to(newObject); 107 | expect(newObject.title).toBe(undefined); 108 | }); 109 | }); 110 | 111 | describe('Handle', () => { 112 | var originObject; 113 | 114 | beforeEach(function() { 115 | originObject = { 116 | title: 'hello', 117 | blog: 'AAAAAAAAAAAA BBBBBBBBBBBB CCCCCCCCCCCCC DDDDDDDDDDDDDDD', 118 | author: 'phodal' 119 | }; 120 | }); 121 | 122 | it('should able to add custom handle event', () => { 123 | let ddm = new DDM(); 124 | 125 | var newObject = {}; 126 | 127 | function handler(blog) { 128 | return blog[0]; 129 | } 130 | 131 | ddm.get(['title', 'blog', 'author']) 132 | .from(originObject) 133 | .handle("blog", handler) 134 | .to(newObject); 135 | expect(newObject.blog).toBe('A'); 136 | }); 137 | 138 | it('should able to add custom multi handle event', () => { 139 | let ddm = new DDM(); 140 | 141 | var newObject = {}; 142 | 143 | function handler(blog) { 144 | return blog[0]; 145 | } 146 | 147 | ddm.get(['title', 'blog', 'author']) 148 | .from(originObject) 149 | .handle("blog", handler) 150 | .handle("title", handler) 151 | .to(newObject); 152 | expect(newObject.blog).toBe('A'); 153 | expect(newObject.title).toBe('h'); 154 | }); 155 | }); 156 | 157 | describe('Replace', () => { 158 | var originObject; 159 | 160 | beforeEach(function() { 161 | originObject = { 162 | title: 'hello', 163 | blog: 'AAAAAAAAAAAAAAA', 164 | author: 'phodal' 165 | }; 166 | }); 167 | 168 | it('should be able to replace field', () => { 169 | let ddm = new DDM(); 170 | 171 | var newObject = {}; 172 | 173 | ddm.get(['title', 'blog', 'author']) 174 | .from(originObject) 175 | .replace("blog", "description") 176 | .to(newObject); 177 | expect(newObject.description).toBe('AAAAAAAAAAAAAAA'); 178 | expect(newObject.blog).toBe(undefined); 179 | 180 | expect(JSON.stringify(newObject)).toBe('{"description":"AAAAAAAAAAAAAAA","title":"hello","author":"phodal"}'); 181 | }); 182 | }); 183 | 184 | describe('ReplaceWithHandle', () => { 185 | var originObject; 186 | 187 | beforeEach(function() { 188 | originObject = { 189 | title: 'hello', 190 | blog: 'AAAAAAAAAAAAAAA', 191 | author: 'phodal' 192 | }; 193 | }); 194 | 195 | it('should able to add custom handle event', () => { 196 | let ddm = new DDM(); 197 | 198 | var newObject = {}; 199 | 200 | function handler(blog) { 201 | return blog[0]; 202 | } 203 | 204 | ddm.get(['title', 'blog', 'author']) 205 | .from(originObject) 206 | .replaceWithHandle("blog", "description", handler) 207 | .to(newObject); 208 | expect(newObject.description).toBe('A'); 209 | expect(newObject.blog).toBe(undefined); 210 | 211 | expect(JSON.stringify(newObject)).toBe('{"description":"A","title":"hello","author":"phodal"}'); 212 | }); 213 | }); 214 | 215 | describe('Complex', () => { 216 | var originObject; 217 | 218 | beforeEach(function() { 219 | originObject = { 220 | title: 'hello', 221 | content: 'AAAAAAAAAAAAAAA', 222 | author: 'phodal', 223 | date: '2016-03-02' 224 | }; 225 | }); 226 | 227 | it('should able to test with multi case', () => { 228 | let ddm = new DDM(); 229 | 230 | var newObject = {}; 231 | 232 | function handler(blog) { 233 | return blog[0]; 234 | } 235 | 236 | ddm.get(['title', 'content', 'author', 'date']) 237 | .from(originObject) 238 | .add('tag', 'zzz') 239 | .remove('title') 240 | .replace('date', 'publishdate') 241 | .replaceWithHandle("content", "description", handler) 242 | .to(newObject); 243 | expect(newObject.description).toBe('A'); 244 | expect(newObject.tag).toBe('zzz'); 245 | expect(newObject.blog).toBe(undefined); 246 | expect(newObject.content).toBe(undefined); 247 | expect(newObject.date).toBe(undefined); 248 | expect(newObject.publishdate).toBe("2016-03-02"); 249 | 250 | expect(JSON.stringify(newObject)).toBe('{"tag":"zzz","publishdate":"2016-03-02","description":"A","author":"phodal"}'); 251 | }); 252 | }); 253 | --------------------------------------------------------------------------------