decoders 2.0.0-beta4 → 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.
Files changed (132) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/NotSupportedTSVersion.d.ts +1 -0
  3. package/README.md +728 -343
  4. package/_guard.d.ts +7 -0
  5. package/_guard.js +2 -6
  6. package/_guard.js.flow +3 -3
  7. package/{_esm/_guard.js → _guard.mjs} +3 -3
  8. package/_types.d.ts +13 -0
  9. package/{_esm/_types.js → _types.mjs} +0 -0
  10. package/_utils.d.ts +10 -0
  11. package/{_esm/_utils.js → _utils.mjs} +0 -0
  12. package/annotate.d.ts +62 -0
  13. package/{_esm/annotate.js → annotate.mjs} +0 -0
  14. package/core/_helpers.d.ts +79 -0
  15. package/core/array.d.ts +5 -0
  16. package/core/array.js +7 -11
  17. package/core/array.js.flow +6 -9
  18. package/{_esm/core/array.js → core/array.mjs} +9 -9
  19. package/core/boolean.d.ts +5 -0
  20. package/core/boolean.js +4 -8
  21. package/core/boolean.js.flow +3 -5
  22. package/{_esm/core/boolean.js → core/boolean.mjs} +6 -6
  23. package/core/composition.d.ts +14 -0
  24. package/core/composition.js +9 -11
  25. package/core/composition.js.flow +13 -8
  26. package/{_esm/core/composition.js → core/composition.mjs} +10 -8
  27. package/core/constants.d.ts +11 -0
  28. package/core/constants.js +6 -10
  29. package/core/constants.js.flow +7 -9
  30. package/{_esm/core/constants.js → core/constants.mjs} +7 -7
  31. package/core/date.d.ts +4 -0
  32. package/core/date.js +3 -7
  33. package/core/date.js.flow +2 -4
  34. package/{_esm/core/date.js → core/date.mjs} +6 -6
  35. package/core/describe.d.ts +3 -0
  36. package/core/describe.js +2 -6
  37. package/core/describe.js.flow +2 -2
  38. package/{_esm/core/describe.js → core/describe.mjs} +3 -3
  39. package/core/dispatch.d.ts +8 -0
  40. package/core/dispatch.js +9 -13
  41. package/core/dispatch.js.flow +8 -8
  42. package/{_esm/core/dispatch.js → core/dispatch.mjs} +10 -10
  43. package/core/either.d.ts +61 -0
  44. package/core/either.js +7 -11
  45. package/core/either.js.flow +6 -6
  46. package/{_esm/core/either.js → core/either.mjs} +8 -8
  47. package/core/fail.d.ts +3 -0
  48. package/core/fail.js +2 -6
  49. package/core/fail.js.flow +2 -2
  50. package/{_esm/core/fail.js → core/fail.mjs} +3 -3
  51. package/core/instanceOf.d.ts +3 -0
  52. package/core/instanceOf.js +2 -6
  53. package/core/instanceOf.js.flow +3 -3
  54. package/core/instanceOf.mjs +8 -0
  55. package/core/json.d.ts +11 -0
  56. package/core/json.mjs +15 -0
  57. package/core/lazy.d.ts +3 -0
  58. package/{_esm/core/lazy.js → core/lazy.mjs} +0 -0
  59. package/core/mapping.d.ts +6 -0
  60. package/core/mapping.js +23 -23
  61. package/core/mapping.js.flow +25 -17
  62. package/{_esm/core/mapping.js → core/mapping.mjs} +26 -22
  63. package/core/number.d.ts +6 -0
  64. package/core/number.js +9 -13
  65. package/core/number.js.flow +18 -12
  66. package/core/number.mjs +25 -0
  67. package/core/object.d.ts +33 -0
  68. package/core/object.js +7 -11
  69. package/core/object.js.flow +7 -7
  70. package/{_esm/core/object.js → core/object.mjs} +9 -9
  71. package/core/optional.d.ts +5 -0
  72. package/core/optional.js +4 -8
  73. package/core/optional.js.flow +3 -3
  74. package/{_esm/core/optional.js → core/optional.mjs} +6 -6
  75. package/core/string.d.ts +10 -0
  76. package/core/string.js +18 -48
  77. package/core/string.js.flow +16 -39
  78. package/core/string.mjs +49 -0
  79. package/core/tuple.d.ts +30 -0
  80. package/core/tuple.js +12 -8
  81. package/core/tuple.js.flow +25 -29
  82. package/{_esm/core/tuple.js → core/tuple.mjs} +16 -12
  83. package/format.d.ts +4 -0
  84. package/{format/inline.js → format.js} +6 -1
  85. package/{_esm/format/inline.js.flow → format.js.flow} +6 -2
  86. package/{_esm/format/inline.js → format.mjs} +4 -1
  87. package/index.d.ts +43 -0
  88. package/index.js +3 -2
  89. package/index.js.flow +2 -2
  90. package/{_esm/index.js → index.mjs} +19 -19
  91. package/package.json +15 -3
  92. package/result.d.ts +39 -0
  93. package/result.js +3 -78
  94. package/result.js.flow +4 -76
  95. package/{_esm/result.js → result.mjs} +3 -64
  96. package/_esm/_guard.js.flow +0 -20
  97. package/_esm/_types.js.flow +0 -20
  98. package/_esm/_utils.js.flow +0 -97
  99. package/_esm/annotate.js.flow +0 -218
  100. package/_esm/core/array.js.flow +0 -103
  101. package/_esm/core/boolean.js.flow +0 -29
  102. package/_esm/core/composition.js.flow +0 -43
  103. package/_esm/core/constants.js.flow +0 -46
  104. package/_esm/core/date.js.flow +0 -40
  105. package/_esm/core/describe.js.flow +0 -17
  106. package/_esm/core/dispatch.js.flow +0 -58
  107. package/_esm/core/either.js.flow +0 -151
  108. package/_esm/core/fail.js.flow +0 -12
  109. package/_esm/core/instanceOf.js +0 -8
  110. package/_esm/core/instanceOf.js.flow +0 -20
  111. package/_esm/core/json.js +0 -15
  112. package/_esm/core/json.js.flow +0 -28
  113. package/_esm/core/lazy.js.flow +0 -15
  114. package/_esm/core/mapping.js.flow +0 -54
  115. package/_esm/core/number.js +0 -25
  116. package/_esm/core/number.js.flow +0 -34
  117. package/_esm/core/object.js.flow +0 -203
  118. package/_esm/core/optional.js.flow +0 -41
  119. package/_esm/core/string.js +0 -76
  120. package/_esm/core/string.js.flow +0 -82
  121. package/_esm/core/tuple.js.flow +0 -215
  122. package/_esm/format/index.js +0 -2
  123. package/_esm/format/index.js.flow +0 -4
  124. package/_esm/format/short.js +0 -4
  125. package/_esm/format/short.js.flow +0 -8
  126. package/_esm/index.js.flow +0 -63
  127. package/_esm/result.js.flow +0 -170
  128. package/format/index.js +0 -12
  129. package/format/index.js.flow +0 -4
  130. package/format/inline.js.flow +0 -122
  131. package/format/short.js +0 -10
  132. package/format/short.js.flow +0 -8
