From 963d2e8afbf1c17885c45fffc89bf6594e981c19 Mon Sep 17 00:00:00 2001 From: Jason Quense Date: Thu, 19 Nov 2020 11:11:44 -0500 Subject: [PATCH] feat: more strictly coerce strings, exclude arrays and plain objects BREAKING CHANGE: plain objects and arrays are no long cast to strings automatically to recreate the old behavior: ```js string().transform((_, input) => input != null && input.toString ? input.toString() : value); ``` --- src/string.js | 17 ++++++++++++----- test/string.js | 10 ++++++++-- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/string.js b/src/string.js index e6cdcf711..8088aa612 100644 --- a/src/string.js +++ b/src/string.js @@ -8,10 +8,12 @@ let rEmail = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\u // eslint-disable-next-line let rUrl = /^((https?|ftp):)?\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i; // eslint-disable-next-line -let rUUID = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i +let rUUID = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i; let isTrimmed = (value) => isAbsent(value) || value === value.trim(); +let objStringTag = {}.toString(); + export default function StringSchema() { if (!(this instanceof StringSchema)) return new StringSchema(); @@ -20,7 +22,14 @@ export default function StringSchema() { this.withMutation(() => { this.transform(function (value) { if (this.isType(value)) return value; - return value != null && value.toString ? value.toString() : value; + if (Array.isArray(value)) return value; + + const strValue = + value != null && value.toString ? value.toString() : value; + + if (strValue === objStringTag) return value; + + return strValue; }); }); } @@ -33,9 +42,7 @@ inherits(StringSchema, MixedSchema, { }, _isPresent(value) { - return ( - MixedSchema.prototype._isPresent.call(this, value) && value.length > 0 - ); + return MixedSchema.prototype._isPresent.call(this, value) && !!value.length; }, length(length, message = locale.length) { diff --git a/test/string.js b/test/string.js index 1e129bff7..cd79a64e9 100644 --- a/test/string.js +++ b/test/string.js @@ -10,14 +10,20 @@ describe('String types', () => { valid: [ [5, '5'], ['3', '3'], - //[new String('foo'), 'foo'], + // [new String('foo'), 'foo'], ['', ''], [true, 'true'], [false, 'false'], [0, '0'], [null, null, schema.nullable()], + [ + { + toString: () => 'hey', + }, + 'hey', + ], ], - invalid: [null], + invalid: [null, {}, []], }); describe('ensure', () => {