Skip to content

Commit

Permalink
Merge pull request #37 from Prefinem/parse
Browse files Browse the repository at this point in the history
Transform types 'post' and 'pre'
  • Loading branch information
William authored Feb 24, 2019
2 parents 2b3ce64 + 62b6365 commit 09d1dc0
Show file tree
Hide file tree
Showing 8 changed files with 313 additions and 210 deletions.
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,22 +138,27 @@ Forces the value to be required. Is ignored if default value is set

Requires the value that is passed in to be the correct datatype instead of coerced

### datatypes.transform(transformFunction)
### datatypes.transform(transformFunction, type = 'post')

Takes a validated value, and transforms it according to the transform function

#### Types

- `post` - happens after validation
- `pre` - happens before validation

```js
const { createModel } = require('nativemodels');
const { string } = require('nativiemodels/datatypes');

const schema = {
name: string().transform((value) => value.toUpperCase()),
id: int().transform((value) => parseInt(value), 'pre'),
};
const model = createModel(schema);
const user = model({ name: 'john' });
const user = model({ name: 'john', id: '1' });

console.log(user.name);
// => 'JOHN'
// => { name: 'JOHN', id: 1 }
```

### datatypes.from(fromKeys, options)
Expand Down
4 changes: 3 additions & 1 deletion src/createModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ const recaseKeys = require('./lib/recaseKeys');
const requireAllKeys = require('./lib/requireAllKeys');
const requiredCheck = require('./lib/requiredCheck');
const stripUndefinedKeys = require('./lib/stripUndefinedKeys');
const transformRecord = require('./lib/transformRecord');

const buildRecord = (schema, record, options) => {
const mappedRecord = mapRecord(schema, record, options.caseSensitive);
const stripedRecord = options.stripUndefined ? stripUndefinedKeys(schema, mappedRecord) : mappedRecord;
const transformedRecord = transformRecord(schema, mappedRecord);
const stripedRecord = options.stripUndefined ? stripUndefinedKeys(schema, transformedRecord) : transformedRecord;
const casedRecord = options.caseSensitive ? stripedRecord : recaseKeys(schema, stripedRecord);
const defaultedRecord = defaultRecord(schema, casedRecord);

Expand Down
5 changes: 3 additions & 2 deletions src/datatypes/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ const chainable = {

return this;
},
transform(fn) {
this.transformFn = fn;
transform(fn, type = 'post') {
this.transforms = this.transforms || {};
this.transforms[type] = fn;

return this;
},
Expand Down
3 changes: 2 additions & 1 deletion src/lib/parseValue.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable max-params */
const invalidTypeCheck = require('./checks/invalidType');
const { isNull } = require('./checks/types');
const transformValue = require('./transformValue');

const checks = {
required: require('./checks/required'),
Expand All @@ -27,7 +28,7 @@ const parseValue = (type, key, value, allowNulls) => {

const parsedValue = type.parse(key, value);

return type.transformFn ? type.transformFn(parsedValue) : parsedValue;
return transformValue(type, parsedValue, 'post');
};

module.exports = parseValue;
12 changes: 12 additions & 0 deletions src/lib/transformRecord.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const transformValue = require('./transformValue');

const transformRecord = (schema, record) =>
Object.keys(record).reduce(
(result, key) => ({
...result,
[key]: schema[key] ? transformValue(schema[key], record[key], 'pre') : record[key],
}),
{},
);

module.exports = transformRecord;
4 changes: 4 additions & 0 deletions src/lib/transformValue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const transformValue = (type, value, key) =>
type.transforms && type.transforms[key] ? type.transforms[key](value) : value;

module.exports = transformValue;
23 changes: 23 additions & 0 deletions tests/transform.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const {
createModel,
customtypes: { email },
datatypes: { string },
} = require('./../src');

test('transform - pre', async () => {
const schema = {
foo: email().transform((value) => (value === '' ? undefined : value), 'pre'),
};
const model = createModel(schema);

await expect(model({ foo: '' })).toEqual({});
});

test('transform - post', async () => {
const schema = {
foo: string().transform((value) => (value === '' ? 'bar' : value), 'post'),
};
const model = createModel(schema);

await expect(model({ foo: '' })).toEqual({ foo: 'bar' });
});
Loading

0 comments on commit 09d1dc0

Please sign in to comment.