decoders 2.0.0-beta1 → 2.0.0-beta13

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 (165) hide show
  1. package/CHANGELOG.md +53 -5
  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/NotSupportedTSVersion.d.ts +1 -0
  7. package/README.md +124 -961
  8. package/_utils.d.ts +9 -0
  9. package/{cjs/_utils.js → _utils.js} +12 -18
  10. package/{cjs/_utils.js.flow → _utils.js.flow} +15 -19
  11. package/{es/_utils.js → _utils.mjs} +11 -15
  12. package/{ts/annotate.d.ts → annotate.d.ts} +25 -21
  13. package/{cjs/annotate.js → annotate.js} +0 -0
  14. package/{cjs/annotate.js.flow → annotate.js.flow} +0 -0
  15. package/{es/annotate.js → annotate.mjs} +0 -0
  16. package/format.d.ts +6 -0
  17. package/{cjs/format/inline.js → format.js} +7 -2
  18. package/{cjs/format/inline.js.flow → format.js.flow} +9 -3
  19. package/{es/format/inline.js → format.mjs} +5 -2
  20. package/index.d.ts +40 -0
  21. package/index.js +89 -0
  22. package/index.js.flow +44 -0
  23. package/index.mjs +11 -0
  24. package/{ts → lib}/_helpers.d.ts +0 -0
  25. package/lib/arrays.d.ts +59 -0
  26. package/lib/arrays.js +139 -0
  27. package/lib/arrays.js.flow +138 -0
  28. package/lib/arrays.mjs +124 -0
  29. package/lib/basics.d.ts +93 -0
  30. package/lib/basics.js +144 -0
  31. package/lib/basics.js.flow +124 -0
  32. package/lib/basics.mjs +120 -0
  33. package/lib/booleans.d.ts +16 -0
  34. package/lib/booleans.js +35 -0
  35. package/lib/booleans.js.flow +22 -0
  36. package/lib/booleans.mjs +25 -0
  37. package/lib/dates.d.ts +15 -0
  38. package/lib/dates.js +44 -0
  39. package/lib/dates.js.flow +40 -0
  40. package/lib/dates.mjs +34 -0
  41. package/lib/json.d.ts +35 -0
  42. package/lib/json.js +55 -0
  43. package/lib/json.js.flow +50 -0
  44. package/lib/json.mjs +40 -0
  45. package/lib/numbers.d.ts +31 -0
  46. package/lib/numbers.js +51 -0
  47. package/lib/numbers.js.flow +48 -0
  48. package/lib/numbers.mjs +41 -0
  49. package/lib/objects.d.ts +75 -0
  50. package/lib/objects.js +240 -0
  51. package/lib/objects.js.flow +246 -0
  52. package/lib/objects.mjs +223 -0
  53. package/lib/strings.d.ts +56 -0
  54. package/lib/strings.js +101 -0
  55. package/lib/strings.js.flow +90 -0
  56. package/lib/strings.mjs +82 -0
  57. package/lib/unions.d.ts +55 -0
  58. package/lib/unions.js +160 -0
  59. package/lib/unions.js.flow +155 -0
  60. package/lib/unions.mjs +146 -0
  61. package/lib/utilities.d.ts +34 -0
  62. package/lib/utilities.js +75 -0
  63. package/lib/utilities.js.flow +65 -0
  64. package/lib/utilities.mjs +60 -0
  65. package/package.json +79 -29
  66. package/result.d.ts +16 -0
  67. package/result.js +34 -0
  68. package/result.js.flow +26 -0
  69. package/result.mjs +27 -0
  70. package/cjs/_guard.js +0 -26
  71. package/cjs/_guard.js.flow +0 -20
  72. package/cjs/_types.js +0 -1
  73. package/cjs/_types.js.flow +0 -20
  74. package/cjs/format/index.js +0 -12
  75. package/cjs/format/index.js.flow +0 -4
  76. package/cjs/format/short.js +0 -10
  77. package/cjs/format/short.js.flow +0 -8
  78. package/cjs/index.js +0 -120
  79. package/cjs/index.js.flow +0 -63
  80. package/cjs/result.js +0 -172
  81. package/cjs/result.js.flow +0 -166
  82. package/cjs/stdlib/array.js +0 -108
  83. package/cjs/stdlib/array.js.flow +0 -103
  84. package/cjs/stdlib/boolean.js +0 -44
  85. package/cjs/stdlib/boolean.js.flow +0 -29
  86. package/cjs/stdlib/composition.js +0 -56
  87. package/cjs/stdlib/composition.js.flow +0 -43
  88. package/cjs/stdlib/constants.js +0 -69
  89. package/cjs/stdlib/constants.js.flow +0 -46
  90. package/cjs/stdlib/date.js +0 -46
  91. package/cjs/stdlib/date.js.flow +0 -40
  92. package/cjs/stdlib/describe.js +0 -26
  93. package/cjs/stdlib/describe.js.flow +0 -17
  94. package/cjs/stdlib/dispatch.js +0 -62
  95. package/cjs/stdlib/dispatch.js.flow +0 -58
  96. package/cjs/stdlib/either.js +0 -117
  97. package/cjs/stdlib/either.js.flow +0 -151
  98. package/cjs/stdlib/fail.js +0 -21
  99. package/cjs/stdlib/fail.js.flow +0 -12
  100. package/cjs/stdlib/instanceOf.js +0 -19
  101. package/cjs/stdlib/instanceOf.js.flow +0 -20
  102. package/cjs/stdlib/json.js +0 -31
  103. package/cjs/stdlib/json.js.flow +0 -28
  104. package/cjs/stdlib/lazy.js +0 -16
  105. package/cjs/stdlib/lazy.js.flow +0 -15
  106. package/cjs/stdlib/mapping.js +0 -67
  107. package/cjs/stdlib/mapping.js.flow +0 -54
  108. package/cjs/stdlib/number.js +0 -40
  109. package/cjs/stdlib/number.js.flow +0 -34
  110. package/cjs/stdlib/object.js +0 -194
  111. package/cjs/stdlib/object.js.flow +0 -203
  112. package/cjs/stdlib/optional.js +0 -54
  113. package/cjs/stdlib/optional.js.flow +0 -41
  114. package/cjs/stdlib/string.js +0 -98
  115. package/cjs/stdlib/string.js.flow +0 -82
  116. package/cjs/stdlib/tuple.js +0 -173
  117. package/cjs/stdlib/tuple.js.flow +0 -220
  118. package/es/_guard.js +0 -15
  119. package/es/_types.js +0 -0
  120. package/es/format/index.js +0 -2
  121. package/es/format/short.js +0 -4
  122. package/es/index.js +0 -37
  123. package/es/result.js +0 -139
  124. package/es/stdlib/array.js +0 -91
  125. package/es/stdlib/boolean.js +0 -28
  126. package/es/stdlib/composition.js +0 -42
  127. package/es/stdlib/constants.js +0 -46
  128. package/es/stdlib/date.js +0 -28
  129. package/es/stdlib/describe.js +0 -16
  130. package/es/stdlib/dispatch.js +0 -51
  131. package/es/stdlib/either.js +0 -90
  132. package/es/stdlib/fail.js +0 -11
  133. package/es/stdlib/instanceOf.js +0 -8
  134. package/es/stdlib/json.js +0 -15
  135. package/es/stdlib/lazy.js +0 -11
  136. package/es/stdlib/mapping.js +0 -54
  137. package/es/stdlib/number.js +0 -25
  138. package/es/stdlib/object.js +0 -175
  139. package/es/stdlib/optional.js +0 -38
  140. package/es/stdlib/string.js +0 -76
  141. package/es/stdlib/tuple.js +0 -155
  142. package/ts/_guard.d.ts +0 -7
  143. package/ts/_types.d.ts +0 -16
  144. package/ts/_utils.d.ts +0 -13
  145. package/ts/array.d.ts +0 -5
  146. package/ts/boolean.d.ts +0 -5
  147. package/ts/constants.d.ts +0 -11
  148. package/ts/date.d.ts +0 -4
  149. package/ts/describe.d.ts +0 -3
  150. package/ts/dispatch.d.ts +0 -8
  151. package/ts/either.d.ts +0 -61
  152. package/ts/fail.d.ts +0 -3
  153. package/ts/index.d.ts +0 -42
  154. package/ts/inline.d.ts +0 -3
  155. package/ts/instanceOf.d.ts +0 -3
  156. package/ts/json.d.ts +0 -11
  157. package/ts/lazy.d.ts +0 -3
  158. package/ts/mapping.d.ts +0 -4
  159. package/ts/number.d.ts +0 -6
  160. package/ts/object.d.ts +0 -33
  161. package/ts/optional.d.ts +0 -5
  162. package/ts/result.d.ts +0 -39
  163. package/ts/short.d.ts +0 -3
  164. package/ts/string.d.ts +0 -7
  165. package/ts/tuple.d.ts +0 -30
