From 1935ed3c34f9510b72c585be06b774ac3aa91695 Mon Sep 17 00:00:00 2001 From: Gillian Perard Date: Mon, 15 Apr 2019 23:02:01 +0200 Subject: [PATCH 1/5] Fix ts config --- .gitignore | 2 +- .npmignore | 10 +++++++++- README.md | 2 ++ examples/models/snake.ts | 1 - examples/models/zoo.ts | 2 +- package.json | 12 ++++++------ spec/index.spec.ts | 4 ++-- tsconfig.json | 2 ++ tslint.json | 1 - 9 files changed, 23 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index b98d35d..f7ddfb8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ # Compiled -dist +**/dist # Logs logs diff --git a/.npmignore b/.npmignore index 2140838..f10104c 100644 --- a/.npmignore +++ b/.npmignore @@ -1,3 +1,11 @@ src/ coverage/ -examples/ \ No newline at end of file +examples/ +spec/ +.travis.yml +gulpfile.js +tsconfig.json +tslint.json +yarn.lock +dist/examples +dist/spec \ No newline at end of file diff --git a/README.md b/README.md index b41f4e9..965ac3a 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,8 @@ For example: "moduleResolution": "node", "emitDecoratorMetadata": true, "experimentalDecorators": true, + "noUnusedLocals": true, + "noUnusedParameters": true, "target": "es5", "typeRoots": [ "node_modules/@types" diff --git a/examples/models/snake.ts b/examples/models/snake.ts index 019e316..d4e00d2 100644 --- a/examples/models/snake.ts +++ b/examples/models/snake.ts @@ -1,4 +1,3 @@ -import { Serializable, JsonProperty } from './../../src'; import { Animal } from './animal'; export class Snake extends Animal { diff --git a/examples/models/zoo.ts b/examples/models/zoo.ts index c9f355a..ebc2ea2 100644 --- a/examples/models/zoo.ts +++ b/examples/models/zoo.ts @@ -1,5 +1,5 @@ import { Serializable, JsonProperty } from './../../src'; -import { Animal } from './animal'; + import { Employee } from './employee'; import { Panther } from './panther'; diff --git a/package.json b/package.json index 8050112..0aca13c 100644 --- a/package.json +++ b/package.json @@ -32,18 +32,18 @@ }, "devDependencies": { "@types/mocha": "^5.2.6", - "@types/node": "^11.12.1", + "@types/node": "^11.13.4", "chai": "^4.2.0", "coveralls": "^3.0.3", - "del": "^4.0.0", + "del": "^4.1.0", "gulp": "^4.0.0", "gulp-tslint": "^8.1.4", "gulp-typescript": "^5.0.1", "istanbul": "^0.4.5", - "mocha": "^6.0.2", + "mocha": "^6.1.3", "rewire": "^4.0.1", - "ts-node": "^8.0.3", - "tslint": "^5.14.0", - "typescript": "^3.3.4000" + "ts-node": "^8.1.0", + "tslint": "^5.15.0", + "typescript": "^3.4.3" } } diff --git a/spec/index.spec.ts b/spec/index.spec.ts index b5c9548..9cc75f6 100644 --- a/spec/index.spec.ts +++ b/spec/index.spec.ts @@ -1,11 +1,11 @@ import { expect } from 'chai'; -import { JsonProperty, Serializable, serialize, deserialize } from '../src/index'; +import { serialize, deserialize } from '../src/index'; -import { Employee } from '../examples/models/employee'; import { Panther } from '../examples/models/panther'; import { Snake } from '../examples/models/snake'; import { Zoo } from '../examples/models/zoo'; + import { data, deserializedData } from '../examples/json/data'; import 'reflect-metadata'; diff --git a/tsconfig.json b/tsconfig.json index ef930ec..869ef5a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,6 +7,8 @@ "moduleResolution": "node", "emitDecoratorMetadata": true, "experimentalDecorators": true, + "noUnusedLocals": true, + "noUnusedParameters": true, "target": "es5", "typeRoots": [ "node_modules/@types" diff --git a/tslint.json b/tslint.json index 3957a0d..d447fa3 100644 --- a/tslint.json +++ b/tslint.json @@ -132,7 +132,6 @@ "check-separator", "check-type" ], - "no-unused-variable": true, "no-duplicate-imports": true, "prefer-readonly": true, "trailing-comma": [ From 941dfd4a78eb53558a9f8029664e11129e97925d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gillian=20Pe=CC=81rard?= Date: Wed, 17 Apr 2019 13:39:47 +0200 Subject: [PATCH 2/5] Remove lodash from spec and add missing dev dependencies --- package.json | 4 +- spec/index.spec.ts | 7 +- yarn.lock | 206 +++++++++++++++++++++++++++++++++------------ 3 files changed, 157 insertions(+), 60 deletions(-) diff --git a/package.json b/package.json index 0aca13c..47ba3c0 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "scripts": { "build": "gulp build", "test": "yarn build && mocha -r ts-node/register dist/spec/**/*.spec.js", - "cover": "yarn build && istanbul cover node_modules/mocha/bin/_mocha dist/spec/**/*.spec.js -- -R spec" + "cover": "yarn build && istanbul cover node_modules/mocha/bin/_mocha dist/spec/**/*.spec.js -- -R spec", + "lint": "./node_modules/tslint/bin/tslint -p tsconfig.json" }, "repository": { "type": "git", @@ -31,6 +32,7 @@ "reflect-metadata": "^0.1.13" }, "devDependencies": { + "@types/chai": "^4.1.7", "@types/mocha": "^5.2.6", "@types/node": "^11.13.4", "chai": "^4.2.0", diff --git a/spec/index.spec.ts b/spec/index.spec.ts index 9cc75f6..51fe84f 100644 --- a/spec/index.spec.ts +++ b/spec/index.spec.ts @@ -1,4 +1,6 @@ import { expect } from 'chai'; +import 'reflect-metadata'; +import * as rewire from 'rewire'; import { serialize, deserialize } from '../src/index'; @@ -8,9 +10,6 @@ import { Zoo } from '../examples/models/zoo'; import { data, deserializedData } from '../examples/json/data'; -import 'reflect-metadata'; -import * as _ from 'lodash'; -const rewire: any = require('rewire'); const tjs: any = rewire('../src/index'); describe('Serializable', () => { @@ -43,7 +42,7 @@ describe('serialize', () => { it('should return 3', () => { const result: any = serialize(deserializedData, false); let count: number = 0; - _.forEach(result.Panthers, (panther: any) => { + result.Panthers.forEach((panther: any) => { if (panther.hasOwnProperty('childrenIdentifiers')) { count++; } diff --git a/yarn.lock b/yarn.lock index e9ec428..80c4045 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,27 @@ # yarn lockfile v1 +"@babel/code-frame@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" + integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA== + dependencies: + "@babel/highlight" "^7.0.0" + +"@babel/highlight@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4" + integrity sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw== + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^4.0.0" + +"@types/chai@^4.1.7": + version "4.1.7" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.1.7.tgz#1b8e33b61a8c09cbe1f85133071baa0dbf9fa71a" + integrity sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA== + "@types/fancy-log@1.3.0": version "1.3.0" resolved "https://registry.yarnpkg.com/@types/fancy-log/-/fancy-log-1.3.0.tgz#a61ab476e5e628cd07a846330df53b85e05c8ce0" @@ -12,10 +33,10 @@ resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.6.tgz#b8622d50557dd155e9f2f634b7d68fd38de5e94b" integrity sha512-1axi39YdtBI7z957vdqXI4Ac25e7YihYQtJa+Clnxg1zTJEaIRbndt71O3sP4GAMgiAm0pY26/b9BrY4MR/PMw== -"@types/node@^11.12.1": - version "11.12.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-11.12.1.tgz#d90123f6c61fdf2f7cddd286ddae891586dd3488" - integrity sha512-sKDlqv6COJrR7ar0+GqqhrXQDzQlMcqMnF2iEU6m9hLo8kxozoAGUazwPyELHlRVmjsbvlnGXjnzyptSXVmceA== +"@types/node@^11.13.4": + version "11.13.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-11.13.4.tgz#f83ec3c3e05b174b7241fadeb6688267fe5b22ca" + integrity sha512-+rabAZZ3Yn7tF/XPGHupKIL5EcAbrLxnTr/hgQICxbeuAfWtT0UZSfULE+ndusckBItcv4o6ZeOJplQikVcLvQ== abbrev@1: version "1.1.1" @@ -108,6 +129,11 @@ ansi-regex@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" @@ -840,17 +866,17 @@ define-property@^2.0.2: is-descriptor "^1.0.2" isobject "^3.0.1" -del@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/del/-/del-4.0.0.tgz#4fa27e92c366cb45b9bdaa56a9b8703dced17437" - integrity sha512-/BnSJ+SuZyLu7xMn48kZY0nMXDi+5KNmR4g8n21Wivsl8+B9njV6/5kcTNE9juSprp0zRWBU28JuHUq0FqK1Nw== +del@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/del/-/del-4.1.0.tgz#049543b8290e1a9293e2bd150ab3a06f637322b8" + integrity sha512-C4kvKNlYrwXhKxz97BuohF8YoGgQ23Xm9lvoHmgT7JaPGprSEjk3+XFled74Yt/x0ZABUHg2D67covzAPUKx5Q== dependencies: globby "^6.1.0" is-path-cwd "^2.0.0" is-path-in-cwd "^2.0.0" p-map "^2.0.0" pify "^4.0.1" - rimraf "^2.6.2" + rimraf "^2.6.3" delayed-stream@~1.0.0: version "1.0.0" @@ -910,6 +936,11 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + end-of-stream@^1.0.0, end-of-stream@^1.1.0: version "1.4.1" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" @@ -1243,6 +1274,13 @@ fill-range@^4.0.0: repeat-string "^1.6.1" to-regex-range "^2.1.0" +find-up@3.0.0, find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + find-up@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" @@ -1251,14 +1289,7 @@ find-up@^1.0.0: path-exists "^2.0.0" pinkie-promise "^2.0.0" -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - -findup-sync@2.0.0, findup-sync@^2.0.0: +findup-sync@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc" integrity sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw= @@ -1399,6 +1430,11 @@ get-caller-file@^1.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + get-func-name@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" @@ -2079,15 +2115,20 @@ js-tokens@^3.0.2: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= -js-yaml@3.12.0: - version "3.12.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" - integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@3.13.0: + version "3.13.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.0.tgz#38ee7178ac0eea2c97ff6d96fff4b18c7d8cf98e" + integrity sha512-pZZoSxcCYco+DIKBTimr67J6Hy+EYGZDY/HCWC+iAEA9h1ByhMXAIVUXMcMFpOCxQ/xjXmPI2MkDL5HRm5eFrQ== dependencies: argparse "^1.0.7" esprima "^4.0.0" -js-yaml@3.x, js-yaml@^3.11.0, js-yaml@^3.7.0, js-yaml@^3.9.1: +js-yaml@3.x, js-yaml@^3.11.0, js-yaml@^3.9.1: version "3.12.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.1.tgz#295c8632a18a23e054cf5c9d3cecafe678167600" integrity sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA== @@ -2095,6 +2136,14 @@ js-yaml@3.x, js-yaml@^3.11.0, js-yaml@^3.7.0, js-yaml@^3.9.1: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^3.13.0: + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" @@ -2419,33 +2468,33 @@ mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@^0.5.0, mkdirp@^0.5.1: dependencies: minimist "0.0.8" -mocha@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-6.0.2.tgz#cdc1a6fdf66472c079b5605bac59d29807702d2c" - integrity sha512-RtTJsmmToGyeTznSOMoM6TPEk1A84FQaHIciKrRqARZx+B5ccJ5tXlmJzEKGBxZdqk9UjpRsesZTUkZmR5YnuQ== +mocha@^6.1.3: + version "6.1.3" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-6.1.3.tgz#79d1b370a92dfdb409e6f77bc395ca5afe4cdc93" + integrity sha512-QdE/w//EPHrqgT5PNRUjRVHy6IJAzAf1R8n2O8W8K2RZ+NbPfOD5cBDp+PGa2Gptep37C/TdBiaNwakppEzEbg== dependencies: ansi-colors "3.2.3" browser-stdout "1.3.1" debug "3.2.6" diff "3.5.0" escape-string-regexp "1.0.5" - findup-sync "2.0.0" + find-up "3.0.0" glob "7.1.3" growl "1.10.5" he "1.2.0" - js-yaml "3.12.0" + js-yaml "3.13.0" log-symbols "2.2.0" minimatch "3.0.4" mkdirp "0.5.1" ms "2.1.1" - node-environment-flags "1.0.4" + node-environment-flags "1.0.5" object.assign "4.1.0" strip-json-comments "2.0.1" supports-color "6.0.0" which "1.3.1" wide-align "1.1.3" - yargs "12.0.5" - yargs-parser "11.1.1" + yargs "13.2.2" + yargs-parser "13.0.0" yargs-unparser "1.5.0" ms@2.0.0: @@ -2514,12 +2563,13 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== -node-environment-flags@1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.4.tgz#0b784a6551426bfc16d3b2208424dcbc2b2ff038" - integrity sha512-M9rwCnWVLW7PX+NUWe3ejEdiLYinRpsEre9hMkU/6NS4h+EEulYaDH1gCEZ2gyXsmw+RXYDaV2JkkTNcsPDJ0Q== +node-environment-flags@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.5.tgz#fa930275f5bf5dae188d6192b24b4c8bbac3d76a" + integrity sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ== dependencies: object.getownpropertydescriptors "^2.0.3" + semver "^5.7.0" node-pre-gyp@^0.10.0: version "0.10.3" @@ -2751,7 +2801,7 @@ os-locale@^1.4.0: dependencies: lcid "^1.0.0" -os-locale@^3.0.0: +os-locale@^3.0.0, os-locale@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== @@ -3193,6 +3243,11 @@ require-main-filename@^1.0.1: resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + require-uncached@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" @@ -3258,7 +3313,7 @@ rewire@^4.0.1: dependencies: eslint "^4.19.1" -rimraf@^2.6.1, rimraf@^2.6.2, rimraf@~2.6.2: +rimraf@^2.6.1, rimraf@^2.6.3, rimraf@~2.6.2: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== @@ -3318,7 +3373,7 @@ semver-greatest-satisfied-range@^1.1.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== -semver@^5.5.0: +semver@^5.5.0, semver@^5.7.0: version "5.7.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== @@ -3546,6 +3601,15 @@ string-width@^1.0.1, string-width@^1.0.2: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" +string-width@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + string_decoder@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" @@ -3574,6 +3638,13 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" +strip-ansi@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + strip-bom@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" @@ -3744,10 +3815,10 @@ tough-cookie@~2.4.3: psl "^1.1.24" punycode "^1.4.1" -ts-node@^8.0.3: - version "8.0.3" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.0.3.tgz#aa60b836a24dafd8bf21b54766841a232fdbc641" - integrity sha512-2qayBA4vdtVRuDo11DEFSsD/SFsBXQBRZZhbRGSIkmYmVkWjULn/GGMdG10KVqkaGndljfaTD8dKjWgcejO8YA== +ts-node@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.1.0.tgz#8c4b37036abd448577db22a061fd7a67d47e658e" + integrity sha512-34jpuOrxDuf+O6iW1JpgTRDFynUZ1iEqtYruBqh35gICNjN8x+LpVcPAcwzLPi9VU6mdA3ym+x233nZmZp445A== dependencies: arg "^4.1.0" diff "^3.1.0" @@ -3760,18 +3831,18 @@ tslib@^1.8.0, tslib@^1.8.1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== -tslint@^5.14.0: - version "5.14.0" - resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.14.0.tgz#be62637135ac244fc9b37ed6ea5252c9eba1616e" - integrity sha512-IUla/ieHVnB8Le7LdQFRGlVJid2T/gaJe5VkjzRVSRR6pA2ODYrnfR1hmxi+5+au9l50jBwpbBL34txgv4NnTQ== +tslint@^5.15.0: + version "5.16.0" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.16.0.tgz#ae61f9c5a98d295b9a4f4553b1b1e831c1984d67" + integrity sha512-UxG2yNxJ5pgGwmMzPMYh/CCnCnh0HfPgtlVRDs1ykZklufFBL1ZoTlWFRz2NQjcoEiDoRp+JyT0lhBbbH/obyA== dependencies: - babel-code-frame "^6.22.0" + "@babel/code-frame" "^7.0.0" builtin-modules "^1.1.1" chalk "^2.3.0" commander "^2.12.1" diff "^3.2.0" glob "^7.1.1" - js-yaml "^3.7.0" + js-yaml "^3.13.0" minimatch "^3.0.4" mkdirp "^0.5.1" resolve "^1.3.2" @@ -3815,10 +3886,10 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typescript@^3.3.4000: - version "3.3.4000" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.3.4000.tgz#76b0f89cfdbf97827e1112d64f283f1151d6adf0" - integrity sha512-jjOcCZvpkl2+z7JFn0yBOoLQyLoIkNZAs/fYJkUG6VKy6zLPHJGfQJYFHzibB6GJaF/8QrcECtlQ5cpvRHSMEA== +typescript@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.4.3.tgz#0eb320e4ace9b10eadf5bc6103286b0f8b7c224f" + integrity sha512-FFgHdPt4T/duxx6Ndf7hwgMZZjZpB+U0nMNGVCYPq0rEzWKjEDobm4J6yb3CS7naZ0yURFqdw9Gwc7UOh/P9oQ== uglify-js@^3.1.4: version "3.4.9" @@ -4052,7 +4123,7 @@ y18n@^3.2.1: resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= -"y18n@^3.2.1 || ^4.0.0": +"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== @@ -4067,7 +4138,15 @@ yallist@^3.0.0, yallist@^3.0.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== -yargs-parser@11.1.1, yargs-parser@^11.1.1: +yargs-parser@13.0.0, yargs-parser@^13.0.0: + version "13.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.0.0.tgz#3fc44f3e76a8bdb1cc3602e860108602e5ccde8b" + integrity sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@^11.1.1: version "11.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== @@ -4091,7 +4170,24 @@ yargs-unparser@1.5.0: lodash "^4.17.11" yargs "^12.0.5" -yargs@12.0.5, yargs@^12.0.5: +yargs@13.2.2: + version "13.2.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.2.tgz#0c101f580ae95cea7f39d927e7770e3fdc97f993" + integrity sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA== + dependencies: + cliui "^4.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + os-locale "^3.1.0" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.0.0" + +yargs@^12.0.5: version "12.0.5" resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== From 36ad82a336f982c4276e01f53915ea351ff39a8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gillian=20Pe=CC=81rard?= Date: Thu, 18 Apr 2019 09:13:46 +0200 Subject: [PATCH 3/5] Add vscode config --- .npmignore | 3 ++- .vscode/extensions.json | 12 ++++++++++++ .vscode/settings.json | 7 +++++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 .vscode/extensions.json create mode 100644 .vscode/settings.json diff --git a/.npmignore b/.npmignore index f10104c..656ada2 100644 --- a/.npmignore +++ b/.npmignore @@ -8,4 +8,5 @@ tsconfig.json tslint.json yarn.lock dist/examples -dist/spec \ No newline at end of file +dist/spec +.vscode/ \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..4a0b547 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,12 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. + // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp + // List of extensions which should be recommended for users of this workspace. + "recommendations": [ + "msjsdiag.debugger-for-chrome", + "eg2.tslint", + "wix.vscode-import-cost" + ], + // List of extensions recommended by VS Code that should not be recommended for users of this workspace. + "unwantedRecommendations": [] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..050efc2 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "editor.detectIndentation": false, + "editor.insertSpaces": true, + "tslint.enable": true, + "tslint.autoFixOnSave": true, + "editor.formatOnSave": true +} \ No newline at end of file From 7df0ea01e08c511cc976248f1fb722e27bba6000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gillian=20Pe=CC=81rard?= Date: Wed, 17 Apr 2019 17:24:53 +0200 Subject: [PATCH 4/5] Improve lib code --- src/index.ts | 177 ++++++++++++++++++++++++++---------------------- src/metadata.ts | 3 + src/type.ts | 9 +++ 3 files changed, 108 insertions(+), 81 deletions(-) create mode 100644 src/metadata.ts create mode 100644 src/type.ts diff --git a/src/index.ts b/src/index.ts index 1f00945..7aef786 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,20 +1,28 @@ import 'reflect-metadata'; +import Metadata from './metadata'; +import Type from './type'; + +const apiMap: string = 'api:map:'; +const apiMapSerializable: string = `${apiMap}serializable`; +const designType: string = 'design:type'; + /** * Decorator JsonProperty */ export function JsonProperty(args?: string | { name?: string, type: Function }): Function { return (target: Object, key: string): void => { - let map: { [id: string]: { name: string, type: Function }; } = {}; + let map: { [id: string]: Metadata; } = {}; const targetName: string = target.constructor.name; + const ApiMapTargetName: string = `${apiMap}${targetName}`; - if (Reflect.hasMetadata('api:map:' + targetName, target)) { - map = Reflect.getMetadata('api:map:' + targetName, target); + if (Reflect.hasMetadata(ApiMapTargetName, target)) { + map = Reflect.getMetadata(ApiMapTargetName, target); } map[key] = getJsonPropertyValue(key, args); - Reflect.defineMetadata('api:map:' + targetName, map, target); + Reflect.defineMetadata(ApiMapTargetName, map, target); }; } @@ -23,7 +31,7 @@ export function JsonProperty(args?: string | { name?: string, type: Function }): */ export function Serializable(baseClassName?: string): Function { return (target: Object): void => { - Reflect.defineMetadata('api:map:serializable', baseClassName, target); + Reflect.defineMetadata(apiMapSerializable, baseClassName, target); }; } @@ -34,25 +42,29 @@ export function deserialize(json: any, type: any): any { const instance: any = new type(); const instanceName: string = instance.constructor.name; - const baseClassName: string = Reflect.getMetadata('api:map:serializable', type); - let instanceMap: { [id: string]: { name: string, type: Function }; } = {}; + const baseClassName: string = Reflect.getMetadata(apiMapSerializable, type); + const apiMapInstanceName: string = `${apiMap}${instanceName}`; + const hasMap: boolean = Reflect.hasMetadata(apiMapInstanceName, instance); + let instanceMap: { [id: string]: Metadata; } = {}; - if (Reflect.hasMetadata('api:map:' + instanceName, instance)) { - instanceMap = Reflect.getMetadata('api:map:' + instanceName, instance); + if (!hasMap) { + return instance; + } - if (baseClassName) { - const baseClassMap: { [id: string]: any; } = Reflect.getMetadata('api:map:' + baseClassName, instance); - instanceMap = {...instanceMap, ...baseClassMap}; - } + instanceMap = Reflect.getMetadata(apiMapInstanceName, instance); - const keys: Array = Object.keys(instanceMap); - keys.forEach((key: string) => { - if (json[instanceMap[key].name] !== undefined) { - instance[key] = convertDataToProperty(instance, key, instanceMap[key], json[instanceMap[key].name]); - } - }); + if (baseClassName) { + const baseClassMap: { [id: string]: any; } = Reflect.getMetadata(`${apiMap}${baseClassName}`, instance); + instanceMap = { ...instanceMap, ...baseClassMap }; } + const keys: Array = Object.keys(instanceMap); + keys.forEach((key: string) => { + if (json[instanceMap[key].name] !== undefined) { + instance[key] = convertDataToProperty(instance, key, instanceMap[key], json[instanceMap[key].name]); + } + }); + return instance; } @@ -63,37 +75,41 @@ export function serialize(instance: any, removeUndefined: boolean = true): any { const json: any = {}; const instanceName: string = instance.constructor.name; - const baseClassName: string = Reflect.getMetadata('api:map:serializable', instance.constructor); - let instanceMap: { [id: string]: { name: string, type: Function }; } = {}; + const baseClassName: string = Reflect.getMetadata(apiMapSerializable, instance.constructor); + const apiMapInstanceName: string = `${apiMap}${instanceName}`; + const hasMap: boolean = Reflect.hasMetadata(apiMapInstanceName, instance); + let instanceMap: { [id: string]: Metadata; } = {}; - if (Reflect.hasMetadata('api:map:' + instanceName, instance)) { - instanceMap = Reflect.getMetadata('api:map:' + instanceName, instance); - - if (baseClassName !== undefined) { - const baseClassMap: { [id: string]: any; } = Reflect.getMetadata('api:map:' + baseClassName, instance); - instanceMap = {...instanceMap, ...baseClassMap}; - } + if (!hasMap) { + return json; + } - Object.keys(instanceMap).forEach((key: string) => { - const data: any = convertPropertyToData(instance, key, instanceMap[key], removeUndefined); + instanceMap = Reflect.getMetadata(apiMapInstanceName, instance); - if (!removeUndefined || removeUndefined && data !== undefined) { - json[instanceMap[key].name] = data; - } - }); + if (baseClassName !== undefined) { + const baseClassMap: { [id: string]: any; } = Reflect.getMetadata(`${apiMap}${baseClassName}`, instance); + instanceMap = { ...instanceMap, ...baseClassMap }; } + Object.keys(instanceMap).forEach((key: string) => { + const data: any = convertPropertyToData(instance, key, instanceMap[key], removeUndefined); + if (!removeUndefined || removeUndefined && data !== undefined) { + json[instanceMap[key].name] = data; + } + }); + return json; } /** * Function to convert json data to the class property */ -function convertPropertyToData(instance: Function, key: string, value: { name: string, type: Function }, removeUndefined: boolean): any { +function convertPropertyToData(instance: Function, key: string, value: Metadata, removeUndefined: boolean): any { const property: any = instance[key]; - const isArray: boolean = Reflect.getMetadata('design:type', instance, key).name === 'Array'; - const propertyType: any = value.type || Reflect.getMetadata('design:type', instance, key); + const type: Metadata = Reflect.getMetadata(designType, instance, key); + const isArray: boolean = type.name.toLocaleLowerCase() === Type.Array; + const propertyType: any = value.type || type; const isSerializableProperty: boolean = isSerializable(propertyType); if (isSerializableProperty) { @@ -107,62 +123,63 @@ function convertPropertyToData(instance: Function, key: string, value: { name: s } return serialize(property, removeUndefined); - } else { - if (propertyType.name === 'Date') { - return property.toISOString(); - } + } - return property; + if (propertyType.name.toLocaleLowerCase() === Type.Date) { + return property.toISOString(); } + + return property; } /** * Function to convert json data to the class property */ -function convertDataToProperty(instance: Function, key: string, value: { name: string, type: Function }, data: any): any { +function convertDataToProperty(instance: Function, key: string, value: Metadata, data: any): any { - const isArray: boolean = Reflect.getMetadata('design:type', instance, key).name === 'Array'; - const propertyType: any = value.type || Reflect.getMetadata('design:type', instance, key); + const type: Metadata = Reflect.getMetadata(designType, instance, key); + const isArray: boolean = type.name.toLowerCase() === Type.Array; + const propertyType: any = value.type || type; const isSerializableProperty: boolean = isSerializable(propertyType); - if (isSerializableProperty) { - if (isArray) { - const array: Array = []; - data.forEach((d: any) => { - array.push(deserialize(d, propertyType)); - }); - - return array; - } else { - return deserialize(data, propertyType); - } - } else { + if (!isSerializableProperty) { return castSimpleData(propertyType.name, data); } + + if (isArray) { + const array: Array = []; + data.forEach((d: any) => { + array.push(deserialize(d, propertyType)); + }); + + return array; + } + + return deserialize(data, propertyType); } /** * Function to test if a class has the serializable decorator (metadata) */ function isSerializable(type: any): boolean { - return Reflect.hasOwnMetadata('api:map:serializable', type); + return Reflect.hasOwnMetadata(apiMapSerializable, type); } /** * Function to transform the JsonProperty value into an object like {name: string, type: Function} */ -function getJsonPropertyValue(key: string, args: string | { name?: string, type: Function }): { name: string, type: Function } { - if (args) { - return { - name: typeof args === 'string' ? args : args['name'] ? args['name'] : key.toString(), - type: args['type'] - }; - } else { +function getJsonPropertyValue(key: string, args: string | { name?: string, type: Function }): Metadata { + if (!args) { return { name: key.toString(), type: undefined }; } + + return { + name: typeof args === Type.String ? args : args['name'] ? args['name'] : key.toString(), + type: args['type'] + }; } /** @@ -173,31 +190,29 @@ function castSimpleData(type: string, data: any): any { if ((typeof data).toLowerCase() === type) { return data; - } else { - if (type === 'string') { + } + + switch (type) { + case Type.String: return data.toString(); - } else if (type === 'number') { - const n: number = +data; - if (isNaN(n)) { + case Type.Number: + const number: number = +data; + if (isNaN(number)) { console.error(`${data}: Type ${typeof data} is not assignable to type ${type}.`); return undefined; - } else { - return n; } - } else if (type === 'boolean') { + return number; + case Type.Boolean: console.error(`${data}: Type ${typeof data} is not assignable to type ${type}.`); return undefined; - } else if (type === 'date') { - const n: number = Date.parse(data); - if (isNaN(n)) { + case Type.Date: + if (isNaN(Date.parse(data))) { console.error(`${data}: Type ${typeof data} is not assignable to type ${type}.`); return undefined; - } else { - return new Date(data); } - } - - return data; + return new Date(data); + default: + return data; } } diff --git a/src/metadata.ts b/src/metadata.ts new file mode 100644 index 0000000..6f96067 --- /dev/null +++ b/src/metadata.ts @@ -0,0 +1,3 @@ +export default class Metadata { + public constructor(public name: string, public type: Function) { } +} diff --git a/src/type.ts b/src/type.ts new file mode 100644 index 0000000..66f5ad4 --- /dev/null +++ b/src/type.ts @@ -0,0 +1,9 @@ +enum Type { + Array = 'array', + Boolean = 'boolean', + Date = 'date', + Number = 'number', + String = 'string' +} + +export default Type; From c5946f62f170b1c59775639b79f4ce9edd2ceab3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gillian=20Pe=CC=81rard?= Date: Thu, 18 Apr 2019 10:39:40 +0200 Subject: [PATCH 5/5] Improve tests --- examples/json/data.ts | 22 ++++++++++++++++++++ examples/models/dummy.ts | 1 + examples/models/snake.ts | 3 +++ examples/models/zoo.ts | 3 +++ spec/index.spec.ts | 43 ++++++++++++++++++++++++++++++++++++---- src/index.ts | 4 ++++ 6 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 examples/models/dummy.ts diff --git a/examples/json/data.ts b/examples/json/data.ts index c5b0773..5ec6d38 100644 --- a/examples/json/data.ts +++ b/examples/json/data.ts @@ -4,6 +4,7 @@ import { Panther } from '../models/panther'; import { Gender } from '../models/gender'; import { Status } from '../models/status'; +import { Snake } from '../models/snake'; export const data: any = { 'id': 15, @@ -82,6 +83,17 @@ export const data: any = { 'isSpeckled': false, 'status': 'Dead and alive' } + ], + 'snakes': [ + { + 'id': 1, + 'name': 'Ka', + 'birthdate': '2018-09-09T00:00:00.000Z', + 'numberOfPaws': 0, + 'gender': 1, + 'isPoisonous': true, + 'status': 'Alive' + } ] }; @@ -144,6 +156,15 @@ schrodinger.color = data.Panthers[2].color; schrodinger.isSpeckled = data.Panthers[2].isSpeckled; schrodinger.status = Status.deadAndAlive; +const ka: Snake = new Snake(); +ka.id = data.snakes[0].id; +ka.name = data.snakes[0].name; +ka.birthdate = new Date(data.snakes[0].birthdate); +ka.numberOfPaws = data.snakes[0].numberOfPaws; +ka.gender = Gender.male; +ka.isPoisonous = data.snakes[0].isPoisonous; +ka.status = Status.alive; + const zoo: Zoo = new Zoo(); zoo.id = data.id; zoo.name = data.name; @@ -152,5 +173,6 @@ zoo.city = data.city; zoo.boss = boss; zoo.employees = [boss, mikasa, red, fried]; zoo.panthers = [bagheera, jolene, schrodinger]; +zoo.snakes = [ka]; export const deserializedData: Zoo = zoo; diff --git a/examples/models/dummy.ts b/examples/models/dummy.ts new file mode 100644 index 0000000..4f4da1e --- /dev/null +++ b/examples/models/dummy.ts @@ -0,0 +1 @@ +export class Dummy { } diff --git a/examples/models/snake.ts b/examples/models/snake.ts index d4e00d2..1772c75 100644 --- a/examples/models/snake.ts +++ b/examples/models/snake.ts @@ -1,7 +1,10 @@ import { Animal } from './animal'; +import { JsonProperty, Serializable } from '../../src'; +@Serializable('Animal') export class Snake extends Animal { + @JsonProperty() public isPoisonous: boolean; public constructor() { diff --git a/examples/models/zoo.ts b/examples/models/zoo.ts index ebc2ea2..3f932df 100644 --- a/examples/models/zoo.ts +++ b/examples/models/zoo.ts @@ -2,6 +2,7 @@ import { Serializable, JsonProperty } from './../../src'; import { Employee } from './employee'; import { Panther } from './panther'; +import { Snake } from './snake'; @Serializable() export class Zoo { @@ -20,6 +21,8 @@ export class Zoo { public name: string; @JsonProperty({ name: 'Panthers', type: Panther }) public panthers: Array; + @JsonProperty({ type: Snake }) + public snakes: Array; public isOpen: boolean = true; diff --git a/spec/index.spec.ts b/spec/index.spec.ts index 51fe84f..8f6af54 100644 --- a/spec/index.spec.ts +++ b/spec/index.spec.ts @@ -4,8 +4,8 @@ import * as rewire from 'rewire'; import { serialize, deserialize } from '../src/index'; +import { Dummy } from '../examples/models/dummy'; import { Panther } from '../examples/models/panther'; -import { Snake } from '../examples/models/snake'; import { Zoo } from '../examples/models/zoo'; import { data, deserializedData } from '../examples/json/data'; @@ -15,7 +15,7 @@ const tjs: any = rewire('../src/index'); describe('Serializable', () => { it('should return false', () => { - const hasMetadata: boolean = Reflect.hasOwnMetadata('api:map:serializable', Snake); + const hasMetadata: boolean = Reflect.hasOwnMetadata('api:map:serializable', Dummy); expect(hasMetadata).to.equal(false); }); @@ -47,7 +47,28 @@ describe('serialize', () => { count++; } }); - expect(count).to.equal(3); + expect(count).to.equal(1); + }); + + it('empty zoo should return an empty object', () => { + const zoo: Zoo = new Zoo(); + expect(serialize(zoo)).to.deep.equal({}); + }); + + it('{} should return an empty object', () => { + expect(serialize({})).to.deep.equal({}); + }); + + const zooWithUndefinedValue: Zoo = new Zoo(); + zooWithUndefinedValue.id = 4; + zooWithUndefinedValue.name = undefined; + + it('zooWithUndefinedValue should return an object with undefined value', () => { + expect(serialize(zooWithUndefinedValue, false)).to.deep.equal({ id: 4, name: undefined }); + }); + + it('zooWithUndefinedValue should return an object without undefined value', () => { + expect(serialize(zooWithUndefinedValue)).to.deep.equal({ id: 4 }); }); }); @@ -55,6 +76,20 @@ describe('deserialize', () => { it('should return true', () => { expect(deserialize(data, Zoo)).to.deep.equal(deserializedData); }); + + it('should return true even if there are fake data included', () => { + const alteredData: any = { ...data }; + alteredData['fake'] = 'fake'; + alteredData['Panthers'][0]['fake'] = 'fake'; + expect(deserialize(alteredData, Zoo)).to.deep.equal(deserializedData); + }); + + it('should return an empty zoo (except for the isOpen property)', () => { + const badData: any = { + fake: 'fake' + }; + expect(deserialize(badData, Zoo)).to.deep.equal({ isOpen: true }); + }); }); describe('castSimpleData', () => { @@ -120,7 +155,7 @@ describe('isSerializable', () => { }); it('should return false', () => { - expect(isSerializable(Snake)).to.equal(false); + expect(isSerializable(Dummy)).to.equal(false); }); }); diff --git a/src/index.ts b/src/index.ts index 7aef786..4e9cf5f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -91,7 +91,11 @@ export function serialize(instance: any, removeUndefined: boolean = true): any { instanceMap = { ...instanceMap, ...baseClassMap }; } + const instanceKeys: Array = Object.keys(instance); Object.keys(instanceMap).forEach((key: string) => { + if (!instanceKeys.includes(key)) { + return; + } const data: any = convertPropertyToData(instance, key, instanceMap[key], removeUndefined); if (!removeUndefined || removeUndefined && data !== undefined) { json[instanceMap[key].name] = data;