package/core/object.js CHANGED
@@ -6,15 +6,11 @@ exports.inexact = inexact;
6
6
  exports.object = object;
7
7
  exports.pojo = void 0;
8
8
 
9
- var Result = _interopRequireWildcard(require("../result"));
10
-
11
9
  var _annotate = require("../annotate");
12
10
 
13
11
  var _composition = require("./composition");
14
12
 
15
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
16
-
17
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
13
+ var _result = require("../result");
18
14
 
19
15
  function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
20
16
 
@@ -36,7 +32,7 @@ function subtract(xs, ys) {
36
32
  }
37
33
 
38
34
  var pojo = function pojo(blob) {
39
- return isPojo(blob) ? Result.ok( // NOTE:
35
+ return isPojo(blob) ? (0, _result.ok)( // NOTE:
40
36
  // Since Flow 0.98, typeof o === 'object' refines to
41
37
  // {| +[string]: mixed |}
42
38
  // instead of
@@ -50,7 +46,7 @@ var pojo = function pojo(blob) {
50
46
  // way to turn a read-only Object to a writeable one in ES6 seems
51
47
  // to be to use object-spread. (Going off this benchmark:
52
48
  // https://thecodebarbarian.com/object-assign-vs-object-spread.html)
53
- _extends({}, blob)) : Result.err((0, _annotate.annotate)(blob, 'Must be an object'));
49
+ _extends({}, blob)) : (0, _result.err)((0, _annotate.annotate)(blob, 'Must be an object'));
54
50
  };
55
51
  /**
56
52
  * Given a mapping of fields-to-decoders, builds a decoder for an object type.
@@ -139,10 +135,10 @@ function object(mapping) {
139
135
  objAnn = (0, _annotate.updateText)(objAnn, "Missing " + pluralized + ": " + errMsg);
140
136
  }
141
137
 
142
- return Result.err(objAnn);
138
+ return (0, _result.err)(objAnn);
143
139
  }
144
140
 
145
- return Result.ok(record);
141
+ return (0, _result.ok)(record);
146
142
  });
147
143
  }
148
144
 
@@ -154,10 +150,10 @@ function exact(mapping) {
154
150
  var superfluous = subtract(actual, allowed);
155
151
 
156
152
  if (superfluous.size > 0) {
157
- return Result.err((0, _annotate.annotate)(blob, "Superfluous keys: " + Array.from(superfluous).join(', ')));
153
+ return (0, _result.err)((0, _annotate.annotate)(blob, "Superfluous keys: " + Array.from(superfluous).join(', ')));
158
154
  }
159
155
 
160
- return Result.ok(blob);
156
+ return (0, _result.ok)(blob);
161
157
  }); // Defer to the "object" decoder for doing the real decoding work. Since
162
158
  // we made sure there are no superfluous keys in this structure, it's now
163
159
  // safe to force-cast it to an $Exact<> type.
@@ -1,8 +1,8 @@
1
1
  // @flow strict
2
2
 
3
- import * as Result from '../result';
4
3
  import { annotate, annotateObject, merge, updateText } from '../annotate';
5
4
  import { compose, map } from './composition';
5
+ import { err, ok } from '../result';
6
6
  import type { Annotation } from '../annotate';
7
7
  import type { Decoder, DecoderType } from '../_types';
8
8
 
@@ -36,7 +36,7 @@ function subtract(xs: Set<string>, ys: Set<string>): Set<string> {
36
36
 
37
37
  export const pojo: Decoder<{| [string]: mixed |}> = (blob: mixed) => {
38
38
  return isPojo(blob)
39
- ? Result.ok(
39
+ ? ok(
40
40
  // NOTE:
41
41
  // Since Flow 0.98, typeof o === 'object' refines to
42
42
  // {| +[string]: mixed |}
@@ -53,7 +53,7 @@ export const pojo: Decoder<{| [string]: mixed |}> = (blob: mixed) => {
53
53
  // https://thecodebarbarian.com/object-assign-vs-object-spread.html)
54
54
  { ...blob },
55
55
  )
56
- : Result.err(annotate(blob, 'Must be an object'));
56
+ : err(annotate(blob, 'Must be an object'));
57
57
  };
58
58
 
59
59
  /**
@@ -144,10 +144,10 @@ export function object<O: { +[field: string]: AnyDecoder, ... }>(
144
144
  objAnn = updateText(objAnn, `Missing ${pluralized}: ${errMsg}`);
145
145
  }
146
146
 
147
- return Result.err(objAnn);
147
+ return err(objAnn);
148
148
  }
149
149
 
150
- return Result.ok(record);
150
+ return ok(record);
151
151
  });
152
152
  }
153
153
 
@@ -160,11 +160,11 @@ export function exact<O: { +[field: string]: AnyDecoder, ... }>(
160
160
  const actual = new Set(Object.keys(blob));
161
161
  const superfluous = subtract(actual, allowed);
162
162
  if (superfluous.size > 0) {
163
- return Result.err(
163
+ return err(
164
164
  annotate(blob, `Superfluous keys: ${Array.from(superfluous).join(', ')}`),
165
165
  );
166
166
  }
167
- return Result.ok(blob);
167
+ return ok(blob);
168
168
  });
169
169
 
170
170
  // Defer to the "object" decoder for doing the real decoding work. Since
@@ -1,8 +1,8 @@
1
1
  function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
2
 
3
- import * as Result from '../result';
4
- import { annotate, annotateObject, merge, updateText } from '../annotate';
5
- import { compose, map } from './composition';
3
+ import { annotate, annotateObject, merge, updateText } from '../annotate.mjs';
4
+ import { compose, map } from './composition.mjs';
5
+ import { err, ok } from '../result.mjs';
6
6
 
7
7
  function isPojo(o) {
8
8
  return o !== null && o !== undefined && typeof o === 'object' && // This still seems to be the only reliable way to determine whether
@@ -22,7 +22,7 @@ function subtract(xs, ys) {
22
22
  }
23
23
 
24
24
  export var pojo = function pojo(blob) {
25
- return isPojo(blob) ? Result.ok( // NOTE:
25
+ return isPojo(blob) ? ok( // NOTE:
26
26
  // Since Flow 0.98, typeof o === 'object' refines to
27
27
  // {| +[string]: mixed |}
28
28
  // instead of
@@ -36,7 +36,7 @@ export var pojo = function pojo(blob) {
36
36
  // way to turn a read-only Object to a writeable one in ES6 seems
37
37
  // to be to use object-spread. (Going off this benchmark:
38
38
  // https://thecodebarbarian.com/object-assign-vs-object-spread.html)
39
- _extends({}, blob)) : Result.err(annotate(blob, 'Must be an object'));
39
+ _extends({}, blob)) : err(annotate(blob, 'Must be an object'));
40
40
  };
41
41
  /**
42
42
  * Given a mapping of fields-to-decoders, builds a decoder for an object type.
@@ -122,10 +122,10 @@ export function object(mapping) {
122
122
  objAnn = updateText(objAnn, "Missing " + pluralized + ": " + errMsg);
123
123
  }
124
124
 
125
- return Result.err(objAnn);
125
+ return err(objAnn);
126
126
  }
127
127
 
128
- return Result.ok(record);
128
+ return ok(record);
129
129
  });
130
130
  }
131
131
  export function exact(mapping) {
@@ -136,10 +136,10 @@ export function exact(mapping) {
136
136
  var superfluous = subtract(actual, allowed);
137
137
 
138
138
  if (superfluous.size > 0) {
139
- return Result.err(annotate(blob, "Superfluous keys: " + Array.from(superfluous).join(', ')));
139
+ return err(annotate(blob, "Superfluous keys: " + Array.from(superfluous).join(', ')));
140
140
  }
141
141
 
142
- return Result.ok(blob);
142
+ return ok(blob);
143
143
  }); // Defer to the "object" decoder for doing the real decoding work. Since
144
144
  // we made sure there are no superfluous keys in this structure, it's now
145
145
  // safe to force-cast it to an $Exact<> type.
@@ -0,0 +1,5 @@
1
+ import { Decoder } from '../_types';
2
+
3
+ export function optional<T>(decoder: Decoder<T>): Decoder<T | undefined>;
4
+ export function nullable<T>(decoder: Decoder<T>): Decoder<T | null>;
5
+ export function maybe<T>(decoder: Decoder<T>): Decoder<T | null | undefined>;
package/core/optional.js CHANGED
@@ -5,17 +5,13 @@ exports.maybe = maybe;
5
5
  exports.nullable = nullable;
6
6
  exports.optional = optional;
7
7
 
8
- var Result = _interopRequireWildcard(require("../result"));
9
-
10
8
  var _annotate = require("../annotate");
11
9
 
12
10
  var _either = require("./either");
13
11
 
14
- var _constants = require("./constants");
15
-
16
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
12
+ var _result = require("../result");
17
13
 
18
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
14
+ var _constants = require("./constants");
19
15
 
20
16
  /**
21
17
  * Builds a Decoder that returns Ok for either `undefined` or `T` values,
@@ -41,8 +37,8 @@ function nullable(decoder) {
41
37
 
42
38
 
43
39
  var undefined_or_null = function undefined_or_null(blob) {
44
- return blob === undefined || blob === null ? Result.ok(blob) : // Combine error message into a single line
45
- Result.err((0, _annotate.annotate)(blob, 'Must be undefined or null'));
40
+ return blob === undefined || blob === null ? (0, _result.ok)(blob) : // Combine error message into a single line
41
+ (0, _result.err)((0, _annotate.annotate)(blob, 'Must be undefined or null'));
46
42
  };
47
43
  /**
48
44
  * Decoder that only returns Ok for `null` or `undefined` inputs.
@@ -1,8 +1,8 @@
1
1
  // @flow strict
2
2
 
3
- import * as Result from '../result';
4
3
  import { annotate } from '../annotate';
5
4
  import { either } from './either';
5
+ import { err, ok } from '../result';
6
6
  import { null_, undefined_ } from './constants';
7
7
  import type { Decoder } from '../_types';
8
8
 
@@ -29,9 +29,9 @@ export function nullable<T>(decoder: Decoder<T>): Decoder<null | T> {
29
29
  */
30
30
  const undefined_or_null: Decoder<null | void> = (blob: mixed) =>
31
31
  blob === undefined || blob === null
32
- ? Result.ok(blob)
32
+ ? ok(blob)
33
33
  : // Combine error message into a single line
34
- Result.err(annotate(blob, 'Must be undefined or null'));
34
+ err(annotate(blob, 'Must be undefined or null'));
35
35
 
36
36
  /**
37
37
  * Decoder that only returns Ok for `null` or `undefined` inputs.
@@ -1,7 +1,7 @@
1
- import * as Result from '../result';
2
- import { annotate } from '../annotate';
3
- import { either } from './either';
4
- import { null_, undefined_ } from './constants';
1
+ import { annotate } from '../annotate.mjs';
2
+ import { either } from './either.mjs';
3
+ import { err, ok } from '../result.mjs';
4
+ import { null_, undefined_ } from './constants.mjs';
5
5
 
6
6
  /**
7
7
  * Builds a Decoder that returns Ok for either `undefined` or `T` values,
@@ -25,8 +25,8 @@ export function nullable(decoder) {
25
25
  */
26
26
 
27
27
  var undefined_or_null = function undefined_or_null(blob) {
28
- return blob === undefined || blob === null ? Result.ok(blob) : // Combine error message into a single line
29
- Result.err(annotate(blob, 'Must be undefined or null'));
28
+ return blob === undefined || blob === null ? ok(blob) : // Combine error message into a single line
29
+ err(annotate(blob, 'Must be undefined or null'));
30
30
  };
31
31
  /**
32
32
  * Decoder that only returns Ok for `null` or `undefined` inputs.
@@ -0,0 +1,10 @@
1
+ /// <reference lib="dom" />
2
+
3
+ import { Decoder } from '../_types';
4
+
5
+ export const string: Decoder<string>;
6
+ export const nonEmptyString: Decoder<string>;
7
+ export function regex(regex: RegExp, msg: string): Decoder<string>;
8
+ export const email: Decoder<string>;
9
+ export const url: Decoder<URL>;
10
+ export const httpsUrl: Decoder<URL>;
package/core/string.js CHANGED
@@ -1,19 +1,19 @@
1
1
  "use strict";
2
2
 
3
3
  exports.__esModule = true;
4
- exports.nonEmptyString = exports.email = void 0;
4
+ exports.nonEmptyString = exports.httpsUrl = exports.email = void 0;
5
5
  exports.regex = regex;
6
6
  exports.url = exports.string = void 0;
7
7
 
8
- var Result = _interopRequireWildcard(require("../result"));
9
-
10
8
  var _annotate = require("../annotate");
11
9
 
12
- var _composition = require("./composition");
10
+ var _either = require("./either");
13
11
 
14
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
12
+ var _result = require("../result");
15
13
 
16
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
14
+ var _instanceOf = require("./instanceOf");
15
+
16
+ var _composition = require("./composition");
17
17
 
18
18
  /** Match groups in this regex:
19
19
  * \1 - the scheme
@@ -22,15 +22,13 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
22
22
  * \4 - the port (optional)
23
23
  * \5 - the path (optional)
24
24
  */
25
- 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
26
-
27
- var DEFAULT_SCHEMES = ['https'];
25
+ 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]*)?)?$/;
28
26
  /**
29
27
  * Decoder that only returns Ok for string inputs. Err otherwise.
30
28
  */
