decoders 2.0.0-beta9 → 2.0.0

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 (136) hide show
  1. package/CHANGELOG.md +56 -29
  2. package/Decoder.d.ts +94 -0
  3. package/Decoder.js +222 -0
  4. package/Decoder.js.flow +286 -0
  5. package/Decoder.mjs +215 -0
  6. package/README.md +122 -1507
  7. package/_utils.d.ts +0 -1
  8. package/_utils.js +11 -17
  9. package/_utils.js.flow +13 -17
  10. package/_utils.mjs +10 -14
  11. package/format.d.ts +4 -2
  12. package/format.js +1 -1
  13. package/format.js.flow +3 -1
  14. package/format.mjs +1 -1
  15. package/index.d.ts +29 -31
  16. package/index.js +62 -84
  17. package/index.js.flow +30 -48
  18. package/index.mjs +11 -36
  19. package/{core → lib}/_helpers.d.ts +0 -0
  20. package/lib/arrays.d.ts +59 -0
  21. package/lib/arrays.js +139 -0
  22. package/lib/arrays.js.flow +138 -0
  23. package/lib/arrays.mjs +124 -0
  24. package/lib/basics.d.ts +93 -0
  25. package/lib/basics.js +144 -0
  26. package/lib/basics.js.flow +124 -0
  27. package/lib/basics.mjs +120 -0
  28. package/lib/booleans.d.ts +16 -0
  29. package/lib/booleans.js +35 -0
  30. package/lib/booleans.js.flow +22 -0
  31. package/lib/booleans.mjs +25 -0
  32. package/lib/dates.d.ts +15 -0
  33. package/lib/dates.js +44 -0
  34. package/lib/dates.js.flow +40 -0
  35. package/lib/dates.mjs +34 -0
  36. package/lib/json.d.ts +35 -0
  37. package/lib/json.js +55 -0
  38. package/lib/json.js.flow +50 -0
  39. package/lib/json.mjs +40 -0
  40. package/lib/numbers.d.ts +31 -0
  41. package/lib/numbers.js +51 -0
  42. package/lib/numbers.js.flow +48 -0
  43. package/lib/numbers.mjs +41 -0
  44. package/lib/objects.d.ts +75 -0
  45. package/{core/object.js → lib/objects.js} +78 -85
  46. package/{core/object.js.flow → lib/objects.js.flow} +89 -102
  47. package/{core/object.mjs → lib/objects.mjs} +77 -82
  48. package/lib/strings.d.ts +56 -0
  49. package/lib/strings.js +101 -0
  50. package/lib/strings.js.flow +90 -0
  51. package/lib/strings.mjs +82 -0
  52. package/lib/unions.d.ts +55 -0
  53. package/lib/unions.js +160 -0
  54. package/{core/either.js.flow → lib/unions.js.flow} +67 -17
  55. package/lib/unions.mjs +146 -0
  56. package/lib/utilities.d.ts +34 -0
  57. package/lib/utilities.js +75 -0
  58. package/lib/utilities.js.flow +65 -0
  59. package/lib/utilities.mjs +60 -0
  60. package/package.json +64 -17
  61. package/result.d.ts +0 -23
  62. package/result.js +0 -68
  63. package/result.js.flow +0 -72
  64. package/result.mjs +0 -54
  65. package/_guard.d.ts +0 -7
  66. package/_guard.js +0 -22
  67. package/_guard.js.flow +0 -20
  68. package/_guard.mjs +0 -15
  69. package/_types.d.ts +0 -13
  70. package/_types.js +0 -1
  71. package/_types.js.flow +0 -20
  72. package/_types.mjs +0 -0
  73. package/core/array.d.ts +0 -8
  74. package/core/array.js +0 -115
  75. package/core/array.js.flow +0 -107
  76. package/core/array.mjs +0 -100
  77. package/core/boolean.d.ts +0 -5
  78. package/core/boolean.js +0 -40
  79. package/core/boolean.js.flow +0 -27
  80. package/core/boolean.mjs +0 -28
  81. package/core/composition.d.ts +0 -18
  82. package/core/composition.js +0 -82
  83. package/core/composition.js.flow +0 -74
  84. package/core/composition.mjs +0 -70
  85. package/core/constants.d.ts +0 -11
  86. package/core/constants.js +0 -65
  87. package/core/constants.js.flow +0 -44
  88. package/core/constants.mjs +0 -46
  89. package/core/date.d.ts +0 -4
  90. package/core/date.js +0 -42
  91. package/core/date.js.flow +0 -38
  92. package/core/date.mjs +0 -28
  93. package/core/describe.d.ts +0 -3
  94. package/core/describe.js +0 -22
  95. package/core/describe.js.flow +0 -17
  96. package/core/describe.mjs +0 -16
  97. package/core/dispatch.d.ts +0 -8
  98. package/core/dispatch.js +0 -60
  99. package/core/dispatch.js.flow +0 -59
  100. package/core/dispatch.mjs +0 -52
  101. package/core/either.d.ts +0 -66
  102. package/core/either.js +0 -101
  103. package/core/either.mjs +0 -90
  104. package/core/fail.d.ts +0 -3
  105. package/core/fail.js +0 -17
  106. package/core/fail.js.flow +0 -12
  107. package/core/fail.mjs +0 -11
  108. package/core/instanceOf.d.ts +0 -3
  109. package/core/instanceOf.js +0 -15
  110. package/core/instanceOf.js.flow +0 -20
  111. package/core/instanceOf.mjs +0 -8
  112. package/core/json.d.ts +0 -11
  113. package/core/json.js +0 -31
  114. package/core/json.js.flow +0 -28
  115. package/core/json.mjs +0 -15
  116. package/core/lazy.d.ts +0 -3
  117. package/core/lazy.js +0 -16
  118. package/core/lazy.js.flow +0 -15
  119. package/core/lazy.mjs +0 -11
  120. package/core/number.d.ts +0 -6
  121. package/core/number.js +0 -36
  122. package/core/number.js.flow +0 -40
  123. package/core/number.mjs +0 -25
  124. package/core/object.d.ts +0 -38
  125. package/core/optional.d.ts +0 -5
  126. package/core/optional.js +0 -50
  127. package/core/optional.js.flow +0 -41
  128. package/core/optional.mjs +0 -38
  129. package/core/string.d.ts +0 -13
  130. package/core/string.js +0 -80
  131. package/core/string.js.flow +0 -72
  132. package/core/string.mjs +0 -58
  133. package/core/tuple.d.ts +0 -30
  134. package/core/tuple.js +0 -54
  135. package/core/tuple.js.flow +0 -51
  136. package/core/tuple.mjs +0 -45
