From 8bdf8db5ecf1a444b45a7f02cbd63b8cfbff2631 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Tue, 12 Sep 2017 22:53:42 -0700 Subject: [PATCH] feat(unmarshal): add rudimentary support for $transform --- src/unmarshal/index.js | 13 +++++++++---- src/unmarshal/util.js | 8 ++++++-- test/unit.test.js | 16 ++++++++++++++-- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/unmarshal/index.js b/src/unmarshal/index.js index ddbb32f..f4e0c9b 100644 --- a/src/unmarshal/index.js +++ b/src/unmarshal/index.js @@ -120,7 +120,8 @@ function visitArray(arr, schema, projection, path) { } try { - handleCast(arr, index, schema._paths[newPath].$type); + const pathOptions = schema._paths[newPath]; + handleCast(arr, index, pathOptions.$type, pathOptions.$transform); } catch(err) { error.markError(join(path, index, true), err); } @@ -168,8 +169,9 @@ function visitObject(obj, schema, projection, path) { // If type not specified, no type casting return; } + const pathOptions = schema._paths[newPath]; - if (schema._paths[newPath].$type === Array || + if (pathOptions.$type === Array || Array.isArray(schema._paths[newPath].$type)) { let res = visitArray(value, schema, projection, newPath); if (res.error) { @@ -178,11 +180,14 @@ function visitObject(obj, schema, projection, path) { } obj[key] = res.value; return; - } else if (schema._paths[newPath].$type === Object) { + } else if (pathOptions.$type === Object) { if (value == null) { delete obj[key]; return; } + if (pathOptions.$transform != null) { + value = pathOptions.$transform(obj[key]); + } let res = visitObject(value, schema, projection, newPath); if (res.error) { debug('merge', res.error.errors); @@ -193,7 +198,7 @@ function visitObject(obj, schema, projection, path) { } try { - handleCast(obj, key, schema._paths[newPath].$type); + handleCast(obj, key, pathOptions.$type, pathOptions.$transform); } catch(err) { error.markError(join(path, key, true), err); } diff --git a/src/unmarshal/util.js b/src/unmarshal/util.js index 6381c5f..5eff69e 100644 --- a/src/unmarshal/util.js +++ b/src/unmarshal/util.js @@ -2,8 +2,12 @@ const to = require('../to'); -exports.handleCast = function(obj, key, type) { - obj[key] = to(obj[key], type); +const noop = x => x; + +exports.handleCast = function(obj, key, type, transform) { + transform = transform == null ? noop : transform; + console.log('F', transform) + obj[key] = to(transform(obj[key]), type); }; exports.realPathToSchemaPath = function(path) { diff --git a/test/unit.test.js b/test/unit.test.js index 881b4f1..816a5c0 100644 --- a/test/unit.test.js +++ b/test/unit.test.js @@ -600,14 +600,26 @@ describe('unmarshal()', function() { assert.deepEqual(Test.paths().filter(v => !v.$description), [ { path: 'str', $type: 'string' } - ]) + ]); assert.deepEqual(Test.paths().filter(v => !!v.$description), [ { path: 'num', $type: 'number', $description: 'this is a number' } - ]) + ]); + }); + + it('$transform', function() { + const Test = new Archetype({ + str: { + $type: Object, + $transform: JSON.parse + } + }).compile(); + + const doc = new Test({ str: JSON.stringify({ hello: 'world' }) }); + assert.deepEqual(doc.str, { hello: 'world' }); }); it('to()', function() {