31
29
 
32
30
  var string = function string(blob) {
33
- return typeof blob === 'string' ? Result.ok(blob) : Result.err((0, _annotate.annotate)(blob, 'Must be string'));
31
+ return typeof blob === 'string' ? (0, _result.ok)(blob) : (0, _result.err)((0, _annotate.annotate)(blob, 'Must be string'));
34
32
  };
35
33
  /**
36
34
  * Decoder that only returns Ok for non-empty string inputs. Err otherwise.
@@ -48,9 +46,9 @@ var nonEmptyString = regex(/\S/, 'Must be non-empty string');
48
46
  exports.nonEmptyString = nonEmptyString;
49
47
 
50
48
  function regex(regex, msg) {
51
- return (0, _composition.compose)(string, (0, _composition.predicate)(function (s) {
49
+ return (0, _composition.predicate)(string, function (s) {
52
50
  return regex.test(s);
53
- }, msg));
51
+ }, msg);
54
52
  }
55
53
  /**
56
54
  * Decoder that only returns Ok for string inputs that match the almost perfect
@@ -59,40 +57,12 @@ function regex(regex, msg) {
59
57
 
60
58
 
61
59
  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');
62
- /**
63
- * Decoder that only returns Ok for string inputs that match URLs of the
64
- * expected scheme. Defaults to only accept HTTPS URLs. Err otherwise.
65
- *
66
- * Variants that can be used:
67
- *
68
- * - url() accepts only https:// URLs
69
- * - url([]) accepts any URL scheme
70
- * - url(['http']) accepts only HTTP
71
- * - url(['https', 'git+ssh']) accepts both https:// and git+ssh:// URLs
72
- */
73
-
74
60
  exports.email = email;
