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
@@ -1,6 +1,6 @@
1
- import * as Result from '../result';
2
- import { annotate } from '../annotate';
3
- import { indent, summarize } from '../_utils';
1
+ import { annotate } from '../annotate.mjs';
2
+ import { err, ok, orElse } from '../result.mjs';
3
+ import { indent, summarize } from '../_utils.mjs';
4
4
 
5
5
  /**
6
6
  * Indents and adds a dash in front of this (potentially multiline) string.
@@ -42,12 +42,12 @@ function nest(errText) {
42
42
 
43
43
  export function either(d1, d2) {
44
44
  return function (blob) {
45
- return Result.orElse(d1(blob), function (err1) {
46
- return Result.orElse(d2(blob), function (err2) {
45
+ return orElse(d1(blob), function (err1) {
46
+ return orElse(d2(blob), function (err2) {
47
47
  var serr1 = summarize(err1).join('\n');
48
48
  var serr2 = summarize(err2).join('\n');
49
49
  var text = ['Either:', nest(serr1), nest(serr2)].join('\n');
50
- return Result.err(annotate(blob, text));
50
+ return err(annotate(blob, text));
51
51
  });
52
52
  });
53
53
  };
@@ -80,10 +80,10 @@ export function oneOf(constants) {
80
80
  });
81
81
 
82
82
  if (winner !== undefined) {
83
- return Result.ok(winner);
83
+ return ok(winner);
84
84
  }
85
85
 
86
- return Result.err(annotate(blob, "Must be one of " + constants.map(function (value) {
86
+ return err(annotate(blob, "Must be one of " + constants.map(function (value) {
87
87
  return JSON.stringify(value);
88
88
  }).join(', ')));
89
89
  };
package/core/fail.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import { Decoder } from '../_types';
2
+
3
+ export function fail(msg: string): Decoder<never>;
package/core/fail.js CHANGED
@@ -3,19 +3,15 @@
3
3
  exports.__esModule = true;
4
4
  exports.fail = fail;
5
5
 
6
- var Result = _interopRequireWildcard(require("../result"));
7
-
8
6
  var _annotate = require("../annotate");
9
7
 
10
- 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); }
11
-
12
- 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; }
8
+ var _result = require("../result");
13
9
 
14
10
  /**
15
11
  * Decoder that always fails with the given error message, no matter what the input.
16
12
  */
17
13
  function fail(msg) {
18
14
  return function (blob) {
19
- return Result.err((0, _annotate.annotate)(blob, msg));
15
+ return (0, _result.err)((0, _annotate.annotate)(blob, msg));
20
16
  };
21
17
  }
package/core/fail.js.flow CHANGED
@@ -1,12 +1,12 @@
1
1
  // @flow strict
2
2
 
3
- import * as Result from '../result';
4
3
  import { annotate } from '../annotate';
4
+ import { err } from '../result';
5
5
  import type { Decoder } from '../_types';
6
6
 
7
7
  /**
8
8
  * Decoder that always fails with the given error message, no matter what the input.
9
9
  */
10
10
  export function fail(msg: string): Decoder<empty> {
11
- return (blob: mixed) => Result.err(annotate(blob, msg));
11
+ return (blob: mixed) => err(annotate(blob, msg));
12
12
  }
@@ -1,11 +1,11 @@
1
- import * as Result from '../result';
2
- import { annotate } from '../annotate';
1
+ import { annotate } from '../annotate.mjs';
2
+ import { err } from '../result.mjs';
3
3
 
4
4
  /**
5
5
  * Decoder that always fails with the given error message, no matter what the input.
6
6
  */
7
7
  export function fail(msg) {
8
8
  return function (blob) {
9
- return Result.err(annotate(blob, msg));
9
+ return err(annotate(blob, msg));
10
10
  };
11
11
  }
@@ -0,0 +1,3 @@
1
+ import { Decoder } from '../_types';
2
+
3
+ export function instanceOf<T>(klass: new (...args: any) => T): Decoder<T>;
@@ -3,17 +3,13 @@
3
3
  exports.__esModule = true;