package/Decoder.mjs ADDED
@@ -0,0 +1,215 @@
1
+ import { annotate } from './annotate.mjs';
2
+ import { formatInline } from './format.mjs';
3
+ import { err as makeErr, ok as makeOk } from './result.mjs';
4
+
5
+ function noThrow(fn) {
6
+ return function (t) {
7
+ try {
8
+ var v = fn(t);
9
+ return makeOk(v);
10
+ } catch (e) {
11
+ return makeErr(annotate(t, e instanceof Error ? e.message : String(e)));
12
+ }
13
+ };
14
+ }
15
+
16
+ function format(err, formatter) {
17
+ var formatted = formatter(err); // Formatter functions may return a string or an error for convenience of
18
+ // writing them. If it already returns an Error, return it unmodified. If
19
+ // it returns a string, wrap it in a "Decoding error" instance.
20
+
21
+ if (typeof formatted === 'string') {
22
+ var _err = new Error('\n' + formatted);
23
+
24
+ _err.name = 'Decoding error';
25
+ return _err;
26
+ } else {
27
+ return formatted;
28
+ }
29
+ }
30
+ /**
31
+ * Defines a new `Decoder<T>`, by implementing a custom acceptance function.
32
+ * The function receives three arguments:
33
+ *
34
+ * 1. `blob` - the raw/unknown input (aka your external data)
35
+ * 2. `ok` - Call `ok(value)` to accept the input and return ``value``
36
+ * 3. `err` - Call `err(message)` to reject the input with error ``message``
37
+ *
38
+ * The expected return value should be a `DecodeResult<T>`, which can be
39
+ * obtained by returning the result of calling the provided `ok` or `err`
40
+ * helper functions. Please note that `ok()` and `err()` don't perform side
41
+ * effects! You'll need to _return_ those values.
42
+ */
43
+
44
+
45
+ export function define(fn) {
46
+ /**
47
+ * Verifies the untrusted/unknown input and either accepts or rejects it.
48
+ *
49
+ * Contrasted with `.verify()`, calls to `.decode()` will never fail and
50
+ * instead return a result type.
51
+ */
52
+ function decode(blob) {
53
+ return fn(blob, makeOk, function (msg) {
54
+ return makeErr(typeof msg === 'string' ? annotate(blob, msg) : msg);
55
+ });
56
+ }
57
+ /**
58
+ * Verifies the untrusted/unknown input and either accepts or rejects it.
59
+ * When accepted, returns a value of type `T`. Otherwise fail with
60
+ * a runtime error.
61
+ */
62
+
63
+
64
+ function verify(blob, formatter) {
65
+ if (formatter === void 0) {
66
+ formatter = formatInline;
67
+ }
68
+
69
+ var result = decode(blob);
70
+
71
+ if (result.ok) {
72
+ return result.value;
73
+ } else {
74
+ throw format(result.error, formatter);
75
+ }
76
+ }
77
+ /**
78
+ * Verifies the untrusted/unknown input and either accepts or rejects it.
79
+ * When accepted, returns the decoded `T` value directly. Otherwise returns
80
+ * `undefined`.
81
+ *
82
+ * Use this when you're not interested in programmatically handling the
83
+ * error message.
84
+ */
85
+
86
+
87
+ function value(blob) {
88
+ return decode(blob).value;
89
+ }
90
+ /**
91
+ * Accepts any value the given decoder accepts, and on success, will call
92
+ * the given function **on the decoded result**. If the transformation
93
+ * function throws an error, the whole decoder will fail using the error
94
+ * message as the failure reason.
95
+ */
96
+
97
+
98
+ function transform(transformFn) {
99
+ return then(noThrow(transformFn));
100
+ }
101
+ /**
102
+ * Adds an extra predicate to a decoder. The new decoder is like the
103
+ * original decoder, but only accepts values that also meet the
104
+ * predicate.
105
+ */
106
+
107
+
108
+ function refine(predicateFn, errmsg) {
109
+ return reject(function (value) {
110
+ return predicateFn(value) ? // Don't reject
111
+ null : // Reject with the given error message
112
+ errmsg;
113
+ });
114
+ }
115
+ /**
116
+ * Chain together the current decoder with another.
117
+ *
118
+ * > _**NOTE:** This is an advanced, low-level, API. It's not recommended
119
+ * > to reach for this construct unless there is no other way. Most cases can
120
+ * > be covered more elegantly by `.transform()` or `.refine()` instead._
121
+ *
122
+ * If the current decoder accepts an input, the resulting ``T`` value will
123
+ * get passed into the given ``next`` acceptance function to further decide
124
+ * whether or not the value should get accepted or rejected.
125
+ *
126
+ * This works similar to how you would `define()` a new decoder, except
127
+ * that the ``blob`` param will now be ``T`` (a known type), rather than
128
+ * ``unknown``. This will allow the function to make a stronger assumption
129
+ * about its input and avoid re-refining inputs.
130
+ *
131
+ * If it helps, you can think of `define(...)` as equivalent to
132
+ * `unknown.then(...)`.
133
+ */
134
+
135
+
136
+ function then(next) {
137
+ return define(function (blob, ok, err) {
138
+ var result = decode(blob);
139
+ return result.ok ? next(result.value, ok, err) : result;
140
+ });
141
+ }
142
+ /**
143
+ * Adds an extra predicate to a decoder. The new decoder is like the
144
+ * original decoder, but only accepts values that aren't rejected by the
145
+ * given function.
146
+ *
147
+ * The given function can return `null` to accept the decoded value, or
148
+ * return a specific error message to reject.
149
+ *
150
+ * Unlike `.refine()`, you can use this function to return a dynamic error
151
+ * message.
152
+ */
153
+
154
+
155
+ function reject(rejectFn) {
156
+ return then(function (value, ok, err) {
157
+ var errmsg = rejectFn(value);
158
+ return errmsg === null ? ok(value) : err(typeof errmsg === 'string' ? annotate(value, errmsg) : errmsg);
159
+ });
160
+ }
161
+ /**
162
+ * Uses the given decoder, but will use an alternative error message in
163
+ * case it rejects. This can be used to simplify or shorten otherwise
164
+ * long or low-level/technical errors.
165
+ */
166
+
167
+
168
+ function describe(message) {
169
+ return define(function (blob, _, err) {
170
+ // Decode using the given decoder...
171
+ var result = decode(blob);
172
+
173
+ if (result.ok) {
174
+ return result;
175
+ } else {
176
+ // ...but in case of error, annotate this with the custom given
177
+ // message instead
178
+ return err(annotate(result.error, message));
179
+ }
180
+ });
181
+ }
182
+ /**
183
+ * WARNING: This is an EXPERIMENTAL API that will likely change in the
184
+ * future. Please DO NOT rely on it.
185
+ *
186
+ * Chain together the current decoder with another, but also pass along
187
+ * the original input.
188
+ *
189
+ * This is like `.then()`, but instead of this function receiving just
190
+ * the decoded result ``T``, it also receives the original input.
191
+ *
192
+ * This is an advanced, low-level, decoder.
193
+ */
194
+
195
+
196
+ function peek_UNSTABLE(next) {
197
+ return define(function (blob, ok, err) {
198
+ var result = decode(blob);
199
+ return result.ok ? next([blob, result.value], ok, err) : result;
200
+ });
201
+ }
202
+
203
+ return Object.freeze({
204
+ verify: verify,
205
+ value: value,
206
+ decode: decode,
207
+ transform: transform,
208
+ refine: refine,
209
+ reject: reject,
210
+ describe: describe,
211
+ then: then,
212
+ // EXPERIMENTAL - please DO NOT rely on this method
213
+ peek_UNSTABLE: peek_UNSTABLE
214
+ });
215
+ }
@@ -0,0 +1 @@
1
+ "Package `decoders` requires TypeScript >= 4.1.0"