75
-
76
- var url = function url(schemes) {
77
- if (schemes === void 0) {
78
- schemes = DEFAULT_SCHEMES;
79
- }
80
-
81
- return (0, _composition.compose)(string, function (value) {
82
- var matches = value.match(url_re);
83
-
84
- if (!matches) {
85
- return Result.err((0, _annotate.annotate)(value, 'Must be URL'));
86
- } else {
87
- var scheme = matches[1];
88
-
89
- if (schemes.length === 0 || schemes.includes(scheme.toLowerCase())) {
90
- return Result.ok(value);
91
- } else {
92
- return Result.err((0, _annotate.annotate)(value, "URL scheme must be any of: " + schemes.join(', ')));
93
- }
94
- }
95
- });
96
- };
97
-
98
- exports.url = url;
61
+ var url = (0, _either.either)((0, _composition.map)(regex(url_re, 'Must be URL'), function (value) {
62
+ return new URL(value);
63
+ }), (0, _instanceOf.instanceOf)(URL));
64
+ exports.url = url;
65
+ var httpsUrl = (0, _composition.predicate)(url, function (value) {
66
+ return value.protocol === 'https:';
67
+ }, 'Must be an HTTPS URL');
68
+ exports.httpsUrl = httpsUrl;
@@ -1,8 +1,10 @@
1
1
  // @flow strict
