decoders 2.0.0-beta7 → 2.0.0-beta8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,10 @@
1
1
  // @flow strict
2
2
 
3
3
  import { annotate } from '../annotate';
4
- import { compose, predicate } from './composition';
4
+ import { either } from './either';
5
5
  import { err, ok } from '../result';
6
+ import { instanceOf } from './instanceOf';
7
+ import { map, predicate } from './composition';
6
8
  import type { Decoder } from '../_types';
7
9
 
8
10
  /** Match groups in this regex:
@@ -15,9 +17,6 @@ import type { Decoder } from '../_types';
15
17
  const url_re =
16
18
  /^([A-Za-z]{3,9}(?:[+][A-Za-z]{3,9})?):\/\/(?:([-;:&=+$,\w]+)@)?(?:([A-Za-z0-9.-]+)(?::([0-9]{2,5}))?)(\/(?:[-+~%/.,\w]*)?(?:\?[-+=&;%@.,\w]*)?(?:#[.,!/\w]*)?)?$/;
17
19
 
18
- // The URL schemes the url() decoder accepts by default
19
- const DEFAULT_SCHEMES = ['https'];
20
-
21
20
  /**
22
21
  * Decoder that only returns Ok for string inputs. Err otherwise.
23
22
  */
@@ -36,10 +35,7 @@ export const nonEmptyString: Decoder<string> = regex(/\S/, 'Must be non-empty st
36
35
  * before testing the regex.
37
36
  */
38
37
  export function regex(regex: RegExp, msg: string): Decoder<string> {
39
- return compose(
40
- string,
41
- predicate((s) => regex.test(s), msg),
42
- );
38
+ return predicate(string, (s) => regex.test(s), msg);
43
39
  }
44
40
 
45
41
  /**
@@ -51,30 +47,13 @@ export const email: Decoder<string> = regex(
51
47
  'Must be email',
52
48
  );
53
49
 
54
- /**
55
- * Decoder that only returns Ok for string inputs that match URLs of the
56
- * expected scheme. Defaults to only accept HTTPS URLs. Err otherwise.
57
- *
58
- * Variants that can be used:
59
- *
60
- * - url() accepts only https:// URLs
61
- * - url([]) accepts any URL scheme
62
- * - url(['http']) accepts only HTTP
63
- * - url(['https', 'git+ssh']) accepts both https:// and git+ssh:// URLs
64
- */
65
- export const url = (schemes: $ReadOnlyArray<string> = DEFAULT_SCHEMES): Decoder<string> =>
66
- compose(string, (value: string) => {
67
- const matches = value.match(url_re);
68
- if (!matches) {
69
- return err(annotate(value, 'Must be URL'));
70
- } else {
71
- const scheme = matches[1];
72
- if (schemes.length === 0 || schemes.includes(scheme.toLowerCase())) {
73
- return ok(value);
74
- } else {
75
- return err(
76
- annotate(value, `URL scheme must be any of: ${schemes.join(', ')}`),
77
- );
78
- }
79
- }
80
- });
50
+ export const url: Decoder<URL> = either(
51
+ map(regex(url_re, 'Must be URL'), (value) => new URL(value)),
52
+ instanceOf(URL),
53
+ );
54
+
55
+ export const httpsUrl: Decoder<URL> = predicate(
56
+ url,
57
+ (value) => value.protocol === 'https:',
58
+ 'Must be an HTTPS URL',
59
+ );
package/core/string.mjs CHANGED
@@ -1,6 +1,8 @@
1
1
  import { annotate } from '../annotate.mjs';
2
- import { compose, predicate } from './composition.mjs';
2
+ import { either } from './either.mjs';
3
3
  import { err, ok } from '../result.mjs';
4
+ import { instanceOf } from './instanceOf.mjs';
5
+ import { map, predicate } from './composition.mjs';
4
6
 
5
7
  /** Match groups in this regex:
6
8
  * \1 - the scheme
@@ -9,9 +11,7 @@ import { err, ok } from '../result.mjs';
9
11
  * \4 - the port (optional)
10
12
  * \5 - the path (optional)
11
13
  */
12
- var url_re = /^([A-Za-z]{3,9}(?:[+][A-Za-z]{3,9})?):\/\/(?:([-;:&=+$,\w]+)@)?(?:([A-Za-z0-9.-]+)(?::([0-9]{2,5}))?)(\/(?:[-+~%/.,\w]*)?(?:\?[-+=&;%@.,\w]*)?(?:#[.,!/\w]*)?)?$/; // The URL schemes the url() decoder accepts by default
13
-
14
- var DEFAULT_SCHEMES = ['https'];
14
+ var url_re = /^([A-Za-z]{3,9}(?:[+][A-Za-z]{3,9})?):\/\/(?:([-;:&=+$,\w]+)@)?(?:([A-Za-z0-9.-]+)(?::([0-9]{2,5}))?)(\/(?:[-+~%/.,\w]*)?(?:\?[-+=&;%@.,\w]*)?(?:#[.,!/\w]*)?)?$/;
15
15
  /**
16
16
  * Decoder that only returns Ok for string inputs. Err otherwise.
17
17
  */
@@ -31,9 +31,9 @@ export var nonEmptyString = regex(/\S/, 'Must be non-empty string');
31
31
  */
32
32
 
33
33
  export function regex(regex, msg) {
34
- return compose(string, predicate(function (s) {
34
+ return predicate(string, function (s) {
35
35
  return regex.test(s);
36
- }, msg));
36
+ }, msg);
37
37
  }
38
38
  /**
39
39
  * Decoder that only returns Ok for string inputs that match the almost perfect
@@ -41,36 +41,9 @@ export function regex(regex, msg) {
41
41
  */
42
42
 
43
43
  export var email = regex(/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/, 'Must be email');
44
- /**
45
- * Decoder that only returns Ok for string inputs that match URLs of the
46
- * expected scheme. Defaults to only accept HTTPS URLs. Err otherwise.
47
- *
48
- * Variants that can be used:
49
- *
50
- * - url() accepts only https:// URLs
51
- * - url([]) accepts any URL scheme
52
- * - url(['http']) accepts only HTTP
53
- * - url(['https', 'git+ssh']) accepts both https:// and git+ssh:// URLs
54
- */
55
-
56
- export var url = function url(schemes) {
57
- if (schemes === void 0) {
58
- schemes = DEFAULT_SCHEMES;
59
- }
60
-
61
- return compose(string, function (value) {
62
- var matches = value.match(url_re);
63
-
64
- if (!matches) {
65
- return err(annotate(value, 'Must be URL'));
66
- } else {
67
- var scheme = matches[1];
68
-
69
- if (schemes.length === 0 || schemes.includes(scheme.toLowerCase())) {
70
- return ok(value);
71
- } else {
72
- return err(annotate(value, "URL scheme must be any of: " + schemes.join(', ')));
73
- }
74
- }
75
- });
76
- };
44
+ export var url = either(map(regex(url_re, 'Must be URL'), function (value) {
45
+ return new URL(value);
46
+ }), instanceOf(URL));
47
+ export var httpsUrl = predicate(url, function (value) {
48
+ return value.protocol === 'https:';
49
+ }, 'Must be an HTTPS URL');
package/core/tuple.js CHANGED
@@ -21,9 +21,9 @@ function okOrErr(result) {
21
21
  }
22
22
 
23
23
  var ntuple = function ntuple(n) {
24
- return (0, _composition.compose)(_array.poja, (0, _composition.predicate)(function (arr) {
24
+ return (0, _composition.predicate)(_array.poja, function (arr) {
25
25
  return arr.length === n;
26
- }, "Must be a " + n + "-tuple"));
26
+ }, "Must be a " + n + "-tuple");
27
27
  };
28
28
  /**
29
29
  * Builds a Decoder that returns Ok for 1-tuple of [T], given a Decoder for T.
@@ -12,10 +12,7 @@ function okOrErr<T, E>(result: Result<T, E>): T | E {
12
12
  }
13
13
 
14
14
  const ntuple = (n: number) =>
15
- compose(
16
- poja,
17
- predicate((arr) => arr.length === n, `Must be a ${n}-tuple`),
18
- );
15
+ predicate(poja, (arr) => arr.length === n, `Must be a ${n}-tuple`);
19
16
 
20
17
  /**
21
18
  * Builds a Decoder that returns Ok for 1-tuple of [T], given a Decoder for T.
package/core/tuple.mjs CHANGED
@@ -8,9 +8,9 @@ function okOrErr(result) {
8
8
  }
9
9
 
10
10
  var ntuple = function ntuple(n) {
11
- return compose(poja, predicate(function (arr) {
11
+ return predicate(poja, function (arr) {
12
12
  return arr.length === n;
13
- }, "Must be a " + n + "-tuple"));
13
+ }, "Must be a " + n + "-tuple");
14
14
  };
15
15
  /**
16
16
  * Builds a Decoder that returns Ok for 1-tuple of [T], given a Decoder for T.
package/index.d.ts CHANGED
@@ -19,7 +19,7 @@ export { boolean, numericBoolean, truthy } from './core/boolean';
19
19
  export { constant, hardcoded, mixed, null_, undefined_, unknown } from './core/constants';
20
20
  export { date, iso8601 } from './core/date';
21
21
  export { describe } from './core/describe';
22
- export { dispatch } from './core/dispatch';
22
+ export { disjointUnion } from './core/dispatch';
23
23
  export {
24
24
  either,
25
25
  either3,
@@ -39,5 +39,5 @@ export { mapping, dict } from './core/mapping';
39
39
  export { integer, number, positiveInteger, positiveNumber } from './core/number';
40
40
  export { exact, inexact, object, pojo } from './core/object';
41
41
  export { maybe, nullable, optional } from './core/optional';
42
- export { email, nonEmptyString, regex, string, url } from './core/string';
42
+ export { email, httpsUrl, nonEmptyString, regex, string, url } from './core/string';
43
43
  export { tuple1, tuple2, tuple3, tuple4, tuple5, tuple6 } from './core/tuple';
package/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  exports.__esModule = true;
4
- exports.url = exports.unknown = exports.undefined_ = exports.tuple6 = exports.tuple5 = exports.tuple4 = exports.tuple3 = exports.tuple2 = exports.tuple1 = exports.truthy = exports.string = exports.regex = exports.predicate = exports.positiveNumber = exports.positiveInteger = exports.pojo = exports.poja = exports.optional = exports.oneOf = exports.object = exports.numericBoolean = exports.number = exports.nullable = exports.null_ = exports.nonEmptyString = exports.nonEmptyArray = exports.mixed = exports.maybe = exports.mapping = exports.map = exports.lazy = exports.jsonObject = exports.jsonArray = exports.json = exports.iso8601 = exports.integer = exports.instanceOf = exports.inexact = exports.hardcoded = exports.guard = exports.fail = exports.exact = exports.email = exports.either9 = exports.either8 = exports.either7 = exports.either6 = exports.either5 = exports.either4 = exports.either3 = exports.either = exports.dispatch = exports.dict = exports.describe = exports.date = exports.constant = exports.compose = exports["boolean"] = exports.array = void 0;
4
+ exports.url = exports.unknown = exports.undefined_ = exports.tuple6 = exports.tuple5 = exports.tuple4 = exports.tuple3 = exports.tuple2 = exports.tuple1 = exports.truthy = exports.string = exports.regex = exports.predicate = exports.positiveNumber = exports.positiveInteger = exports.pojo = exports.poja = exports.optional = exports.oneOf = exports.object = exports.numericBoolean = exports.number = exports.nullable = exports.null_ = exports.nonEmptyString = exports.nonEmptyArray = exports.mixed = exports.maybe = exports.mapping = exports.map = exports.lazy = exports.jsonObject = exports.jsonArray = exports.json = exports.iso8601 = exports.integer = exports.instanceOf = exports.inexact = exports.httpsUrl = exports.hardcoded = exports.guard = exports.fail = exports.exact = exports.email = exports.either9 = exports.either8 = exports.either7 = exports.either6 = exports.either5 = exports.either4 = exports.either3 = exports.either = exports.disjointUnion = exports.dict = exports.describe = exports.date = exports.constant = exports.compose = exports["boolean"] = exports.array = void 0;
5
5
 
6
6
  var _guard = require("./_guard");
7
7
 
@@ -45,7 +45,7 @@ exports.describe = _describe.describe;
45
45
 
46
46
  var _dispatch = require("./core/dispatch");
47
47
 
48
- exports.dispatch = _dispatch.dispatch;
48
+ exports.disjointUnion = _dispatch.disjointUnion;
49
49
 
50
50
  var _either = require("./core/either");
51
51
 
@@ -105,6 +105,7 @@ exports.optional = _optional.optional;
105
105
  var _string = require("./core/string");
106
106
 
107
107
  exports.email = _string.email;
108
+ exports.httpsUrl = _string.httpsUrl;
108
109
  exports.nonEmptyString = _string.nonEmptyString;
109
110
  exports.regex = _string.regex;
110
111
  exports.string = _string.string;
package/index.js.flow CHANGED
@@ -39,7 +39,7 @@ export { boolean, numericBoolean, truthy } from './core/boolean';
39
39
  export { constant, hardcoded, mixed, null_, undefined_, unknown } from './core/constants';
40
40
  export { date, iso8601 } from './core/date';
41
41
  export { describe } from './core/describe';
42
- export { dispatch } from './core/dispatch';
42
+ export { disjointUnion } from './core/dispatch';
43
43
  export {
44
44
  either,
45
45
  either3,
@@ -59,5 +59,5 @@ export { mapping, dict } from './core/mapping';
59
59
  export { integer, number, positiveInteger, positiveNumber } from './core/number';
60
60
  export { exact, inexact, object, pojo } from './core/object';
61
61
  export { maybe, nullable, optional } from './core/optional';
62
- export { email, nonEmptyString, regex, string, url } from './core/string';
62
+ export { email, httpsUrl, nonEmptyString, regex, string, url } from './core/string';
63
63
  export { tuple1, tuple2, tuple3, tuple4, tuple5, tuple6 } from './core/tuple';
package/index.mjs CHANGED
@@ -23,7 +23,7 @@ export { boolean, numericBoolean, truthy } from './core/boolean.mjs';
23
23
  export { constant, hardcoded, mixed, null_, undefined_, unknown } from './core/constants.mjs';
24
24
  export { date, iso8601 } from './core/date.mjs';
25
25
  export { describe } from './core/describe.mjs';
26
- export { dispatch } from './core/dispatch.mjs';
26
+ export { disjointUnion } from './core/dispatch.mjs';
27
27
  export { either, either3, either4, either5, either6, either7, either8, either9, oneOf } from './core/either.mjs';
28
28
  export { fail } from './core/fail.mjs';
29
29
  export { instanceOf } from './core/instanceOf.mjs';
@@ -33,5 +33,5 @@ export { mapping, dict } from './core/mapping.mjs';
33
33
  export { integer, number, positiveInteger, positiveNumber } from './core/number.mjs';
34
34
  export { exact, inexact, object, pojo } from './core/object.mjs';
35
35
  export { maybe, nullable, optional } from './core/optional.mjs';
36
- export { email, nonEmptyString, regex, string, url } from './core/string.mjs';
36
+ export { email, httpsUrl, nonEmptyString, regex, string, url } from './core/string.mjs';
37
37
  export { tuple1, tuple2, tuple3, tuple4, tuple5, tuple6 } from './core/tuple.mjs';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "decoders",
3
- "version": "2.0.0-beta7",
3
+ "version": "2.0.0-beta8",
4
4
  "description": "Elegant and battle-tested validation library for type-safe input data (for TypeScript and Flow)",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -40,11 +40,6 @@
40
40
  "map",
41
41
  "predicate"
42
42
  ],
43
- "*": {
44
- "*": [
45
- "NotSupportedTSVersion.d.ts"
46
- ]
47
- },
48
43
  "githubUrl": "https://github.com/nvie/decoders",
49
44
  "sideEffects": false,
50
45
  "typesVersions": {
@@ -52,6 +47,11 @@
52
47
  "*": [
53
48
  "*"
54
49
  ]
50
+ },
51
+ "*": {
52
+ "*": [
53
+ "NotSupportedTSVersion.d.ts"
54
+ ]
55
55
  }
56
56
  }
57
57
  }