From 6359aca4213e2b90bfdf9921db8a9cd71bd9b96d Mon Sep 17 00:00:00 2001 From: Erik O'Leary Date: Wed, 5 Dec 2018 09:02:36 -0600 Subject: [PATCH 1/2] - Find case insensitive items - Dont require arg for jsonproperty --- index.js | 24 ++++-- index.ts | 21 ++++- libs/utils.js | 1 + spec/common/dateconverter.d.ts | 3 + spec/common/dateconverter.js | 2 +- spec/index.d.ts | 1 + spec/index.js | 49 +++++------ spec/serialize.d.ts | 1 + spec/serialize.js | 71 ++++++++-------- tsconfig.json | 5 +- yarn.lock | 146 +++++++++++++++++++++++++++++++++ 11 files changed, 255 insertions(+), 69 deletions(-) create mode 100644 spec/common/dateconverter.d.ts create mode 100644 spec/serialize.d.ts create mode 100644 yarn.lock diff --git a/index.js b/index.js index fa42fbc..5282bb4 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,7 @@ "use strict"; -require('reflect-metadata'); -var utils_1 = require('./libs/utils'); +Object.defineProperty(exports, "__esModule", { value: true }); +require("reflect-metadata"); +var utils_1 = require("./libs/utils"); /** * Decorator variable name * @@ -15,7 +16,7 @@ var JSON_META_DATA_KEY = 'JsonProperty'; * @property {string} name, indicate which json property needed to map * @property {string} clazz, if the target is not primitive type, map it to corresponding class */ -var DecoratorMetaData = (function () { +var DecoratorMetaData = /** @class */ (function () { function DecoratorMetaData(name, clazz) { this.name = name; this.clazz = clazz; @@ -38,7 +39,8 @@ function JsonProperty(metadata) { decoratorMetaData = metadata; } else { - throw new Error('index.ts: meta data in Json property is undefined. meta data: ' + metadata); + // throw new Error('index.ts: meta data in Json property is undefined. meta data: ' + metadata) + decoratorMetaData = new DecoratorMetaData(); } return Reflect.metadata(JSON_META_DATA_KEY, decoratorMetaData); } @@ -76,15 +78,25 @@ function getJsonProperty(target, propertyKey) { function hasAnyNullOrUndefined() { var args = []; for (var _i = 0; _i < arguments.length; _i++) { - args[_i - 0] = arguments[_i]; + args[_i] = arguments[_i]; } return args.some(function (arg) { return arg === null || arg === undefined; }); } +function getCaseInsensitiveMatch(obj, key) { + if (obj.hasOwnProperty(key)) + return key; + else { + var newKey = Object.keys(obj).find(function (i) { + return key.toUpperCase() === i.toUpperCase(); + }); + return newKey; + } +} function mapFromJson(decoratorMetadata, instance, json, key) { /** * if decorator name is not found, use target property key as decorator name. It means mapping it directly */ - var decoratorName = decoratorMetadata.name || key; + var decoratorName = getCaseInsensitiveMatch(json, decoratorMetadata.name || key); var innerJson = json ? json[decoratorName] : undefined; var clazz = getClazz(instance, key); if (utils_1.isArrayOrArrayClass(clazz)) { diff --git a/index.ts b/index.ts index 5ef5a14..fc4b9f9 100644 --- a/index.ts +++ b/index.ts @@ -73,7 +73,7 @@ export function JsonProperty(metadata?: IDecoratorMetaData|string): (targe decoratorMetaData = metadata as IDecoratorMetaData; } else { - throw new Error('index.ts: meta data in Json property is undefined. meta data: ' + metadata) + decoratorMetaData = new DecoratorMetaData(); } return Reflect.metadata(JSON_META_DATA_KEY, decoratorMetaData); @@ -117,12 +117,29 @@ function hasAnyNullOrUndefined(...args: any[]) { return args.some((arg: any) => arg === null || arg === undefined); } +/** + * Ensure obj has key, otherwise try to find case-insensitve version of key + * + * @param obj + * @param key + */ +function getCaseInsensitiveMatch(obj: any, key: string): any { + if ((obj as Object).hasOwnProperty(key)) + return key; + else { + let newKey = Object.keys(obj).find(i => { + return key.toUpperCase() === i.toUpperCase(); + }); + + return newKey || key; + } +} function mapFromJson(decoratorMetadata: IDecoratorMetaData, instance: T, json: IGenericObject, key: any): any { /** * if decorator name is not found, use target property key as decorator name. It means mapping it directly */ - let decoratorName = decoratorMetadata.name || key; + let decoratorName = getCaseInsensitiveMatch(json, decoratorMetadata.name || key); let innerJson: any = json ? json[decoratorName] : undefined; let clazz = getClazz(instance, key); if (isArrayOrArrayClass(clazz)) { diff --git a/libs/utils.js b/libs/utils.js index f3f446f..022e6f6 100644 --- a/libs/utils.js +++ b/libs/utils.js @@ -1,4 +1,5 @@ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); function isTargetType(val, type) { return typeof val === type; } diff --git a/spec/common/dateconverter.d.ts b/spec/common/dateconverter.d.ts new file mode 100644 index 0000000..9110a10 --- /dev/null +++ b/spec/common/dateconverter.d.ts @@ -0,0 +1,3 @@ +import { ICustomConverter } from '../../index'; +declare const dateConverter: ICustomConverter; +export default dateConverter; diff --git a/spec/common/dateconverter.js b/spec/common/dateconverter.js index fa45d35..e404315 100644 --- a/spec/common/dateconverter.js +++ b/spec/common/dateconverter.js @@ -1,4 +1,5 @@ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); var dateConverter = { fromJson: function (data) { return new Date(data); @@ -7,6 +8,5 @@ var dateConverter = { return 'some-date'; } }; -Object.defineProperty(exports, "__esModule", { value: true }); exports.default = dateConverter; //# sourceMappingURL=dateconverter.js.map \ No newline at end of file diff --git a/spec/index.d.ts b/spec/index.d.ts index e69de29..cb0ff5c 100644 --- a/spec/index.d.ts +++ b/spec/index.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/spec/index.js b/spec/index.js index db7db24..b5685bc 100644 --- a/spec/index.js +++ b/spec/index.js @@ -8,25 +8,26 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; -var chai_1 = require('chai'); -var index_1 = require('../index'); -var dateconverter_1 = require('./common/dateconverter'); -var Student = (function () { +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var index_1 = require("../index"); +var dateconverter_1 = require("./common/dateconverter"); +var Student = /** @class */ (function () { function Student() { this.dateOfBirth = undefined; this.fullName = void 0; } __decorate([ - index_1.JsonProperty('name'), - __metadata('design:type', String) + index_1.JsonProperty('name'), + __metadata("design:type", String) ], Student.prototype, "fullName", void 0); __decorate([ - index_1.JsonProperty({ name: 'dob', customConverter: dateconverter_1.default }), - __metadata('design:type', Date) + index_1.JsonProperty({ name: 'dob', customConverter: dateconverter_1.default }), + __metadata("design:type", Date) ], Student.prototype, "dateOfBirth", void 0); return Student; }()); -var Address = (function () { +var Address = /** @class */ (function () { function Address() { this.firstLine = void 0; this.secondLine = void 0; @@ -34,20 +35,20 @@ var Address = (function () { this.student = void 0; } __decorate([ - index_1.JsonProperty('first-line'), - __metadata('design:type', String) + index_1.JsonProperty('first-line'), + __metadata("design:type", String) ], Address.prototype, "firstLine", void 0); __decorate([ - index_1.JsonProperty('second-line'), - __metadata('design:type', String) + index_1.JsonProperty('second-line'), + __metadata("design:type", String) ], Address.prototype, "secondLine", void 0); __decorate([ - index_1.JsonProperty({ clazz: Student }), - __metadata('design:type', Student) + index_1.JsonProperty({ clazz: Student }), + __metadata("design:type", Student) ], Address.prototype, "student", void 0); return Address; }()); -var Person = (function () { +var Person = /** @class */ (function () { function Person() { this.name = void 0; this.surname = void 0; @@ -56,20 +57,20 @@ var Person = (function () { this.address = void 0; } __decorate([ - index_1.JsonProperty('Name'), - __metadata('design:type', String) + index_1.JsonProperty('Name'), + __metadata("design:type", String) ], Person.prototype, "name", void 0); __decorate([ - index_1.JsonProperty('xing'), - __metadata('design:type', String) + index_1.JsonProperty('xing'), + __metadata("design:type", String) ], Person.prototype, "surname", void 0); __decorate([ - index_1.JsonProperty({ clazz: Address, name: 'AddressArr' }), - __metadata('design:type', Array) + index_1.JsonProperty({ clazz: Address, name: 'AddressArr' }), + __metadata("design:type", Array) ], Person.prototype, "addressArr", void 0); __decorate([ - index_1.JsonProperty({ clazz: Address, name: 'Address' }), - __metadata('design:type', Address) + index_1.JsonProperty({ clazz: Address, name: 'Address' }), + __metadata("design:type", Address) ], Person.prototype, "address", void 0); return Person; }()); diff --git a/spec/serialize.d.ts b/spec/serialize.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/spec/serialize.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/spec/serialize.js b/spec/serialize.js index f1398f1..b85e8ac 100644 --- a/spec/serialize.js +++ b/spec/serialize.js @@ -8,18 +8,19 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; -var chai_1 = require('chai'); -var index_1 = require('../index'); -var dateconverter_1 = require('./common/dateconverter'); +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var index_1 = require("../index"); +var dateconverter_1 = require("./common/dateconverter"); describe('serialize', function () { it('should use the property name given in the meta data', function () { - var ClassWithPrimitiveProp = (function () { + var ClassWithPrimitiveProp = /** @class */ (function () { function ClassWithPrimitiveProp() { this.name = undefined; } __decorate([ - index_1.JsonProperty('theName'), - __metadata('design:type', String) + index_1.JsonProperty('theName'), + __metadata("design:type", String) ], ClassWithPrimitiveProp.prototype, "name", void 0); return ClassWithPrimitiveProp; }()); @@ -32,13 +33,13 @@ describe('serialize', function () { var primitiveTypes = ['some-string', true, 25, new Number(25), new Boolean(true)]; primitiveTypes.forEach(function (primitiveType) { it("should keep " + typeof primitiveType + " as is", function () { - var PrimitiveProp = (function () { + var PrimitiveProp = /** @class */ (function () { function PrimitiveProp() { this.someProp = primitiveType; } __decorate([ - index_1.JsonProperty('someProp'), - __metadata('design:type', Object) + index_1.JsonProperty('someProp'), + __metadata("design:type", Object) ], PrimitiveProp.prototype, "someProp", void 0); return PrimitiveProp; }()); @@ -50,13 +51,13 @@ describe('serialize', function () { }); }); it('should keep unspecified objects as is', function () { - var ClassWithUnspecObject = (function () { + var ClassWithUnspecObject = /** @class */ (function () { function ClassWithUnspecObject() { this.date = new Date(); } __decorate([ - index_1.JsonProperty('date'), - __metadata('design:type', Date) + index_1.JsonProperty('date'), + __metadata("design:type", Date) ], ClassWithUnspecObject.prototype, "date", void 0); return ClassWithUnspecObject; }()); @@ -65,13 +66,13 @@ describe('serialize', function () { chai_1.expect(serializedInstance.date).to.equal(instance.date); }); it('should use custom converter if available', function () { - var ClassWithCustomConv = (function () { + var ClassWithCustomConv = /** @class */ (function () { function ClassWithCustomConv() { this.date = new Date(); } __decorate([ - index_1.JsonProperty({ name: 'date', customConverter: dateconverter_1.default }), - __metadata('design:type', Date) + index_1.JsonProperty({ name: 'date', customConverter: dateconverter_1.default }), + __metadata("design:type", Date) ], ClassWithCustomConv.prototype, "date", void 0); return ClassWithCustomConv; }()); @@ -80,18 +81,18 @@ describe('serialize', function () { chai_1.expect(serializedInstance.date).to.equal('some-date'); }); it('should exclude properties if specified', function () { - var ClassWithExcludedProp = (function () { + var ClassWithExcludedProp = /** @class */ (function () { function ClassWithExcludedProp() { this.name = 'John'; this.lastName = 'Doe'; } __decorate([ - index_1.JsonProperty('name'), - __metadata('design:type', String) + index_1.JsonProperty('name'), + __metadata("design:type", String) ], ClassWithExcludedProp.prototype, "name", void 0); __decorate([ - index_1.JsonProperty({ name: 'lastName', excludeToJson: true }), - __metadata('design:type', String) + index_1.JsonProperty({ name: 'lastName', excludeToJson: true }), + __metadata("design:type", String) ], ClassWithExcludedProp.prototype, "lastName", void 0); return ClassWithExcludedProp; }()); @@ -101,23 +102,23 @@ describe('serialize', function () { chai_1.expect(serializedInstance.lastName).to.be.undefined; }); it('should work recursively if clazz is specified in meta data', function () { - var OtherClass = (function () { + var OtherClass = /** @class */ (function () { function OtherClass() { this.date = new Date(); } __decorate([ - index_1.JsonProperty({ name: 'date', customConverter: dateconverter_1.default }), - __metadata('design:type', Date) + index_1.JsonProperty({ name: 'date', customConverter: dateconverter_1.default }), + __metadata("design:type", Date) ], OtherClass.prototype, "date", void 0); return OtherClass; }()); - var ClassWithClassProp = (function () { + var ClassWithClassProp = /** @class */ (function () { function ClassWithClassProp() { this.other = new OtherClass(); } __decorate([ - index_1.JsonProperty({ name: 'other', clazz: OtherClass }), - __metadata('design:type', OtherClass) + index_1.JsonProperty({ name: 'other', clazz: OtherClass }), + __metadata("design:type", OtherClass) ], ClassWithClassProp.prototype, "other", void 0); return ClassWithClassProp; }()); @@ -127,13 +128,13 @@ describe('serialize', function () { }); describe('Arrays', function () { it('should keep as is if no clazz is specified', function () { - var ClassWithArrayProp = (function () { + var ClassWithArrayProp = /** @class */ (function () { function ClassWithArrayProp() { this.items = [new Date(), new Date()]; } __decorate([ - index_1.JsonProperty('items'), - __metadata('design:type', Array) + index_1.JsonProperty('items'), + __metadata("design:type", Array) ], ClassWithArrayProp.prototype, "items", void 0); return ClassWithArrayProp; }()); @@ -145,23 +146,23 @@ describe('serialize', function () { chai_1.expect(serializedInstance.items[1]).to.equal(instance.items[1]); }); it('should apply serialize for all array items if clazz is specified', function () { - var OtherClass = (function () { + var OtherClass = /** @class */ (function () { function OtherClass() { this.date = new Date(); } __decorate([ - index_1.JsonProperty({ name: 'date', customConverter: dateconverter_1.default }), - __metadata('design:type', Date) + index_1.JsonProperty({ name: 'date', customConverter: dateconverter_1.default }), + __metadata("design:type", Date) ], OtherClass.prototype, "date", void 0); return OtherClass; }()); - var ClassWithArrayProp = (function () { + var ClassWithArrayProp = /** @class */ (function () { function ClassWithArrayProp() { this.items = [new OtherClass(), new OtherClass()]; } __decorate([ - index_1.JsonProperty({ name: 'items', clazz: OtherClass }), - __metadata('design:type', Array) + index_1.JsonProperty({ name: 'items', clazz: OtherClass }), + __metadata("design:type", Array) ], ClassWithArrayProp.prototype, "items", void 0); return ClassWithArrayProp; }()); diff --git a/tsconfig.json b/tsconfig.json index 833260a..eab24e2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,7 +5,10 @@ "sourceMap": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, - "noImplicitAny": true + "noImplicitAny": true, + "lib": [ + "es2017" + ] }, "exclude": [ "node_modules" diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..3822318 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,146 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +assertion-error@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.0.tgz#c7f85438fdd466bc7ca16ab90c81513797a5d23b" + integrity sha1-x/hUOP3UZrx8oWq5DIFRN5el0js= + +chai@~1.8.0: + version "1.8.1" + resolved "https://registry.yarnpkg.com/chai/-/chai-1.8.1.tgz#cc77866d5e7ebca2bd75144b1edc370a88785f72" + integrity sha1-zHeGbV5+vKK9dRRLHtw3Coh4X3I= + dependencies: + assertion-error "1.0.0" + deep-eql "0.1.3" + +commander@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-0.6.1.tgz#fa68a14f6a945d54dbbe50d8cdb3320e9e3b1a06" + integrity sha1-+mihT2qUXVTbvlDYzbMyDp47GgY= + +commander@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.3.0.tgz#fd430e889832ec353b9acd1de217c11cb3eef873" + integrity sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM= + +debug@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.0.0.tgz#89bd9df6732b51256bc6705342bba02ed12131ef" + integrity sha1-ib2d9nMrUSVrxnBTQrugLtEhMe8= + dependencies: + ms "0.6.2" + +deep-eql@0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-0.1.3.tgz#ef558acab8de25206cd713906d74e56930eb69f2" + integrity sha1-71WKyrjeJSBs1xOQbXTlaTDrafI= + dependencies: + type-detect "0.1.1" + +diff@1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/diff/-/diff-1.0.8.tgz#343276308ec991b7bc82267ed55bc1411f971666" + integrity sha1-NDJ2MI7Jkbe8giZ+1VvBQR+XFmY= + +escape-string-regexp@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz#4dbc2fe674e71949caf3fb2695ce7f2dc1d9a8d1" + integrity sha1-Tbwv5nTnGUnK8/smlc5/LcHZqNE= + +glob@3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.3.tgz#e313eeb249c7affaa5c475286b0e115b59839467" + integrity sha1-4xPusknHr/qlxHUoaw4RW1mDlGc= + dependencies: + graceful-fs "~2.0.0" + inherits "2" + minimatch "~0.2.11" + +graceful-fs@~2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-2.0.3.tgz#7cd2cdb228a4a3f36e95efa6cc142de7d1a136d0" + integrity sha1-fNLNsiiko/Nule+mzBQt59GhNtA= + +growl@1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.8.1.tgz#4b2dec8d907e93db336624dcec0183502f8c9428" + integrity sha1-Sy3sjZB+k9szZiTc7AGDUC+MlCg= + +inherits@2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +jade@0.26.3: + version "0.26.3" + resolved "https://registry.yarnpkg.com/jade/-/jade-0.26.3.tgz#8f10d7977d8d79f2f6ff862a81b0513ccb25686c" + integrity sha1-jxDXl32NefL2/4YqgbBRPMslaGw= + dependencies: + commander "0.6.1" + mkdirp "0.3.0" + +lru-cache@2: + version "2.7.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" + integrity sha1-bUUk6LlV+V1PW1iFHOId1y+06VI= + +minimatch@~0.2.11: + version "0.2.14" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.2.14.tgz#c74e780574f63c6f9a090e90efbe6ef53a6a756a" + integrity sha1-x054BXT2PG+aCQ6Q775u9TpqdWo= + dependencies: + lru-cache "2" + sigmund "~1.0.0" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + +mkdirp@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e" + integrity sha1-G79asbqCevI1dRQ0kEJkVfSB/h4= + +mkdirp@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.0.tgz#1d73076a6df986cd9344e15e71fcc05a4c9abf12" + integrity sha1-HXMHam35hs2TROFecfzAWkyavxI= + dependencies: + minimist "0.0.8" + +mocha@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-2.0.1.tgz#5a16e88b856d0c4145d8c6888c27ebd4fab13e90" + integrity sha1-Whboi4VtDEFF2MaIjCfr1PqxPpA= + dependencies: + commander "2.3.0" + debug "2.0.0" + diff "1.0.8" + escape-string-regexp "1.0.2" + glob "3.2.3" + growl "1.8.1" + jade "0.26.3" + mkdirp "0.5.0" + +ms@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.6.2.tgz#d89c2124c6fdc1353d65a8b77bf1aac4b193708c" + integrity sha1-2JwhJMb9wTU9Zai3e/GqxLGTcIw= + +reflect-metadata@^0.1.3: + version "0.1.12" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.12.tgz#311bf0c6b63cd782f228a81abe146a2bfa9c56f2" + integrity sha512-n+IyV+nGz3+0q3/Yf1ra12KpCyi001bi4XFxSjbiWWjfqb52iTTtpGXmCCAOWWIAn9KEuFZKGqBERHmrtScZ3A== + +sigmund@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA= + +type-detect@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-0.1.1.tgz#0ba5ec2a885640e470ea4e8505971900dac58822" + integrity sha1-C6XsKohWQORw6k6FBZcZANrFiCI= From f7a8fdd3f2088c44d7215b795137b7cc8d6c7871 Mon Sep 17 00:00:00 2001 From: Erik O'Leary Date: Wed, 5 Dec 2018 09:20:40 -0600 Subject: [PATCH 2/2] Find case insensitive with custom converter --- index.js | 12 +++++++++--- index.ts | 4 +++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index 5282bb4..8cad651 100644 --- a/index.js +++ b/index.js @@ -39,7 +39,6 @@ function JsonProperty(metadata) { decoratorMetaData = metadata; } else { - // throw new Error('index.ts: meta data in Json property is undefined. meta data: ' + metadata) decoratorMetaData = new DecoratorMetaData(); } return Reflect.metadata(JSON_META_DATA_KEY, decoratorMetaData); @@ -82,6 +81,12 @@ function hasAnyNullOrUndefined() { } return args.some(function (arg) { return arg === null || arg === undefined; }); } +/** + * Ensure obj has key, otherwise try to find case-insensitve version of key + * + * @param obj + * @param key + */ function getCaseInsensitiveMatch(obj, key) { if (obj.hasOwnProperty(key)) return key; @@ -89,7 +94,7 @@ function getCaseInsensitiveMatch(obj, key) { var newKey = Object.keys(obj).find(function (i) { return key.toUpperCase() === i.toUpperCase(); }); - return newKey; + return newKey || key; } } function mapFromJson(decoratorMetadata, instance, json, key) { @@ -151,7 +156,8 @@ function deserialize(Clazz, json) { * pass value to instance */ if (decoratorMetaData && decoratorMetaData.customConverter) { - instance[key] = decoratorMetaData.customConverter.fromJson(json[decoratorMetaData.name || key]); + var jsonKey = getCaseInsensitiveMatch(json, decoratorMetaData.name || key); + instance[key] = decoratorMetaData.customConverter.fromJson(json[jsonKey]); } else { instance[key] = decoratorMetaData ? mapFromJson(decoratorMetaData, instance, json, key) : json[key]; diff --git a/index.ts b/index.ts index fc4b9f9..e25cd38 100644 --- a/index.ts +++ b/index.ts @@ -201,7 +201,9 @@ export function deserialize(Clazz: {new(): T}, json: I * pass value to instance */ if (decoratorMetaData && decoratorMetaData.customConverter) { - instance[key] = decoratorMetaData.customConverter.fromJson(json[decoratorMetaData.name || key]); + let jsonKey = getCaseInsensitiveMatch(json, decoratorMetaData.name || key); + + instance[key] = decoratorMetaData.customConverter.fromJson(json[jsonKey]); } else { instance[key] = decoratorMetaData ? mapFromJson(decoratorMetaData, instance, json, key) : json[key]; }