Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

validate 🎁🎅 #308

Draft
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

dotnetCarpenter
Copy link

@dotnetCarpenter dotnetCarpenter commented Dec 24, 2021

Signature

validate :: Type -> a -> Either (Array ValidationError) a

Example

// Right (undefined)
const valid   = $.validate ($.Undefined) (undefined);

// Left ([{"error": "WrongValue", "name": "$$", "type": "Undefined", "value": 1}])
const invalid = $.validate ($.Undefined) (1);

Task before merge

Description

Takes a type, and any value. Returns Right a if
the value is a member of the type;
Left (Array ValidationError) for each property
that is invalid. The first index in a Left array
is always named $$, which refers to the entire value.

Custom Type Example

//    $DateIso :: NullaryType
const $DateIso = (
  $.NullaryType ('DateIso')
                ('https://www.w3.org/QA/Tips/iso-date')
                ([$.String])
                (x => /^\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[1-2]\d|3[0-1])$/.test (x))
);

const model = $.RecordType ({
  date: $.NonEmpty ($DateIso),
  bool: $.Boolean,
});

// Right ({"bool": false, "date": "2020-04-10"})
const valid   = $.validate (model) ({date: '2020-04-10', bool: false});

/* Left ([
  {"error": "WrongValue", "name": "$$", "type": "RECORD", "value": {"bool": "foobar", "date": "2020-04-100"}},
  {"error": "WrongValue", "name": "date", "type": "DateIso", "value": "2020-04-100"},
  {"error": "WrongValue", "name": "bool", "type": "Boolean", "value": "foobar"}
]) */
const invalid = $.validate (model) ({date: '2020-04-100', bool: 'foobar'});

/* Left ([
  {"error": "WrongValue", "name": "$$", "type": "RECORD", "value": {"bool": false}},
  {"error": "MissingValue", "name": "date", "type": "NonEmpty", "value": undefined}
]) */
const invalid = $.validate (model) ({bool: false});

Ref: #274

index.js Outdated
Comment on lines 1539 to 1542
// TODO: figure what propPath really is
type: result.value.propPath.length > 0
? type.types[result.value.propPath[0]].name
: type.name,
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davidchambers this part I'm really not sure about. The idea is to get the name of the Type that is invalid for nested types. I haven't seen any propPath that didn't exactly contain ['$1'] but I'm sure that there are cases.

This commit also marks the first use of Z (sanctuary-type-classes),
which should open up for many of the code reductions we already know
from Sanctuary.

Added one more test for Types with properties/keys, without a name, are
missing and the value is null/undefined.
index.js Outdated
Comment on lines 1547 to 1555
return Left ({
error: 'WrongValue',
// TODO: figure out what propPath really is
type: p.result.value.propPath.length > 0
? p.type.types[p.result.value.propPath[0]].name
: p.type.name,
name: p.name,
value: p.value
});
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davidchambers this part I'm really not sure about. The idea is to get the name of the Type that is invalid for nested types. I haven't seen any propPath that didn't exactly contain ['$1'] but I'm sure that there are cases.

@dotnetCarpenter
Copy link
Author

Since a value can have 3 distinct outcomes, I think that it would make the code more readable to encode that as a sum type.

  1. Right a A value is correct.
  2. Left MissingValue Property is missing on the value.
  3. Left WrongValue Value is wrong or property value on the value is wrong.

@davidchambers How do you feel about requiring daggy in sanctuary-def?
I haven't done anything with daggy yet and won't try if you don't feel it should be a dependency of sanctuary-def.

test/index.js Outdated Show resolved Hide resolved
This commit adds two extra functions, a curried `map` and `lefts`.

There is plenty of room for optimization but we should validate the concept
with a simple example application before optimizing.
@dotnetCarpenter
Copy link
Author

There is plenty of room for optimization but before I do any of that, I want to create a simple form validation example using the new $.validate.

@davidchambers I really need you help to understand propPath.
I might also need your help with sanctuary-benchmark. I looked at it before for https://github.com/dotnetCarpenter/express-mime-sniff but was not able to get anything working.

@dotnetCarpenter dotnetCarpenter marked this pull request as draft January 4, 2022 21:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants