decoders 2.0.0-beta12 → 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.
- package/CHANGELOG.md +53 -35
- package/Decoder.d.ts +71 -5
- package/Decoder.js +41 -42
- package/Decoder.js.flow +102 -66
- package/Decoder.mjs +41 -42
- package/README.md +81 -62
- package/format.d.ts +4 -2
- package/format.js.flow +2 -0
- package/index.d.ts +1 -1
- package/index.js +1 -2
- package/index.js.flow +1 -1
- package/index.mjs +1 -1
- package/lib/arrays.d.ts +22 -0
- package/lib/arrays.js +5 -4
- package/lib/arrays.js.flow +6 -6
- package/lib/arrays.mjs +5 -4
- package/lib/basics.d.ts +64 -9
- package/lib/basics.js +22 -12
- package/lib/basics.js.flow +23 -12
- package/lib/basics.mjs +22 -12
- package/lib/booleans.d.ts +11 -0
- package/lib/booleans.js +1 -1
- package/lib/booleans.js.flow +1 -1
- package/lib/booleans.mjs +1 -1
- package/lib/dates.d.ts +11 -0
- package/lib/dates.js +1 -1
- package/lib/dates.js.flow +1 -1
- package/lib/dates.mjs +1 -1
- package/lib/json.d.ts +24 -0
- package/lib/numbers.d.ts +26 -2
- package/lib/numbers.js +4 -5
- package/lib/numbers.js.flow +4 -5
- package/lib/numbers.mjs +4 -5
- package/lib/objects.d.ts +38 -1
- package/lib/strings.d.ts +43 -0
- package/lib/unions.d.ts +40 -63
- package/lib/unions.js +10 -11
- package/lib/unions.js.flow +10 -13
- package/lib/unions.mjs +9 -8
- package/lib/utilities.d.ts +24 -0
- package/lib/utilities.js +0 -19
- package/lib/utilities.js.flow +0 -19
- package/lib/utilities.mjs +0 -19
- package/package.json +1 -1
package/Decoder.mjs
CHANGED
|
@@ -12,38 +12,52 @@ function noThrow(fn) {
|
|
|
12
12
|
}
|
|
13
13
|
};
|
|
14
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
|
+
}
|
|
15
30
|
/**
|
|
16
31
|
* Defines a new `Decoder<T>`, by implementing a custom acceptance function.
|
|
17
32
|
* The function receives three arguments:
|
|
18
33
|
*
|
|
19
34
|
* 1. `blob` - the raw/unknown input (aka your external data)
|
|
20
35
|
* 2. `ok` - Call `ok(value)` to accept the input and return ``value``
|
|
21
|
-
* 3. `err` - Call `err(message)` to reject the input
|
|
22
|
-
* annotation
|
|
36
|
+
* 3. `err` - Call `err(message)` to reject the input with error ``message``
|
|
23
37
|
*
|
|
24
38
|
* The expected return value should be a `DecodeResult<T>`, which can be
|
|
25
|
-
* obtained by returning the result
|
|
26
|
-
* functions.
|
|
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.
|
|
27
42
|
*/
|
|
28
43
|
|
|
29
44
|
|
|
30
|
-
export function define(
|
|
45
|
+
export function define(fn) {
|
|
31
46
|
/**
|
|
32
|
-
*
|
|
33
|
-
* it.
|
|
47
|
+
* Verifies the untrusted/unknown input and either accepts or rejects it.
|
|
34
48
|
*
|
|
35
49
|
* Contrasted with `.verify()`, calls to `.decode()` will never fail and
|
|
36
50
|
* instead return a result type.
|
|
37
51
|
*/
|
|
38
52
|
function decode(blob) {
|
|
39
|
-
return
|
|
53
|
+
return fn(blob, makeOk, function (msg) {
|
|
40
54
|
return makeErr(typeof msg === 'string' ? annotate(blob, msg) : msg);
|
|
41
55
|
});
|
|
42
56
|
}
|
|
43
57
|
/**
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
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.
|
|
47
61
|
*/
|
|
48
62
|
|
|
49
63
|
|
|
@@ -57,26 +71,13 @@ export function define(decodeFn) {
|
|
|
57
71
|
if (result.ok) {
|
|
58
72
|
return result.value;
|
|
59
73
|
} else {
|
|
60
|
-
|
|
61
|
-
// writing them. If it already returns an Error, throw it
|
|
62
|
-
// unmodified. If it returns a string, wrap it in a "Decoding
|
|
63
|
-
// error" instance from it and throw that.
|
|
64
|
-
var strOrErr = formatter(result.error);
|
|
65
|
-
|
|
66
|
-
if (typeof strOrErr === 'string') {
|
|
67
|
-
var _err = new Error('\n' + strOrErr);
|
|
68
|
-
|
|
69
|
-
_err.name = 'Decoding error';
|
|
70
|
-
throw _err;
|
|
71
|
-
} else {
|
|
72
|
-
throw strOrErr;
|
|
73
|
-
}
|
|
74
|
+
throw format(result.error, formatter);
|
|
74
75
|
}
|
|
75
76
|
}
|
|
76
77
|
/**
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
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`.
|
|
80
81
|
*
|
|
81
82
|
* Use this when you're not interested in programmatically handling the
|
|
82
83
|
* error message.
|
|
@@ -114,23 +115,21 @@ export function define(decodeFn) {
|
|
|
114
115
|
/**
|
|
115
116
|
* Chain together the current decoder with another.
|
|
116
117
|
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
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._
|
|
120
121
|
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
* a `.then()` call the provided ``next`` function will receive a ``T`` as
|
|
125
|
-
* its input. This will allow the function to make a stronger assumption
|
|
126
|
-
* about its input.
|
|
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.
|
|
127
125
|
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
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
130
|
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
* cases can be covered by `.transform()` or `.refine()`.
|
|
131
|
+
* If it helps, you can think of `define(...)` as equivalent to
|
|
132
|
+
* `unknown.then(...)`.
|
|
134
133
|
*/
|
|
135
134
|
|
|
136
135
|
|
package/README.md
CHANGED
|
@@ -22,14 +22,19 @@ solve both of these problems at once.**
|
|
|
22
22
|
```typescript
|
|
23
23
|
import { array, iso8601, number, object, optional, string } from 'decoders';
|
|
24
24
|
|
|
25
|
-
//
|
|
25
|
+
//
|
|
26
|
+
// Incoming data at runtime
|
|
27
|
+
//
|
|
26
28
|
const externalData = {
|
|
27
29
|
id: 123,
|
|
28
30
|
name: 'Alison Roberts',
|
|
29
|
-
createdAt: '
|
|
30
|
-
tags: ['foo', 'bar'
|
|
31
|
+
createdAt: '1994-01-11T12:26:37.024Z',
|
|
32
|
+
tags: ['foo', 'bar'],
|
|
31
33
|
};
|
|
32
34
|
|
|
35
|
+
//
|
|
36
|
+
// Write the decoder (= what you expect the data to look like)
|
|
37
|
+
//
|
|
33
38
|
const userDecoder = object({
|
|
34
39
|
id: number,
|
|
35
40
|
name: string,
|
|
@@ -37,82 +42,96 @@ const userDecoder = object({
|
|
|
37
42
|
tags: array(string),
|
|
38
43
|
});
|
|
39
44
|
|
|
40
|
-
//
|
|
41
|
-
//
|
|
42
|
-
//
|
|
43
|
-
// name: string;
|
|
44
|
-
// createdAt?: Date;
|
|
45
|
-
// tags: string[];
|
|
46
|
-
// }
|
|
47
|
-
|
|
45
|
+
//
|
|
46
|
+
// Call .verify() on the incoming data
|
|
47
|
+
//
|
|
48
48
|
const user = userDecoder.verify(externalData);
|
|
49
|
+
// ^^^^
|
|
50
|
+
// TypeScript can automatically infer this type now:
|
|
51
|
+
//
|
|
52
|
+
// {
|
|
53
|
+
// id: number;
|
|
54
|
+
// name: string;
|
|
55
|
+
// createdAt?: Date;
|
|
56
|
+
// tags: string[];
|
|
57
|
+
// }
|
|
58
|
+
//
|
|
49
59
|
```
|
|
50
60
|
|
|
51
61
|
## Documentation
|
|
52
62
|
|
|
53
|
-
<div id="
|
|
54
|
-
<div id="
|
|
55
|
-
<div id="
|
|
63
|
+
<div id="$DecoderType"></div>
|
|
64
|
+
<div id="DecodeResult"></div>
|
|
65
|
+
<div id="Decoder"></div>
|
|
66
|
+
<div id="DecoderType"></div>
|
|
67
|
+
<div id="Guard"></div>
|
|
68
|
+
<div id="JSONArray"></div>
|
|
69
|
+
<div id="JSONObject"></div>
|
|
70
|
+
<div id="JSONValue"></div>
|
|
71
|
+
<div id="Scalar"></div>
|
|
72
|
+
<div id="adding-predicates"></div>
|
|
73
|
+
<div id="always"></div>
|
|
74
|
+
<div id="anyNumber"></div>
|
|
75
|
+
<div id="array"></div>
|
|
76
|
+
<div id="boolean"></div>
|
|
56
77
|
<div id="building-custom-decoders"></div>
|
|
57
|
-
<div id="
|
|
58
|
-
<div id="
|
|
59
|
-
<div id="
|
|
60
|
-
<div id="
|
|
61
|
-
<div id="
|
|
62
|
-
<div id="
|
|
63
|
-
<div id="
|
|
78
|
+
<div id="compose"></div>
|
|
79
|
+
<div id="compositions"></div>
|
|
80
|
+
<div id="constant"></div>
|
|
81
|
+
<div id="date"></div>
|
|
82
|
+
<div id="define"></div>
|
|
83
|
+
<div id="describe"></div>
|
|
84
|
+
<div id="dict"></div>
|
|
85
|
+
<div id="either"></div>
|
|
64
86
|
<div id="email"></div>
|
|
65
|
-
<div id="
|
|
87
|
+
<div id="exact"></div>
|
|
88
|
+
<div id="fail"></div>
|
|
89
|
+
<div id="guard"></div>
|
|
90
|
+
<div id="hardcoded"></div>
|
|
66
91
|
<div id="httpsUrl"></div>
|
|
67
|
-
<div id="
|
|
68
|
-
<div id="
|
|
69
|
-
<div id="
|
|
70
|
-
<div id="boolean"></div>
|
|
71
|
-
<div id="string"></div>
|
|
72
|
-
<div id="truthy"></div>
|
|
73
|
-
<div id="numericBoolean"></div>
|
|
74
|
-
<div id="date"></div>
|
|
92
|
+
<div id="inexact"></div>
|
|
93
|
+
<div id="instanceOf"></div>
|
|
94
|
+
<div id="integer"></div>
|
|
75
95
|
<div id="iso8601"></div>
|
|
76
|
-
<div id="
|
|
77
|
-
<div id="
|
|
78
|
-
<div id="
|
|
79
|
-
<div id="
|
|
80
|
-
<div id="
|
|
81
|
-
<div id="never"></div>
|
|
82
|
-
<div id="fail"></div>
|
|
83
|
-
<div id="unknown"></div>
|
|
84
|
-
<div id="mixed"></div>
|
|
85
|
-
<div id="optional"></div>
|
|
86
|
-
<div id="nullable"></div>
|
|
96
|
+
<div id="json"></div>
|
|
97
|
+
<div id="jsonArray"></div>
|
|
98
|
+
<div id="jsonObject"></div>
|
|
99
|
+
<div id="lazy"></div>
|
|
100
|
+
<div id="mapping"></div>
|
|
87
101
|
<div id="maybe"></div>
|
|
88
|
-
<div id="
|
|
102
|
+
<div id="mixed"></div>
|
|
103
|
+
<div id="never"></div>
|
|
89
104
|
<div id="nonEmptyArray"></div>
|
|
90
|
-
<div id="
|
|
91
|
-
<div id="
|
|
92
|
-
<div id="
|
|
105
|
+
<div id="nonEmptyString"></div>
|
|
106
|
+
<div id="null_"></div>
|
|
107
|
+
<div id="nullable"></div>
|
|
108
|
+
<div id="number"></div>
|
|
109
|
+
<div id="numericBoolean"></div>
|
|
93
110
|
<div id="object"></div>
|
|
94
|
-
<div id="exact"></div>
|
|
95
|
-
<div id="inexact"></div>
|
|
96
|
-
<div id="pojo"></div>
|
|
97
|
-
<div id="dict"></div>
|
|
98
|
-
<div id="mapping"></div>
|
|
99
|
-
<div id="json"></div>
|
|
100
|
-
<div id="jsonObject"></div>
|
|
101
|
-
<div id="jsonArray"></div>
|
|
102
|
-
<div id="either"></div>
|
|
103
|
-
<div id="taggedUnion"></div>
|
|
104
111
|
<div id="oneOf"></div>
|
|
105
|
-
<div id="
|
|
106
|
-
<div id="
|
|
107
|
-
<div id="
|
|
112
|
+
<div id="optional"></div>
|
|
113
|
+
<div id="poja"></div>
|
|
114
|
+
<div id="pojo"></div>
|
|
115
|
+
<div id="positiveInteger"></div>
|
|
116
|
+
<div id="positiveNumber"></div>
|
|
108
117
|
<div id="predicate"></div>
|
|
109
118
|
<div id="prep"></div>
|
|
110
|
-
<div id="
|
|
111
|
-
<div id="
|
|
119
|
+
<div id="primitives"></div>
|
|
120
|
+
<div id="regex"></div>
|
|
121
|
+
<div id="set"></div>
|
|
122
|
+
<div id="string"></div>
|
|
123
|
+
<div id="taggedUnion"></div>
|
|
112
124
|
<div id="the-difference-between-object-exact-and-inexact"></div>
|
|
113
|
-
<div id="
|
|
125
|
+
<div id="transform"></div>
|
|
114
126
|
<div id="transformation"></div>
|
|
115
|
-
<div id="
|
|
127
|
+
<div id="truthy"></div>
|
|
128
|
+
<div id="tuple"></div>
|
|
129
|
+
<div id="undefined_"></div>
|
|
130
|
+
<div id="unknown"></div>
|
|
131
|
+
<div id="url"></div>
|
|
132
|
+
<div id="uuid"></div>
|
|
133
|
+
<div id="uuidv1"></div>
|
|
134
|
+
<div id="uuidv4"></div>
|
|
116
135
|
|
|
117
136
|
Documentation for v1 can be found
|
|
118
137
|
[here](https://github.com/nvie/decoders/tree/v1.25.5#readme).
|
package/format.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { Annotation } from './annotate';
|
|
2
2
|
|
|
3
|
-
export
|
|
4
|
-
|
|
3
|
+
export type Formatter = (err: Annotation) => string | Error;
|
|
4
|
+
|
|
5
|
+
export const formatInline: Formatter;
|
|
6
|
+
export const formatShort: Formatter;
|
package/format.js.flow
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
import { summarize as _summarize, asDate, INDENT, indent, isMultiline } from './_utils';
|
|
4
4
|
import type { Annotation, ArrayAnnotation, ObjectAnnotation } from './annotate';
|
|
5
5
|
|
|
6
|
+
export type Formatter = (err: Annotation) => string | Error;
|
|
7
|
+
|
|
6
8
|
function serializeString(s: string, width: number = 80): string {
|
|
7
9
|
// Full string
|
|
8
10
|
// Abbreviated to $maxlen i.e. "Vincent Driess..." [truncated]
|
package/index.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export { array, nonEmptyArray, poja, set, tuple } from './lib/arrays';
|
|
|
17
17
|
export { boolean, numericBoolean, truthy } from './lib/booleans';
|
|
18
18
|
export { date, iso8601 } from './lib/dates';
|
|
19
19
|
export { dict, exact, inexact, mapping, object, pojo } from './lib/objects';
|
|
20
|
-
export { either, oneOf, taggedUnion
|
|
20
|
+
export { either, oneOf, taggedUnion } from './lib/unions';
|
|
21
21
|
export {
|
|
22
22
|
email,
|
|
23
23
|
httpsUrl,
|
package/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
exports.__esModule = true;
|
|
4
|
-
exports.uuidv4 = exports.uuidv1 = exports.uuid = exports.url = exports.unknown = exports.undefined_ = exports.tuple = exports.truthy = exports.taggedUnion = exports.string = exports.set = exports.regex = exports.prep = exports.positiveNumber = exports.positiveInteger = exports.pojo = exports.poja = exports.optional = exports.oneOf = exports.object = exports.numericBoolean = exports.number = exports.nullable = exports.null_ = exports.nonEmptyString = exports.nonEmptyArray = exports.never = exports.mixed = exports.maybe = exports.mapping = exports.lazy = exports.jsonObject = exports.jsonArray = exports.json = exports.iso8601 = exports.integer = exports.instanceOf = exports.inexact = exports.httpsUrl = exports.hardcoded = exports.fail = exports.exact = exports.email = exports.either = exports.
|
|
4
|
+
exports.uuidv4 = exports.uuidv1 = exports.uuid = exports.url = exports.unknown = exports.undefined_ = exports.tuple = exports.truthy = exports.taggedUnion = exports.string = exports.set = exports.regex = exports.prep = exports.positiveNumber = exports.positiveInteger = exports.pojo = exports.poja = exports.optional = exports.oneOf = exports.object = exports.numericBoolean = exports.number = exports.nullable = exports.null_ = exports.nonEmptyString = exports.nonEmptyArray = exports.never = exports.mixed = exports.maybe = exports.mapping = exports.lazy = exports.jsonObject = exports.jsonArray = exports.json = exports.iso8601 = exports.integer = exports.instanceOf = exports.inexact = exports.httpsUrl = exports.hardcoded = exports.fail = exports.exact = exports.email = exports.either = exports.dict = exports.define = exports.date = exports.constant = exports["boolean"] = exports.array = exports.anyNumber = exports.always = void 0;
|
|
5
5
|
|
|
6
6
|
var _Decoder = require("./Decoder");
|
|
7
7
|
|
|
@@ -53,7 +53,6 @@ var _unions = require("./lib/unions");
|
|
|
53
53
|
exports.either = _unions.either;
|
|
54
54
|
exports.oneOf = _unions.oneOf;
|
|
55
55
|
exports.taggedUnion = _unions.taggedUnion;
|
|
56
|
-
exports.dispatch = _unions.dispatch;
|
|
57
56
|
|
|
58
57
|
var _strings = require("./lib/strings");
|
|
59
58
|
|
package/index.js.flow
CHANGED
|
@@ -21,7 +21,7 @@ export { array, nonEmptyArray, poja, set, tuple } from './lib/arrays';
|
|
|
21
21
|
export { boolean, numericBoolean, truthy } from './lib/booleans';
|
|
22
22
|
export { date, iso8601 } from './lib/dates';
|
|
23
23
|
export { dict, exact, inexact, mapping, object, pojo } from './lib/objects';
|
|
24
|
-
export { either, oneOf, taggedUnion
|
|
24
|
+
export { either, oneOf, taggedUnion } from './lib/unions';
|
|
25
25
|
export {
|
|
26
26
|
email,
|
|
27
27
|
httpsUrl,
|
package/index.mjs
CHANGED
|
@@ -4,7 +4,7 @@ export { array, nonEmptyArray, poja, set, tuple } from './lib/arrays.mjs';
|
|
|
4
4
|
export { boolean, numericBoolean, truthy } from './lib/booleans.mjs';
|
|
5
5
|
export { date, iso8601 } from './lib/dates.mjs';
|
|
6
6
|
export { dict, exact, inexact, mapping, object, pojo } from './lib/objects.mjs';
|
|
7
|
-
export { either, oneOf, taggedUnion
|
|
7
|
+
export { either, oneOf, taggedUnion } from './lib/unions.mjs';
|
|
8
8
|
export { email, httpsUrl, nonEmptyString, regex, string, url, uuid, uuidv1, uuidv4 } from './lib/strings.mjs';
|
|
9
9
|
export { fail, instanceOf, lazy, never, prep } from './lib/utilities.mjs';
|
|
10
10
|
export { anyNumber, integer, number, positiveInteger, positiveNumber } from './lib/numbers.mjs';
|
package/lib/arrays.d.ts
CHANGED
|
@@ -2,11 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
import { Decoder } from '../Decoder';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Accepts any array, but doesn't validate its items further.
|
|
7
|
+
*
|
|
8
|
+
* "poja" means "plain old JavaScript array", a play on `pojo()`.
|
|
9
|
+
*/
|
|
5
10
|
export const poja: Decoder<unknown[]>;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Accepts arrays of whatever the given decoder accepts.
|
|
14
|
+
*/
|
|
6
15
|
export function array<T>(decoder: Decoder<T>): Decoder<T[]>;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Like `array()`, but will reject arrays with 0 elements.
|
|
19
|
+
*/
|
|
7
20
|
export function nonEmptyArray<T>(decoder: Decoder<T>): Decoder<[T, ...T[]]>;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Similar to `array()`, but returns the result as an [ES6
|
|
24
|
+
* Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set).
|
|
25
|
+
*/
|
|
8
26
|
export function set<T>(decoder: Decoder<T>): Decoder<Set<T>>;
|
|
9
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Accepts a tuple (an array with exactly _n_ items) of values accepted by the
|
|
30
|
+
* _n_ given decoders.
|
|
31
|
+
*/
|
|
10
32
|
export function tuple<A>(a: Decoder<A>): Decoder<[A]>;
|
|
11
33
|
export function tuple<A, B>(a: Decoder<A>, b: Decoder<B>): Decoder<[A, B]>;
|
|
12
34
|
export function tuple<A, B, C>(
|
package/lib/arrays.js
CHANGED
|
@@ -101,10 +101,6 @@ var ntuple = function ntuple(n) {
|
|
|
101
101
|
}; // prettier-ignore
|
|
102
102
|
|
|
103
103
|
|
|
104
|
-
/**
|
|
105
|
-
* Accepts a tuple (an array with exactly _n_ items) of values accepted by the
|
|
106
|
-
* _n_ given decoders.
|
|
107
|
-
*/
|
|
108
104
|
function _tuple() {
|
|
109
105
|
for (var _len = arguments.length, decoders = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
110
106
|
decoders[_key] = arguments[_key];
|
|
@@ -133,6 +129,11 @@ function _tuple() {
|
|
|
133
129
|
}
|
|
134
130
|
});
|
|
135
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* Accepts a tuple (an array with exactly _n_ items) of values accepted by the
|
|
134
|
+
* _n_ given decoders.
|
|
135
|
+
*/
|
|
136
|
+
|
|
136
137
|
|
|
137
138
|
var tuple = _tuple;
|
|
138
139
|
exports.tuple = tuple;
|
package/lib/arrays.js.flow
CHANGED
|
@@ -97,7 +97,7 @@ const ntuple = (n: number) =>
|
|
|
97
97
|
poja.refine((arr) => arr.length === n, `Must be a ${n}-tuple`);
|
|
98
98
|
|
|
99
99
|
// prettier-ignore
|
|
100
|
-
interface
|
|
100
|
+
interface TupleT {
|
|
101
101
|
<A>(a: Decoder<A>): Decoder<[A]>;
|
|
102
102
|
<A, B>(a: Decoder<A>, b: Decoder<B>): Decoder<[A, B]>;
|
|
103
103
|
<A, B, C>(a: Decoder<A>, b: Decoder<B>, c: Decoder<C>): Decoder<[A, B, C]>;
|
|
@@ -106,10 +106,6 @@ interface TupleFuncSignature {
|
|
|
106
106
|
<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]>;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
/**
|
|
110
|
-
* Accepts a tuple (an array with exactly _n_ items) of values accepted by the
|
|
111
|
-
* _n_ given decoders.
|
|
112
|
-
*/
|
|
113
109
|
function _tuple(...decoders: $ReadOnlyArray<Decoder<mixed>>): Decoder<Array<mixed>> {
|
|
114
110
|
return ntuple(decoders.length).then((blobs, ok, err) => {
|
|
115
111
|
let allOk = true;
|
|
@@ -135,4 +131,8 @@ function _tuple(...decoders: $ReadOnlyArray<Decoder<mixed>>): Decoder<Array<mixe
|
|
|
135
131
|
});
|
|
136
132
|
}
|
|
137
133
|
|
|
138
|
-
|
|
134
|
+
/**
|
|
135
|
+
* Accepts a tuple (an array with exactly _n_ items) of values accepted by the
|
|
136
|
+
* _n_ given decoders.
|
|
137
|
+
*/
|
|
138
|
+
export const tuple: TupleT = (_tuple: _Any);
|
package/lib/arrays.mjs
CHANGED
|
@@ -87,10 +87,6 @@ var ntuple = function ntuple(n) {
|
|
|
87
87
|
}; // prettier-ignore
|
|
88
88
|
|
|
89
89
|
|
|
90
|
-
/**
|
|
91
|
-
* Accepts a tuple (an array with exactly _n_ items) of values accepted by the
|
|
92
|
-
* _n_ given decoders.
|
|
93
|
-
*/
|
|
94
90
|
function _tuple() {
|
|
95
91
|
for (var _len = arguments.length, decoders = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
96
92
|
decoders[_key] = arguments[_key];
|
|
@@ -119,5 +115,10 @@ function _tuple() {
|
|
|
119
115
|
}
|
|
120
116
|
});
|
|
121
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* Accepts a tuple (an array with exactly _n_ items) of values accepted by the
|
|
120
|
+
* _n_ given decoders.
|
|
121
|
+
*/
|
|
122
|
+
|
|
122
123
|
|
|
123
124
|
export var tuple = _tuple;
|
package/lib/basics.d.ts
CHANGED
|
@@ -1,38 +1,93 @@
|
|
|
1
1
|
import { Decoder, Scalar } from '../Decoder';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Accepts and returns only the literal `null` value.
|
|
5
|
+
*/
|
|
3
6
|
export const null_: Decoder<null>;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Accepts and returns only the literal `undefined` value.
|
|
10
|
+
*/
|
|
4
11
|
export const undefined_: Decoder<undefined>;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Accepts whatever the given decoder accepts, or `undefined`.
|
|
15
|
+
*
|
|
16
|
+
* If a default value is explicitly provided, return that instead in the
|
|
17
|
+
* `undefined` case.
|
|
18
|
+
*/
|
|
5
19
|
export function optional<T>(decoder: Decoder<T>): Decoder<T | undefined>;
|
|
6
20
|
export function optional<T, V extends Scalar>(
|
|
7
21
|
decoder: Decoder<T>,
|
|
8
|
-
defaultValue: V,
|
|
22
|
+
defaultValue: (() => V) | V,
|
|
9
23
|
): Decoder<NonNullable<T> | V>;
|
|
10
24
|
export function optional<T, V>(
|
|
11
25
|
decoder: Decoder<T>,
|
|
12
|
-
defaultValue: V,
|
|
26
|
+
defaultValue: (() => V) | V,
|
|
13
27
|
): Decoder<NonNullable<T> | V>;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Accepts whatever the given decoder accepts, or `null`.
|
|
31
|
+
*
|
|
32
|
+
* If a default value is explicitly provided, return that instead in the `null`
|
|
33
|
+
* case.
|
|
34
|
+
*/
|
|
14
35
|
export function nullable<T>(decoder: Decoder<T>): Decoder<T | null>;
|
|
15
36
|
export function nullable<T, V extends Scalar>(
|
|
16
37
|
decoder: Decoder<T>,
|
|
17
|
-
defaultValue: V,
|
|
38
|
+
defaultValue: (() => V) | V,
|
|
18
39
|
): Decoder<NonNullable<T> | V>;
|
|
19
40
|
export function nullable<T, V>(
|
|
20
41
|
decoder: Decoder<T>,
|
|
21
|
-
defaultValue: V,
|
|
42
|
+
defaultValue: (() => V) | V,
|
|
22
43
|
): Decoder<NonNullable<T> | V>;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Accepts whatever the given decoder accepts, or `null`, or `undefined`.
|
|
47
|
+
*
|
|
48
|
+
* If a default value is explicitly provided, return that instead in the
|
|
49
|
+
* `null`/`undefined` case.
|
|
50
|
+
*/
|
|
23
51
|
export function maybe<T>(decoder: Decoder<T>): Decoder<T | null | undefined>;
|
|
24
52
|
export function maybe<T, V extends Scalar>(
|
|
25
53
|
decoder: Decoder<T>,
|
|
26
|
-
defaultValue: V,
|
|
54
|
+
defaultValue: (() => V) | V,
|
|
27
55
|
): Decoder<NonNullable<T> | V>;
|
|
28
56
|
export function maybe<T, V>(
|
|
29
57
|
decoder: Decoder<T>,
|
|
30
|
-
defaultValue: V,
|
|
58
|
+
defaultValue: (() => V) | V,
|
|
31
59
|
): Decoder<NonNullable<T> | V>;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Accepts only the given constant value.
|
|
63
|
+
*/
|
|
32
64
|
export function constant<T extends Scalar>(value: T): Decoder<T>;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Accepts anything, completely ignores it, and always returns the provided
|
|
68
|
+
* value instead.
|
|
69
|
+
*
|
|
70
|
+
* This is useful to manually add extra fields to object decoders.
|
|
71
|
+
*/
|
|
33
72
|
export function always<T extends Scalar>(value: T): Decoder<T>;
|
|
34
|
-
export function always<T>(value: T): Decoder<T>;
|
|
73
|
+
export function always<T>(value: (() => T) | T): Decoder<T>;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Alias of always.
|
|
77
|
+
*/
|
|
35
78
|
export function hardcoded<T extends Scalar>(value: T): Decoder<T>;
|
|
36
|
-
export function hardcoded<T>(value: T): Decoder<T>;
|
|
37
|
-
|
|
79
|
+
export function hardcoded<T>(value: (() => T) | T): Decoder<T>;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Accepts anything and returns it unchanged.
|
|
83
|
+
*
|
|
84
|
+
* Useful for situation in which you don't know or expect a specific type. Of
|
|
85
|
+
* course, the downside is that you won't know the type of the value statically
|
|
86
|
+
* and you'll have to further refine it yourself.
|
|
87
|
+
*/
|
|
38
88
|
export const unknown: Decoder<unknown>;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Alias of unknown.
|
|
92
|
+
*/
|
|
93
|
+
export const mixed: Decoder<unknown>;
|
package/lib/basics.js
CHANGED
|
@@ -29,22 +29,26 @@ var undefined_or_null = (0, _Decoder.define)(function (blob, ok, err) {
|
|
|
29
29
|
err('Must be undefined or null');
|
|
30
30
|
});
|
|
31
31
|
|
|
32
|
-
/**
|
|
33
|
-
* Accepts whatever the given decoder accepts, or `null`, or `undefined`.
|
|
34
|
-
*/
|
|
35
32
|
function _maybeish(emptyCase) {
|
|
36
33
|
function _inner(decoder
|
|
37
34
|
/* defaultValue */
|
|
38
35
|
) {
|
|
39
|
-
var _arguments = arguments;
|
|
40
36
|
var rv = (0, _unions.either)(emptyCase, decoder);
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
37
|
+
|
|
38
|
+
if ( // If a default value is provided...
|
|
39
|
+
arguments.length >= 2) {
|
|
40
|
+
// ...then return the default value
|
|
41
|
+
var _defaultValue = arguments[1];
|
|
42
|
+
|
|
43
|
+
var _defaultValue2 = typeof _defaultValue === 'function' ? _defaultValue() : _defaultValue;
|
|
44
|
+
|
|
45
|
+
return rv.transform(function (value) {
|
|
46
|
+
return value != null ? value : _defaultValue2;
|
|
47
|
+
});
|
|
48
|
+
} else {
|
|
49
|
+
// Otherwise the "normal" empty case
|
|
50
|
+
return rv;
|
|
51
|
+
}
|
|
48
52
|
}
|
|
49
53
|
|
|
50
54
|
return _inner;
|
|
@@ -101,7 +105,13 @@ function constant(value) {
|
|
|
101
105
|
|
|
102
106
|
|
|
103
107
|
function always(value) {
|
|
104
|
-
return (0, _Decoder.define)(function (blob
|
|
108
|
+
return (0, _Decoder.define)(typeof value === 'function' ? function (blob
|
|
109
|
+
/* ignored */
|
|
110
|
+
, ok, _) {
|
|
111
|
+
return (// $FlowFixMe[incompatible-use]
|
|
112
|
+
ok(value())
|
|
113
|
+
);
|
|
114
|
+
} : function (blob
|
|
105
115
|
/* ignored */
|
|
106
116
|
, ok, _) {
|
|
107
117
|
return ok(value);
|