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