4
4
  exports.instanceOf = instanceOf;
5
5
 
6
- var Result = _interopRequireWildcard(require("../result"));
7
-
8
6
  var _annotate = require("../annotate");
9
7
 
10
- 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); }
11
-
12
- 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; }
8
+ var _result = require("../result");
13
9
 
14
10
  function instanceOf(klass) {
15
11
  return function (blob) {
16
- return blob instanceof klass ? Result.ok(blob) : Result.err((0, _annotate.annotate)(blob, "Must be " + // $FlowFixMe[incompatible-use] - klass.name is fine?
12
+ return blob instanceof klass ? (0, _result.ok)(blob) : (0, _result.err)((0, _annotate.annotate)(blob, "Must be " + // $FlowFixMe[incompatible-use] - klass.name is fine?
17
13
  klass.name + " instance"));
18
14
  };
19
15
  }
@@ -1,14 +1,14 @@
1
1
  // @flow strict
2
2
 
3
- import * as Result from '../result';
4
3
  import { annotate } from '../annotate';
4
+ import { err, ok } from '../result';
5
5
  import type { Decoder } from '../_types';
6
6
 
7
7
  export function instanceOf<T>(klass: Class<T>): Decoder<T> {
8
8
  return (blob: mixed) =>
9
9
  blob instanceof klass
10
- ? Result.ok(blob)
11
- : Result.err(
10
+ ? ok(blob)
11
+ : err(
12
12
  annotate(
13
13
  blob,
14
14
  `Must be ${
@@ -0,0 +1,8 @@
1
+ import { annotate } from '../annotate.mjs';
2
+ import { err, ok } from '../result.mjs';
3
+ export function instanceOf(klass) {
4
+ return function (blob) {
5
+ return blob instanceof klass ? ok(blob) : err(annotate(blob, "Must be " + // $FlowFixMe[incompatible-use] - klass.name is fine?
6
+ klass.name + " instance"));
7
+ };
8
+ }
package/core/json.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ import { Decoder } from '../_types';
2
+
3
+ export type JSONValue = null | string | number | boolean | JSONObject | JSONArray;
4
+ export interface JSONObject {
5
+ [key: string]: JSONValue;
6
+ }
7
+ export type JSONArray = JSONValue[];
8
+
9
+ export const json: Decoder<JSONValue>;
10
+ export const jsonArray: Decoder<JSONArray>;
11
+ export const jsonObject: Decoder<JSONObject>;
package/core/json.mjs ADDED
@@ -0,0 +1,15 @@
1
+ import { array } from './array.mjs';
2
+ import { boolean as _boolean } from './boolean.mjs';
3
+ import { dict } from './mapping.mjs';
4
+ import { either6 } from './either.mjs';
5
+ import { lazy } from './lazy.mjs';
6
+ import { null_ } from './constants.mjs';
7
+ import { number } from './number.mjs';
8
+ import { string } from './string.mjs';
9
+ export var jsonObject = lazy(function () {
10
+ return dict(json);
11
+ });
12
+ export var jsonArray = lazy(function () {
13
+ return array(json);
14
+ });
15
+ export var json = either6(null_, string, number, _boolean, jsonObject, jsonArray);
package/core/lazy.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import { Decoder } from '../_types';
2
+
3
+ export function lazy<T>(decoderFn: () => Decoder<T>): Decoder<T>;
File without changes
@@ -0,0 +1,6 @@
1
+ /// <reference lib="es6" />
2
+
3
+ import { Decoder } from '../_types';
4
+
5
+ export function mapping<T>(decoder: Decoder<T>): Decoder<Map<string, T>>;
6
+ export function dict<T>(decoder: Decoder<T>): Decoder<{ [key: string]: T }>;
package/core/mapping.js CHANGED
@@ -4,30 +4,20 @@ exports.__esModule = true;
4
4
  exports.dict = dict;
5
5
  exports.mapping = mapping;
6
6
 
7
- var Result = _interopRequireWildcard(require("../result"));
8
-
9
7
  var _annotate = require("../annotate");
10
8
 
11
9
  var _composition = require("./composition");
12
10
 
13
- var _object = require("./object");
14
-
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); }
11
+ var _result = require("../result");
16
12
 
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 _object = require("./object");
18
14
 
19
15
  /**
20
- * Given an object, will decode a Map of string keys to whatever values.
21
- *
22
- * For example, given a decoder for a Person, we can verify a Person lookup
23
- * table structure (of type Map<string, Person>) like so:
24
- *
25
- * mapping(person)
26
- *
16
+ * Like mapping(), but returns an object rather than a Map instance.
27
17
  */
28
- function mapping(decoder) {
18
+ function dict(decoder) {
29
19
  return (0, _composition.compose)(_object.pojo, function (blob) {
30
- var tuples = [];
20
+ var rv = {};
31
21
  var errors = null;
32
22
  Object.keys(blob).forEach(function (key) {
33
23
  var value = blob[key];
@@ -35,10 +25,10 @@ function mapping(decoder) {
35
25
 
36
26
  if (result.type === 'ok') {
37
27
  if (errors === null) {
38
- tuples.push([key, result.value]);
28
+ rv[key] = result.value;
39
29
  }
40
30
  } else {
41
- tuples.length = 0; // Clear the tuples array
31
+ rv = {}; // Clear the success value so it can get garbage collected early
42
32
 
43
33
  if (errors === null) {
44
34
  errors = {};
@@ -49,19 +39,29 @@ function mapping(decoder) {
49
39
  });
50
40
 
51
41
  if (errors !== null) {
52
- return Result.err((0, _annotate.merge)((0, _annotate.annotateObject)(blob), errors));
42
+ return (0, _result.err)((0, _annotate.merge)((0, _annotate.annotateObject)(blob), errors));
53
43
  } else {
54
- return Result.ok(new Map(tuples));
44
+ return (0, _result.ok)(rv);
55
45
  }
56
46
  });
57
47
  }
58
48
  /**
59
- * Like mapping(), but returns an object rather than a Map instance.
49
+ * Given an object, will decode a Map of string keys to whatever values.
50
+ *
51
+ * For example, given a decoder for a Person, we can verify a Person lookup
52
+ * table structure (of type Map<string, Person>) like so:
53
+ *
54
+ * mapping(person)
55
+ *
60
56
  */
61
57
 
62
58
 
63
- function dict(decoder) {
64
- return (0, _composition.map)(mapping(decoder), function (m) {
65
- return Object.fromEntries(m);
59
+ function mapping(decoder) {
60
+ return (0, _composition.map)(dict(decoder), function (obj) {
61
+ return new Map( // This is effectively Object.entries(obj), but in a way that Flow
62
+ // will know the types are okay
63
+ Object.keys(obj).map(function (key) {
64
+ return [key, obj[key]];
65
+ }));
66
66
  });
67
67
  }
@@ -1,25 +1,19 @@
1
1
  // @flow strict
2
2
 
3
- import * as Result from '../result';
4
3
  import { annotateObject } from '../annotate';
5
4
  import { compose, map } from './composition';
5
+ import { err, ok } from '../result';
6
6
  import { merge } from '../annotate';
7
7
  import { pojo } from './object';
8
8
  import type { Annotation } from '../annotate';
9
9
  import type { Decoder } from '../_types';
10
10
 
11
11
  /**
12
- * Given an object, will decode a Map of string keys to whatever values.
13
- *
14
- * For example, given a decoder for a Person, we can verify a Person lookup
15
- * table structure (of type Map<string, Person>) like so:
16
- *
17
- * mapping(person)
18
- *
12
+ * Like mapping(), but returns an object rather than a Map instance.
19
13
  */
20
- export function mapping<T>(decoder: Decoder<T>): Decoder<Map<string, T>> {
14
+ export function dict<T>(decoder: Decoder<T>): Decoder<{ [string]: T }> {
21
15
  return compose(pojo, (blob: { +[key: string]: mixed }) => {
22
- let tuples: Array<[string, T]> = [];
16
+ let rv: { [key: string]: T } = {};
23
17
  let errors: { [key: string]: Annotation } | null = null;
24
18
 
25
19
  Object.keys(blob).forEach((key: string) => {
@@ -27,10 +21,10 @@ export function mapping<T>(decoder: Decoder<T>): Decoder<Map<string, T>> {
27
21
  const result = decoder(value);
28
22
  if (result.type === 'ok') {
29
23
  if (errors === null) {
30
- tuples.push([key, result.value]);
24
+ rv[key] = result.value;
31
25
  }
32
26
  } else {
33
- tuples.length = 0; // Clear the tuples array
27
+ rv = {}; // Clear the success value so it can get garbage collected early
34
28
  if (errors === null) {
35
29
  errors = {};
36
30
  }
@@ -39,16 +33,30 @@ export function mapping<T>(decoder: Decoder<T>): Decoder<Map<string, T>> {
39
33
  });
40
34
 
41
35
  if (errors !== null) {
42
- return Result.err(merge(annotateObject(blob), errors));
36
+ return err(merge(annotateObject(blob), errors));
43
37
  } else {
44
- return Result.ok(new Map(tuples));
38
+ return ok(rv);
45
39
  }
46
40
  });
47
41
  }
48
42
 
49
43
  /**
50
- * Like mapping(), but returns an object rather than a Map instance.
44
+ * Given an object, will decode a Map of string keys to whatever values.
45
+ *
46
+ * For example, given a decoder for a Person, we can verify a Person lookup
47
+ * table structure (of type Map<string, Person>) like so:
48
+ *
49
+ * mapping(person)
50
+ *
51
51
  */
52
- export function dict<T>(decoder: Decoder<T>): Decoder<{ [string]: T }> {
53
- return map(mapping(decoder), (m) => Object.fromEntries(m));
52
+ export function mapping<T>(decoder: Decoder<T>): Decoder<Map<string, T>> {
53
+ return map(
54
+ dict(decoder),
55
+ (obj) =>
56
+ new Map(
57
+ // This is effectively Object.entries(obj), but in a way that Flow
58
+ // will know the types are okay
59
+ Object.keys(obj).map((key) => [key, obj[key]]),
60
+ ),
61
+ );
54
62
  }
@@ -1,21 +1,15 @@
1
- import * as Result from '../result';
2
- import { annotateObject } from '../annotate';
3
- import { compose, map } from './composition';
4
- import { merge } from '../annotate';
5
- import { pojo } from './object';
1
+ import { annotateObject } from '../annotate.mjs';
2
+ import { compose, map } from './composition.mjs';
3
+ import { err, ok } from '../result.mjs';
4
+ import { merge } from '../annotate.mjs';
5
+ import { pojo } from './object.mjs';
6
6
 
7
7
  /**
8
- * Given an object, will decode a Map of string keys to whatever values.
9
- *
10
- * For example, given a decoder for a Person, we can verify a Person lookup
11
- * table structure (of type Map<string, Person>) like so:
12
- *
13
- * mapping(person)
14
- *
8
+ * Like mapping(), but returns an object rather than a Map instance.
15
9
  */
16
- export function mapping(decoder) {
10
+ export function dict(decoder) {
17
11
  return compose(pojo, function (blob) {
18
- var tuples = [];
12
+ var rv = {};
19
13
  var errors = null;
20
14
  Object.keys(blob).forEach(function (key) {
21
15
  var value = blob[key];
@@ -23,10 +17,10 @@ export function mapping(decoder) {
23
17
 
24
18
  if (result.type === 'ok') {
25
19
  if (errors === null) {
26
- tuples.push([key, result.value]);
20
+ rv[key] = result.value;
27
21
  }
28
22
  } else {
29
- tuples.length = 0; // Clear the tuples array
23
+ rv = {}; // Clear the success value so it can get garbage collected early
30
24
 
31
25
  if (errors === null) {
32
26
  errors = {};
@@ -37,18 +31,28 @@ export function mapping(decoder) {
37
31
  });
38
32
 
39
33
  if (errors !== null) {
40
- return Result.err(merge(annotateObject(blob), errors));
34
+ return err(merge(annotateObject(blob), errors));
41
35
  } else {
42
- return Result.ok(new Map(tuples));
36
+ return ok(rv);
43
37
  }
44
38
  });
45
39
  }
46
40
  /**
47
- * Like mapping(), but returns an object rather than a Map instance.
41
+ * Given an object, will decode a Map of string keys to whatever values.
42
+ *
43
+ * For example, given a decoder for a Person, we can verify a Person lookup
44
+ * table structure (of type Map<string, Person>) like so:
45
+ *
46
+ * mapping(person)
47
+ *
48
48
  */
49
49
 
50
- export function dict(decoder) {
51
- return map(mapping(decoder), function (m) {
52
- return Object.fromEntries(m);
50
+ export function mapping(decoder) {
51
+ return map(dict(decoder), function (obj) {
52
+ return new Map( // This is effectively Object.entries(obj), but in a way that Flow
53
+ // will know the types are okay
54
+ Object.keys(obj).map(function (key) {
55
+ return [key, obj[key]];
56
+ }));
53
57
  });
54
58
  }
@@ -0,0 +1,6 @@
1
+ import { Decoder } from '../_types';
2
+
3
+ export const integer: Decoder<number>;
4
+ export const number: Decoder<number>;
5
+ export const positiveInteger: Decoder<number>;
6
+ export const positiveNumber: Decoder<number>;
package/core/number.js CHANGED
@@ -3,18 +3,14 @@
3
3
  exports.__esModule = true;
4
4
  exports.positiveNumber = exports.positiveInteger = exports.number = exports.integer = void 0;
5
5
 
6
- var Result = _interopRequireWildcard(require("../result"));
7
-
8
6
  var _annotate = require("../annotate");
9
7
 
10
- var _composition = require("./composition");
11
-
12
- 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); }
8
+ var _result = require("../result");
13
9
 
14
- 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; }
10
+ var _composition = require("./composition");
15
11
 
16
12
  var anyNumber = function anyNumber(blob) {
17
- return typeof blob === 'number' && !Number.isNaN(blob) ? Result.ok(blob) : Result.err((0, _annotate.annotate)(blob, 'Must be number'));
13
+ return typeof blob === 'number' && !Number.isNaN(blob) ? (0, _result.ok)(blob) : (0, _result.err)((0, _annotate.annotate)(blob, 'Must be number'));
18
14
  };
19
15
 
20
16
  var isInteger = function isInteger(n) {
@@ -25,16 +21,16 @@ var isFinite = function isFinite(n) {
25
21
  return Number.isFinite(n);
26
22
  };
27
23
 
28
- var number = (0, _composition.compose)(anyNumber, (0, _composition.predicate)(isFinite, 'Number must be finite'));
24
+ var number = (0, _composition.predicate)(anyNumber, isFinite, 'Number must be finite');
29
25
  exports.number = number;
30
- var positiveNumber = (0, _composition.compose)(number, (0, _composition.predicate)(function (n) {
26
+ var positiveNumber = (0, _composition.predicate)(number, function (n) {
31
27
  return n >= 0;
32
- }, 'Number must be positive')); // Integers
28
+ }, 'Number must be positive'); // Integers
33
29
 
34
30
  exports.positiveNumber = positiveNumber;
35
- var integer = (0, _composition.compose)(number, (0, _composition.predicate)(isInteger, 'Number must be an integer'));
31
+ var integer = (0, _composition.predicate)(number, isInteger, 'Number must be an integer');
36
32
  exports.integer = integer;
37
- var positiveInteger = (0, _composition.compose)(integer, (0, _composition.predicate)(function (n) {
33
+ var positiveInteger = (0, _composition.predicate)(integer, function (n) {
38
34
  return n >= 0;
39
- }, 'Number must be positive'));
35
+ }, 'Number must be positive');
40
36
  exports.positiveInteger = positiveInteger;
@@ -1,34 +1,40 @@
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 { err, ok } from '../result';
5
+ import { predicate } from './composition';
6
6
  import type { Decoder } from '../_types';
7
7
 
8
8
  const anyNumber: Decoder<number> = (blob: mixed) => {
9
9
  return typeof blob === 'number' && !Number.isNaN(blob)
10
- ? Result.ok(blob)
11
- : Result.err(annotate(blob, 'Must be number'));
10
+ ? ok(blob)
11
+ : err(annotate(blob, 'Must be number'));
12
12
  };
13
13
 
14
14
  const isInteger = (n: number) => Number.isInteger(n);
15
15
  const isFinite = (n: number) => Number.isFinite(n);
16
16
 
17
- export const number: Decoder<number> = compose(
17
+ export const number: Decoder<number> = predicate(
18
18
  anyNumber,
19
- predicate(isFinite, 'Number must be finite'),
19
+ isFinite,
20
+ 'Number must be finite',
20
21
  );
21
- export const positiveNumber: Decoder<number> = compose(
22
+
23
+ export const positiveNumber: Decoder<number> = predicate(
22
24
  number,
23
- predicate((n) => n >= 0, 'Number must be positive'),
25
+ (n) => n >= 0,
26
+ 'Number must be positive',
24
27
  );
25
28
 
26
29
  // Integers
27
- export const integer: Decoder<number> = compose(
30
+ export const integer: Decoder<number> = predicate(
28
31
  number,
29
- predicate(isInteger, 'Number must be an integer'),
32
+ isInteger,
33
+ 'Number must be an integer',
30
34
  );
31
- export const positiveInteger: Decoder<number> = compose(
35
+
36
+ export const positiveInteger: Decoder<number> = predicate(
32
37
  integer,
33
- predicate((n) => n >= 0, 'Number must be positive'),
38
+ (n) => n >= 0,
39
+ 'Number must be positive',
34
40
  );
@@ -0,0 +1,25 @@
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');
@@ -0,0 +1,33 @@
1
+ import { Decoder, DecoderType } from '../_types';
2
+ import { AllowImplicit } from './_helpers';
3
+
4
+ export type ObjectDecoderType<T> = AllowImplicit<{
5
+ [key in keyof T]: DecoderType<T[key]>;
6
+ }>;
7
+
8
+ export const pojo: Decoder<{ [key: string]: unknown }>;
9
+
10
+ export function object<O extends { [key: string]: Decoder<any> }>(
11
+ mapping: O,
12
+ ): Decoder<{ [K in keyof ObjectDecoderType<O>]: ObjectDecoderType<O>[K] }>;
13
+ // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
14
+ // This is basically just equivalent to:
15
+ // ObjectDecoderType<O>
16
+ //
17
+ // But by "resolving" this with a mapped type, we remove the helper
18
+ // type names from the inferred type here, making this much easier to
19
+ // work with while developing.
20
+
21
+ export function exact<O extends { [key: string]: Decoder<any> }>(
22
+ mapping: O,
23
+ ): Decoder<{ [K in keyof ObjectDecoderType<O>]: ObjectDecoderType<O>[K] }>;
24
+ // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
25
+ // Ditto (see above)
26
+
27
+ export function inexact<O extends { [key: string]: Decoder<any> }>(
28
+ mapping: O,
29
+ ): Decoder<
30
+ { [K in keyof ObjectDecoderType<O>]: ObjectDecoderType<O>[K] } & {
31
+ [extra: string]: unknown;
32
+ }
33
+ >;