@@ -1,40 +0,0 @@
1
- // @flow strict
2
-
3
- import { annotate } from '../annotate';
4
- import { err, ok } from '../result';
5
- import { predicate } from './composition';
6
- import type { Decoder } from '../_types';
7
-
8
- const anyNumber: Decoder<number> = (blob: mixed) => {
9
- return typeof blob === 'number' && !Number.isNaN(blob)
10
- ? ok(blob)
11
- : err(annotate(blob, 'Must be number'));
12
- };
13
-
14
- const isInteger = (n: number) => Number.isInteger(n);
15
- const isFinite = (n: number) => Number.isFinite(n);
16
-
17
- export const number: Decoder<number> = predicate(
18
- anyNumber,
19
- isFinite,
20
- 'Number must be finite',
21
- );
22
-
23
- export const positiveNumber: Decoder<number> = predicate(
24
- number,
25
- (n) => n >= 0,
26
- 'Number must be positive',
27
- );
28
-
29
- // Integers
30
- export const integer: Decoder<number> = predicate(
31
- number,
32
- isInteger,
33
- 'Number must be an integer',
34
- );
35
-
36
- export const positiveInteger: Decoder<number> = predicate(
37
- integer,
38
- (n) => n >= 0,
39
- 'Number must be positive',
40
- );
package/core/number.mjs DELETED
@@ -1,25 +0,0 @@
1
- import { annotate } from '../annotate.mjs';
2
- import { err, ok } from '../result.mjs';
3
- import { predicate } from './composition.mjs';
4
-
5
- var anyNumber = function anyNumber(blob) {
6
- return typeof blob === 'number' && !Number.isNaN(blob) ? ok(blob) : err(annotate(blob, 'Must be number'));
7
- };
8
-
9
- var isInteger = function isInteger(n) {
10
- return Number.isInteger(n);
11
- };
12
-
13
- var isFinite = function isFinite(n) {
14
- return Number.isFinite(n);
15
- };
16
-
17
- export var number = predicate(anyNumber, isFinite, 'Number must be finite');
18
- export var positiveNumber = predicate(number, function (n) {
19
- return n >= 0;
20
- }, 'Number must be positive'); // Integers
21
-
22
- export var integer = predicate(number, isInteger, 'Number must be an integer');
23
- export var positiveInteger = predicate(integer, function (n) {
24
- return n >= 0;
25
- }, 'Number must be positive');
package/core/object.d.ts DELETED
@@ -1,38 +0,0 @@
1
- /// <reference lib="es6" />
2
-
3
- import { Decoder, DecoderType } from '../_types';
4
- import { AllowImplicit } from './_helpers';
5
-
6
- export type ObjectDecoderType<T> = AllowImplicit<{
7
- [key in keyof T]: DecoderType<T[key]>;
8
- }>;
9
-
10
- export const pojo: Decoder<{ [key: string]: unknown }>;
11
-
12
- export function object<O extends { [key: string]: Decoder<any> }>(
13
- mapping: O,
14
- ): Decoder<{ [K in keyof ObjectDecoderType<O>]: ObjectDecoderType<O>[K] }>;
15
- // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
16
- // This is basically just equivalent to:
17
- // ObjectDecoderType<O>
18
- //
19
- // But by "resolving" this with a mapped type, we remove the helper
20
- // type names from the inferred type here, making this much easier to
21
- // work with while developing.
22
-
23
- export function exact<O extends { [key: string]: Decoder<any> }>(
24
- mapping: O,
25
- ): Decoder<{ [K in keyof ObjectDecoderType<O>]: ObjectDecoderType<O>[K] }>;
26
- // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
27
- // Ditto (see above)
28
-
29
- export function inexact<O extends { [key: string]: Decoder<any> }>(
30
- mapping: O,
31
- ): Decoder<
32
- { [K in keyof ObjectDecoderType<O>]: ObjectDecoderType<O>[K] } & {
33
- [extra: string]: unknown;
34
- }
35
- >;
36
-
37
- export function mapping<T>(decoder: Decoder<T>): Decoder<Map<string, T>>;
38
- export function dict<T>(decoder: Decoder<T>): Decoder<{ [key: string]: T }>;
@@ -1,5 +0,0 @@
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 DELETED
@@ -1,50 +0,0 @@
1
- "use strict";
2
-
3
- exports.__esModule = true;
4
- exports.maybe = maybe;
5
- exports.nullable = nullable;
6
- exports.optional = optional;
7
-
8
- var _annotate = require("../annotate");
9
-
10
- var _either = require("./either");
11
-
12
- var _result = require("../result");
13
-
14
- var _constants = require("./constants");
15
-
16
- /**
17
- * Builds a Decoder that returns Ok for either `undefined` or `T` values,
18
- * given a Decoder for `T`. Err otherwise.
19
- */
20
- function optional(decoder) {
21
- return (0, _either.either)(_constants.undefined_, decoder);
22
- }
23
- /**
24
- * Builds a Decoder that returns Ok for either `null` or `T` values,
25
- * given a Decoder for `T`. Err otherwise.
26
- */
27
-
28
-
29
- function nullable(decoder) {
30
- return (0, _either.either)(_constants.null_, decoder);
31
- }
32
- /**
33
- * Decoder that only returns Ok for `null` or `undefined` inputs.
34
- * This is effectively equivalent to either(null_, undefined_), but combines
35
- * their error message output into a single line for convenience.
36
- */
37
-
38
-
39
- var undefined_or_null = function undefined_or_null(blob) {
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'));
42
- };
43
- /**
44
- * Decoder that only returns Ok for `null` or `undefined` inputs.
45
- */
46
-
47
-
48
- function maybe(decoder) {
49
- return (0, _either.either)(undefined_or_null, decoder);
50
- }
@@ -1,41 +0,0 @@
1
- // @flow strict
2
-
3
- import { annotate } from '../annotate';
4
- import { either } from './either';
5
- import { err, ok } from '../result';
6
- import { null_, undefined_ } from './constants';
7
- import type { Decoder } from '../_types';
8
-
9
- /**
10
- * Builds a Decoder that returns Ok for either `undefined` or `T` values,
11
- * given a Decoder for `T`. Err otherwise.
12
- */
13
- export function optional<T>(decoder: Decoder<T>): Decoder<void | T> {
14
- return either(undefined_, decoder);
15
- }
16
-
17
- /**
18
- * Builds a Decoder that returns Ok for either `null` or `T` values,
19
- * given a Decoder for `T`. Err otherwise.
20
- */
21
- export function nullable<T>(decoder: Decoder<T>): Decoder<null | T> {
22
- return either(null_, decoder);
23
- }
24
-
25
- /**
26
- * Decoder that only returns Ok for `null` or `undefined` inputs.
27
- * This is effectively equivalent to either(null_, undefined_), but combines
28
- * their error message output into a single line for convenience.
29
- */
30
- const undefined_or_null: Decoder<null | void> = (blob: mixed) =>
31
- blob === undefined || blob === null
32
- ? ok(blob)
33
- : // Combine error message into a single line
34
- err(annotate(blob, 'Must be undefined or null'));
35
-
36
- /**
37
- * Decoder that only returns Ok for `null` or `undefined` inputs.
38
- */
39
- export function maybe<T>(decoder: Decoder<T>): Decoder<?T> {
40
- return either(undefined_or_null, decoder);
41
- }
package/core/optional.mjs DELETED
@@ -1,38 +0,0 @@
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
-
6
- /**
7
- * Builds a Decoder that returns Ok for either `undefined` or `T` values,
8
- * given a Decoder for `T`. Err otherwise.
9
- */
10
- export function optional(decoder) {
11
- return either(undefined_, decoder);
12
- }
13
- /**
14
- * Builds a Decoder that returns Ok for either `null` or `T` values,
15
- * given a Decoder for `T`. Err otherwise.
16
- */
17
-
18
- export function nullable(decoder) {
19
- return either(null_, decoder);
20
- }
21
- /**
22
- * Decoder that only returns Ok for `null` or `undefined` inputs.
23
- * This is effectively equivalent to either(null_, undefined_), but combines
24
- * their error message output into a single line for convenience.
25
- */
26
-
27
- var undefined_or_null = function undefined_or_null(blob) {
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
- };
31
- /**
32
- * Decoder that only returns Ok for `null` or `undefined` inputs.
33
- */
34
-
35
-
36
- export function maybe(decoder) {
37
- return either(undefined_or_null, decoder);
38
- }
package/core/string.d.ts DELETED
@@ -1,13 +0,0 @@
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>;
11
- export const uuid: Decoder<string>;
12
- export const uuidv1: Decoder<string>;
13
- export const uuidv4: Decoder<string>;
package/core/string.js DELETED
@@ -1,80 +0,0 @@
1
- "use strict";
2
-
3
- exports.__esModule = true;
4
- exports.nonEmptyString = exports.httpsUrl = exports.email = void 0;
5
- exports.regex = regex;
6
- exports.uuidv4 = exports.uuidv1 = exports.uuid = exports.url = exports.string = void 0;
7
-
8
- var _annotate = require("../annotate");
9
-
10
- var _either = require("./either");
11
-
12
- var _result = require("../result");
13
-
14
- var _instanceOf = require("./instanceOf");
15
-
16
- var _composition = require("./composition");
17
-
18
- /** Match groups in this regex:
19
- * \1 - the scheme
20
- * \2 - the username/password (optional)
21
- * \3 - the host
22
- * \4 - the port (optional)
23
- * \5 - the path (optional)
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]*)?)?$/;
26
- /**
27
- * Decoder that only returns Ok for string inputs. Err otherwise.
28
- */
29
-
30
- var string = function string(blob) {
31
- return typeof blob === 'string' ? (0, _result.ok)(blob) : (0, _result.err)((0, _annotate.annotate)(blob, 'Must be string'));
32
- };
33
- /**
34
- * Decoder that only returns Ok for non-empty string inputs. Err otherwise.
35
- */
36
-
37
-
38
- exports.string = string;
39
- var nonEmptyString = regex(/\S/, 'Must be non-empty string');
40
- /**
41
- * Decoder that only returns Ok for string inputs that match the regular
42
- * expression. Err otherwise. Will always validate that the input is a string
43
- * before testing the regex.
44
- */
45
-
46
- exports.nonEmptyString = nonEmptyString;
47
-
48
- function regex(regex, msg) {
49
- return (0, _composition.predicate)(string, function (s) {
50
- return regex.test(s);
51
- }, msg);
52
- }
53
- /**
54
- * Decoder that only returns Ok for string inputs that match the almost perfect
55
- * email regex, taken from http://emailregex.com. Err otherwise.
56
- */
57
-
58
-
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');
60
- exports.email = email;
61
- var url = (0, _either.either)((0, _composition.transform)(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;
69
- var uuid = regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, 'Must be uuid');
70
- exports.uuid = uuid;
71
- var uuidv1 = // https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address)
72
- (0, _composition.predicate)(uuid, function (value) {
73
- return value[14] === '1';
74
- }, 'Must be uuidv1');
75
- exports.uuidv1 = uuidv1;
76
- var uuidv4 = // https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)
77
- (0, _composition.predicate)(uuid, function (value) {
78
- return value[14] === '4';
79
- }, 'Must be uuidv4');
80
- exports.uuidv4 = uuidv4;
@@ -1,72 +0,0 @@
1
- // @flow strict
2
-
3
- import { annotate } from '../annotate';
4
- import { either } from './either';
5
- import { err, ok } from '../result';
6
- import { instanceOf } from './instanceOf';
7
- import { predicate, transform } from './composition';
8
- import type { Decoder } from '../_types';
9
-
10
- /** Match groups in this regex:
11
- * \1 - the scheme
12
- * \2 - the username/password (optional)
13
- * \3 - the host
14
- * \4 - the port (optional)
15
- * \5 - the path (optional)
16
- */
17
- const url_re =
18
- /^([A-Za-z]{3,9}(?:[+][A-Za-z]{3,9})?):\/\/(?:([-;:&=+$,\w]+)@)?(?:([A-Za-z0-9.-]+)(?::([0-9]{2,5}))?)(\/(?:[-+~%/.,\w]*)?(?:\?[-+=&;%@.,\w]*)?(?:#[.,!/\w]*)?)?$/;
19
-
20
- /**
21
- * Decoder that only returns Ok for string inputs. Err otherwise.
22
- */
23
- export const string: Decoder<string> = (blob: mixed) => {
24
- return typeof blob === 'string' ? ok(blob) : err(annotate(blob, 'Must be string'));
25
- };
26
-
27
- /**
28
- * Decoder that only returns Ok for non-empty string inputs. Err otherwise.
29
- */
30
- export const nonEmptyString: Decoder<string> = regex(/\S/, 'Must be non-empty string');
31
-
32
- /**
33
- * Decoder that only returns Ok for string inputs that match the regular
34
- * expression. Err otherwise. Will always validate that the input is a string
35
- * before testing the regex.
36
- */
37
- export function regex(regex: RegExp, msg: string): Decoder<string> {
38
- return predicate(string, (s) => regex.test(s), msg);
39
- }
40
-
41
- /**
42
- * Decoder that only returns Ok for string inputs that match the almost perfect
43
- * email regex, taken from http://emailregex.com. Err otherwise.
44
- */
45
- export const email: Decoder<string> = regex(
46
- /^(([^<>()[\]\\.,;:\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,}))$/,
47
- 'Must be email',
48
- );
49
-
50
- export const url: Decoder<URL> = either(
51
- transform(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
- );
60
-
61
- export const uuid: Decoder<string> = regex(
62
- /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,
63
- 'Must be uuid',
64
- );
65
-
66
- export const uuidv1: Decoder<string> =
67
- // https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address)
68
- predicate(uuid, (value) => value[14] === '1', 'Must be uuidv1');
69
-
70
- export const uuidv4: Decoder<string> =
71
- // https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)
72
- predicate(uuid, (value) => value[14] === '4', 'Must be uuidv4');
package/core/string.mjs DELETED
@@ -1,58 +0,0 @@
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 { predicate, transform } 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(transform(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');
50
- export var uuid = regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, 'Must be uuid');
51
- export var uuidv1 = // https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address)
52
- predicate(uuid, function (value) {
53
- return value[14] === '1';
54
- }, 'Must be uuidv1');
55
- export var uuidv4 = // https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)
56
- predicate(uuid, function (value) {
57
- return value[14] === '4';
58
- }, 'Must be uuidv4');
package/core/tuple.d.ts DELETED
@@ -1,30 +0,0 @@
1
- import { Decoder } from '../_types';
2
-
3
- export function tuple<A>(a: Decoder<A>): Decoder<[A]>;
4
- export function tuple<A, B>(a: Decoder<A>, b: Decoder<B>): Decoder<[A, B]>;
5
- export function tuple<A, B, C>(
6
- a: Decoder<A>,
7
- b: Decoder<B>,
8
- c: Decoder<C>,
9
- ): Decoder<[A, B, C]>;
10
- export function tuple<A, B, C, D>(
11
- a: Decoder<A>,
12
- b: Decoder<B>,
13
- c: Decoder<C>,
14
- d: Decoder<D>,
15
- ): Decoder<[A, B, C, D]>;
16
- export function tuple<A, B, C, D, E>(
17
- a: Decoder<A>,
18
- b: Decoder<B>,
19
- c: Decoder<C>,
20
- d: Decoder<D>,
21
- e: Decoder<E>,
22
- ): Decoder<[A, B, C, D, E]>;
23
- export function tuple<A, B, C, D, E, F>(
24
- a: Decoder<A>,
25
- b: Decoder<B>,
26
- c: Decoder<C>,
27
- d: Decoder<D>,
28
- e: Decoder<E>,
29
- f: Decoder<F>,
30
- ): Decoder<[A, B, C, D, E, F]>;
package/core/tuple.js DELETED
@@ -1,54 +0,0 @@
1
- "use strict";
2
-
3
- exports.__esModule = true;
4
- exports.tuple = void 0;
5
-
6
- var _annotate = require("../annotate");
7
-
8
- var _composition = require("./composition");
9
-
10
- var _result = require("../result");
11
-
12
- var _array = require("./array");
13
-
14
- var ntuple = function ntuple(n) {
15
- return (0, _composition.predicate)(_array.poja, function (arr) {
16
- return arr.length === n;
17
- }, "Must be a " + n + "-tuple");
18
- }; // prettier-ignore
19
-
20
-
21
- /**
22
- * Accepts n-tuples [A, B, C, ...] matching the given decoders A, B, C, ...
23
- */
24
- function _tuple() {
25
- for (var _len = arguments.length, decoders = new Array(_len), _key = 0; _key < _len; _key++) {
26
- decoders[_key] = arguments[_key];
27
- }
28
-
29
- return (0, _composition.compose)(ntuple(decoders.length), function (blobs) {
30
- var allOk = true;
31
- var rvs = decoders.map(function (decoder, i) {
32
- var blob = blobs[i];
33
- var result = decoder(blob);
34
-
35
- if (result.ok) {
36
- return result.value;
37
- } else {
38
- allOk = false;
39
- return result.error;
40
- }
41
- });
42
-
43
- if (allOk) {
44
- return (0, _result.ok)(rvs);
45
- } else {
46
- // If a decoder error has happened while unwrapping all the
47
- // results, try to construct a good error message
48
- return (0, _result.err)((0, _annotate.annotate)(rvs));
49
- }
50
- });
51
- }
52
-
53
- var tuple = _tuple;
54
- exports.tuple = tuple;
@@ -1,51 +0,0 @@
1
- // @flow strict
2
-
3
- import { annotate } from '../annotate';
4
- import { compose, predicate } from './composition';
5
- import { err, ok } from '../result';
6
- import { poja } from './array';
7
- import type { _Any } from '../_utils';
8
- import type { Decoder } from '../_types';
9
-
10
- const ntuple = (n: number) =>
11
- predicate(poja, (arr) => arr.length === n, `Must be a ${n}-tuple`);
12
-
13
- // prettier-ignore
14
- interface TupleFuncSignature {
15
- <A>(a: Decoder<A>): Decoder<[A]>;
16
- <A, B>(a: Decoder<A>, b: Decoder<B>): Decoder<[A, B]>;
17
- <A, B, C>(a: Decoder<A>, b: Decoder<B>, c: Decoder<C>): Decoder<[A, B, C]>;
18
- <A, B, C, D>(a: Decoder<A>, b: Decoder<B>, c: Decoder<C>, d: Decoder<D>): Decoder<[A, B, C, D]>;
19
- <A, B, C, D, E>(a: Decoder<A>, b: Decoder<B>, c: Decoder<C>, d: Decoder<D>, e: Decoder<E>): Decoder<[A, B, C, D, E]>;
20
- <A, B, C, D, E, F>(a: Decoder<A>, b: Decoder<B>, c: Decoder<C>, d: Decoder<D>, e: Decoder<E>, f: Decoder<F>): Decoder<[A, B, C, D, E, F]>;
21
- }
22
-
23
- /**
24
- * Accepts n-tuples [A, B, C, ...] matching the given decoders A, B, C, ...
25
- */
26
- function _tuple(...decoders: $ReadOnlyArray<Decoder<mixed>>): Decoder<mixed> {
27
- return compose(ntuple(decoders.length), (blobs: $ReadOnlyArray<mixed>) => {
28
- let allOk = true;
29
-
30
- const rvs = decoders.map((decoder, i) => {
31
- const blob = blobs[i];
32
- const result = decoder(blob);
33
- if (result.ok) {
34
- return result.value;
35
- } else {
36
- allOk = false;
37
- return result.error;
38
- }
39
- });
40
-
41
- if (allOk) {
42
- return ok(rvs);
43
- } else {
44
- // If a decoder error has happened while unwrapping all the
45
- // results, try to construct a good error message
46
- return err(annotate(rvs));
47
- }
48
- });
49
- }
50
-
51
- export const tuple: TupleFuncSignature = (_tuple: _Any);
package/core/tuple.mjs DELETED
@@ -1,45 +0,0 @@
1
- import { annotate } from '../annotate.mjs';
2
- import { compose, predicate } from './composition.mjs';
3
- import { err, ok } from '../result.mjs';
4
- import { poja } from './array.mjs';
5
-
6
- var ntuple = function ntuple(n) {
7
- return predicate(poja, function (arr) {
8
- return arr.length === n;
9
- }, "Must be a " + n + "-tuple");
10
- }; // prettier-ignore
11
-
12
-
13
- /**
14
- * Accepts n-tuples [A, B, C, ...] matching the given decoders A, B, C, ...
15
- */
16
- function _tuple() {
17
- for (var _len = arguments.length, decoders = new Array(_len), _key = 0; _key < _len; _key++) {
18
- decoders[_key] = arguments[_key];
19
- }
20
-
21
- return compose(ntuple(decoders.length), function (blobs) {
22
- var allOk = true;
23
- var rvs = decoders.map(function (decoder, i) {
24
- var blob = blobs[i];
25
- var result = decoder(blob);
26
-
27
- if (result.ok) {
28
- return result.value;
29
- } else {
30
- allOk = false;
31
- return result.error;
32
- }
33
- });
34
-
35
- if (allOk) {
36
- return ok(rvs);
37
- } else {
38
- // If a decoder error has happened while unwrapping all the
39
- // results, try to construct a good error message
40
- return err(annotate(rvs));
41
- }
42
- });
43
- }
44
-
45
- export var tuple = _tuple;