2
2
 
3
- import * as Result from '../result';
4
3
  import { annotate } from '../annotate';
5
- import { compose, predicate } from './composition';
4
+ import { either } from './either';
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,16 +17,11 @@ 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
  */
24
23
  export const string: Decoder<string> = (blob: mixed) => {
25
- return typeof blob === 'string'
26
- ? Result.ok(blob)
27
- : Result.err(annotate(blob, 'Must be string'));
24
+ return typeof blob === 'string' ? ok(blob) : err(annotate(blob, 'Must be string'));
28
25
  };
29
26
 
30
27
  /**
@@ -38,10 +35,7 @@ export const nonEmptyString: Decoder<string> = regex(/\S/, 'Must be non-empty st
38
35
  * before testing the regex.
39
36
  */
40
37
  export function regex(regex: RegExp, msg: string): Decoder<string> {
41
- return compose(
42
- string,
43
- predicate((s) => regex.test(s), msg),
44
- );
38
+ return predicate(string, (s) => regex.test(s), msg);
45
39
  }
46
40
 
47
41
  /**
@@ -53,30 +47,13 @@ export const email: Decoder<string> = regex(
53
47
  'Must be email',
54
48
  );
55
49
 
56
- /**
57
- * Decoder that only returns Ok for string inputs that match URLs of the
58
- * expected scheme. Defaults to only accept HTTPS URLs. Err otherwise.
59
- *
60
- * Variants that can be used:
61
- *
62
- * - url() accepts only https:// URLs
63
- * - url([]) accepts any URL scheme
64
- * - url(['http']) accepts only HTTP
65
- * - url(['https', 'git+ssh']) accepts both https:// and git+ssh:// URLs
66
- */
67
- export const url = (schemes: $ReadOnlyArray<string> = DEFAULT_SCHEMES): Decoder<string> =>
68
- compose(string, (value: string) => {
69
- const matches = value.match(url_re);
70
- if (!matches) {
71
- return Result.err(annotate(value, 'Must be URL'));
72
- } else {
73
- const scheme = matches[1];
74
- if (schemes.length === 0 || schemes.includes(scheme.toLowerCase())) {
75
- return Result.ok(value);
76
- } else {
77
- return Result.err(
78
- annotate(value, `URL scheme must be any of: ${schemes.join(', ')}`),
79
- );
80
- }
81
- }
82
- });
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
+ );
@@ -0,0 +1,49 @@
1
+ import { annotate } from '../annotate.mjs';
2
+ import { either } from './either.mjs';
3
+ import { err, ok } from '../result.mjs';
4
+ import { instanceOf } from './instanceOf.mjs';
5
+ import { map, predicate } from './composition.mjs';
6
+
7
+ /** Match groups in this regex:
8
+ * \1 - the scheme
9
+ * \2 - the username/password (optional)
10
+ * \3 - the host
11
+ * \4 - the port (optional)
12
+ * \5 - the path (optional)
13
+ */
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
+ /**
16
+ * Decoder that only returns Ok for string inputs. Err otherwise.
17
+ */
18
+
19
+ export var string = function string(blob) {
20
+ return typeof blob === 'string' ? ok(blob) : err(annotate(blob, 'Must be string'));
21
+ };
22
+ /**
23
+ * Decoder that only returns Ok for non-empty string inputs. Err otherwise.
24
+ */
25
+
26
+ export var nonEmptyString = regex(/\S/, 'Must be non-empty string');
27
+ /**
28
+ * Decoder that only returns Ok for string inputs that match the regular
29
+ * expression. Err otherwise. Will always validate that the input is a string
30
+ * before testing the regex.
31
+ */
32
+
33
+ export function regex(regex, msg) {
34
+ return predicate(string, function (s) {
35
+ return regex.test(s);
36
+ }, msg);
37
+ }
38
+ /**
39
+ * Decoder that only returns Ok for string inputs that match the almost perfect
40
+ * email regex, taken from http://emailregex.com. Err otherwise.
41
+ */
42
+
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
+ 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');
@@ -0,0 +1,30 @@
1
+ import { Decoder } from '../_types';
2
+
3
+ export function tuple1<T1>(d1: Decoder<T1>): Decoder<[T1]>;
4
+ export function tuple2<T1, T2>(d1: Decoder<T1>, d2: Decoder<T2>): Decoder<[T1, T2]>;
5
+ export function tuple3<T1, T2, T3>(
6
+ d1: Decoder<T1>,
7
+ d2: Decoder<T2>,
8
+ d3: Decoder<T3>,
9
+ ): Decoder<[T1, T2, T3]>;
10
+ export function tuple4<T1, T2, T3, T4>(
11
+ d1: Decoder<T1>,
12
+ d2: Decoder<T2>,
13
+ d3: Decoder<T3>,
14
+ d4: Decoder<T4>,
15
+ ): Decoder<[T1, T2, T3, T4]>;
16
+ export function tuple5<T1, T2, T3, T4, T5>(
17
+ d1: Decoder<T1>,
18
+ d2: Decoder<T2>,
19
+ d3: Decoder<T3>,
20
+ d4: Decoder<T4>,
21
+ d5: Decoder<T5>,
22
+ ): Decoder<[T1, T2, T3, T4, T5]>;
23
+ export function tuple6<T1, T2, T3, T4, T5, T6>(
24
+ d1: Decoder<T1>,
25
+ d2: Decoder<T2>,
26
+ d3: Decoder<T3>,
27
+ d4: Decoder<T4>,
28
+ d5: Decoder<T5>,
29
+ d6: Decoder<T6>,
30
+ ): Decoder<[T1, T2, T3, T4, T5, T6]>;
package/core/tuple.js CHANGED
@@ -16,10 +16,14 @@ var _result = require("../result");
16
16
 
17
17
  var _array = require("./array");
18
18
 
19
+ function okOrErr(result) {
20
+ return result.type === 'ok' ? result.value : result.error;
21
+ }
22
+
19
23
  var ntuple = function ntuple(n) {
20
- return (0, _composition.compose)(_array.poja, (0, _composition.predicate)(function (arr) {
24
+ return (0, _composition.predicate)(_array.poja, function (arr) {
21
25
  return arr.length === n;
22
- }, "Must be a " + n + "-tuple"));
26
+ }, "Must be a " + n + "-tuple");
23
27
  };
24
28
  /**
25
29
  * Builds a Decoder that returns Ok for 1-tuple of [T], given a Decoder for T.
@@ -37,7 +41,7 @@ function tuple1(decoder1) {
37
41
  } catch (e) {
38
42
  // If a decoder error has happened while unwrapping all the
39
43
  // results, try to construct a good error message
40
- return (0, _result.err)((0, _annotate.annotate)([(0, _result.okOrErrValue)(result1)]));
44
+ return (0, _result.err)((0, _annotate.annotate)([okOrErr(result1)]));
41
45
  }
42
46
  });
43
47
  }
@@ -59,7 +63,7 @@ function tuple2(decoder1, decoder2) {
59
63
  } catch (e) {
60
64
  // If a decoder error has happened while unwrapping all the
61
65
  // results, try to construct a good error message
62
- return (0, _result.err)((0, _annotate.annotate)([(0, _result.okOrErrValue)(result1), (0, _result.okOrErrValue)(result2)]));
66
+ return (0, _result.err)((0, _annotate.annotate)([okOrErr(result1), okOrErr(result2)]));
63
67
  }
64
68
  });
65
69
  }
@@ -83,7 +87,7 @@ function tuple3(decoder1, decoder2, decoder3) {
83
87
  } catch (e) {
84
88
  // If a decoder error has happened while unwrapping all the
85
89
  // results, try to construct a good error message
86
- return (0, _result.err)((0, _annotate.annotate)([(0, _result.okOrErrValue)(result1), (0, _result.okOrErrValue)(result2), (0, _result.okOrErrValue)(result3)]));
90
+ return (0, _result.err)((0, _annotate.annotate)([okOrErr(result1), okOrErr(result2), okOrErr(result3)]));
87
91
  }
88
92
  });
89
93
  }
@@ -109,7 +113,7 @@ function tuple4(decoder1, decoder2, decoder3, decoder4) {
109
113
  } catch (e) {
110
114
  // If a decoder error has happened while unwrapping all the
111
115
  // results, try to construct a good error message
112
- return (0, _result.err)((0, _annotate.annotate)([(0, _result.okOrErrValue)(result1), (0, _result.okOrErrValue)(result2), (0, _result.okOrErrValue)(result3), (0, _result.okOrErrValue)(result4)]));
116
+ return (0, _result.err)((0, _annotate.annotate)([okOrErr(result1), okOrErr(result2), okOrErr(result3), okOrErr(result4)]));
113
117
  }
114
118
  });
115
119
  }
@@ -137,7 +141,7 @@ function tuple5(decoder1, decoder2, decoder3, decoder4, decoder5) {
137
141
  } catch (e) {
138
142
  // If a decoder error has happened while unwrapping all the
139
143
  // results, try to construct a good error message
140
- return (0, _result.err)((0, _annotate.annotate)([(0, _result.okOrErrValue)(result1), (0, _result.okOrErrValue)(result2), (0, _result.okOrErrValue)(result3), (0, _result.okOrErrValue)(result4), (0, _result.okOrErrValue)(result5)]));
144
+ return (0, _result.err)((0, _annotate.annotate)([okOrErr(result1), okOrErr(result2), okOrErr(result3), okOrErr(result4), okOrErr(result5)]));
141
145
  }
142
146
  });
143
147
  }
@@ -167,7 +171,7 @@ function tuple6(decoder1, decoder2, decoder3, decoder4, decoder5, decoder6) {
167
171
  } catch (e) {
168
172
  // If a decoder error has happened while unwrapping all the
169
173
  // results, try to construct a good error message
170
- return (0, _result.err)((0, _annotate.annotate)([(0, _result.okOrErrValue)(result1), (0, _result.okOrErrValue)(result2), (0, _result.okOrErrValue)(result3), (0, _result.okOrErrValue)(result4), (0, _result.okOrErrValue)(result5), (0, _result.okOrErrValue)(result6)]));
174
+ return (0, _result.err)((0, _annotate.annotate)([okOrErr(result1), okOrErr(result2), okOrErr(result3), okOrErr(result4), okOrErr(result5), okOrErr(result6)]));
171
175
  }
172
176
  });
173
177
  }