@colisweb/rescript-toolkit 4.29.3 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +25 -23
- package/{bsconfig.json → rescript.json} +10 -5
- package/src/decoders/Decoders__UnitMeasure.res +251 -0
- package/src/decoders/Toolkit__Decoders.res +118 -412
- package/src/decoders/index.md +5 -5
- package/src/form/Reform.res +18 -18
- package/src/form/Toolkit__Form.res +53 -50
- package/src/hooks/Toolkit__Hooks.res +40 -42
- package/src/hooks/index.md +2 -2
- package/src/identifier/Toolkit__Identifier.res +27 -70
- package/src/identifier/index.md +3 -3
- package/src/intl/Toolkit__Intl.res +1 -1
- package/src/mock/MockOverlay.res +1 -1
- package/src/request/index.md +11 -11
- package/src/router/Toolkit__Router.res +11 -11
- package/src/ui/Toolkit__Ui_Autocomplete.res +2 -2
- package/src/ui/Toolkit__Ui_Button.res +1 -1
- package/src/ui/Toolkit__Ui_ButtonGroup2.res +1 -1
- package/src/ui/Toolkit__Ui_Checkbox.res +1 -1
- package/src/ui/Toolkit__Ui_Coordinates.res +4 -4
- package/src/ui/Toolkit__Ui_DatetimeInput.res +3 -4
- package/src/ui/Toolkit__Ui_Dropdown.res +1 -1
- package/src/ui/Toolkit__Ui_DropdownList.res +1 -1
- package/src/ui/Toolkit__Ui_IconButton.res +5 -5
- package/src/ui/Toolkit__Ui_Layout.res +6 -6
- package/src/ui/Toolkit__Ui_Listbox.res +17 -21
- package/src/ui/Toolkit__Ui_MultiSelect.res +1 -1
- package/src/ui/Toolkit__Ui_MultiSelectWithValidation.res +1 -1
- package/src/ui/Toolkit__Ui_Notice.res +37 -26
- package/src/ui/Toolkit__Ui_Portal.res +1 -1
- package/src/ui/Toolkit__Ui_PortalDropdown.res +8 -6
- package/src/ui/Toolkit__Ui_RadioGroup.res +1 -1
- package/src/ui/Toolkit__Ui_SearchListbox.res +4 -5
- package/src/ui/Toolkit__Ui_SelectWithValidation.res +1 -1
- package/src/ui/Toolkit__Ui_Snackbar.res +2 -2
- package/src/ui/Toolkit__Ui_Switch.res +1 -1
- package/src/ui/Toolkit__Ui_TextInput.res +3 -4
- package/src/ui/Toolkit__Ui_TextareaInput.res +2 -23
- package/src/ui/Toolkit__Ui_Tooltip.res +1 -1
- package/src/ui/Toolkit__Ui_WeekDateFilter.res +1 -1
- package/src/unleash/Toolkit__Unleash.res +6 -6
- package/src/unleash/index.md +1 -1
- package/src/utils/Toolkit__Utils.res +20 -0
- package/src/utils/Toolkit__Utils_UnitMeasure.res +72 -110
- package/src/vendors/Axios.res +2 -2
- package/src/vendors/DatadogRum.res +3 -3
- package/src/vendors/ReactDayPicker.res +4 -4
- package/src/vendors/ReactUse.res +1 -1
- package/src/vendors/Zendesk.res +1 -1
|
@@ -1,437 +1,199 @@
|
|
|
1
|
+
module Option = {
|
|
2
|
+
let encoder = (encoder, value) =>
|
|
3
|
+
switch value {
|
|
4
|
+
| None => %raw("undefined")
|
|
5
|
+
| Some(value) => encoder(value)
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
let decoder = (decoder, json) =>
|
|
9
|
+
json !== %raw("undefined") ? Spice.optionFromJson(decoder, json) : Ok(None)
|
|
10
|
+
|
|
11
|
+
let codec = (encoder, decoder)
|
|
12
|
+
|
|
13
|
+
@spice
|
|
14
|
+
type t<'a> = @spice.codec((encoder, decoder)) option<'a>
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
module Coordinates = {
|
|
18
|
+
@spice
|
|
19
|
+
type t = {
|
|
20
|
+
latitude: float,
|
|
21
|
+
longitude: float,
|
|
22
|
+
}
|
|
23
|
+
let make = (~lat: float, ~lng: float): t => {latitude: lat, longitude: lng}
|
|
24
|
+
let areEquals = (a: t, b: t): bool => a.latitude === b.latitude && a.longitude === b.longitude
|
|
25
|
+
let fromJs = value => {
|
|
26
|
+
latitude: (value->Obj.magic)["lat"](),
|
|
27
|
+
longitude: (value->Obj.magic)["lng"](),
|
|
28
|
+
}
|
|
29
|
+
type gmaps = {
|
|
30
|
+
lat: float,
|
|
31
|
+
lng: float,
|
|
32
|
+
}
|
|
33
|
+
let toGmaps = (t: t): gmaps => {lat: t.latitude, lng: t.longitude}
|
|
34
|
+
let fromGmaps = (gmaps: gmaps) => {
|
|
35
|
+
latitude: gmaps.lat,
|
|
36
|
+
longitude: gmaps.lng,
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
1
40
|
module Datetime = {
|
|
2
41
|
type date = Js.Date.t
|
|
3
42
|
|
|
4
|
-
let encoder:
|
|
43
|
+
let encoder: Spice.encoder<date> = value => value->Js.Date.toISOString->Spice.stringToJson
|
|
5
44
|
|
|
6
|
-
let decoder:
|
|
7
|
-
switch
|
|
45
|
+
let decoder: Spice.decoder<date> = json =>
|
|
46
|
+
switch Spice.stringFromJson(json) {
|
|
8
47
|
| Ok(value) => Ok(value->Js.Date.fromString)
|
|
9
48
|
| Error(_) as error => error
|
|
10
49
|
}
|
|
11
50
|
|
|
12
|
-
let codec:
|
|
51
|
+
let codec: Spice.codec<date> = (encoder, decoder)
|
|
13
52
|
|
|
14
|
-
@
|
|
15
|
-
type t = @
|
|
53
|
+
@spice
|
|
54
|
+
type t = @spice.codec(codec) date
|
|
16
55
|
}
|
|
17
56
|
|
|
18
57
|
module Date = {
|
|
19
58
|
type date = Js.Date.t
|
|
20
59
|
|
|
21
|
-
let encoder:
|
|
22
|
-
date->DateFns.formatWithPattern("yyyy-MM-dd")->
|
|
60
|
+
let encoder: Spice.encoder<date> = date =>
|
|
61
|
+
date->DateFns.formatWithPattern("yyyy-MM-dd")->Spice.stringToJson
|
|
23
62
|
|
|
24
|
-
let decoder:
|
|
25
|
-
switch
|
|
63
|
+
let decoder: Spice.decoder<date> = json =>
|
|
64
|
+
switch Spice.stringFromJson(json) {
|
|
26
65
|
| Ok(v) => Js.Date.fromString(v)->Ok
|
|
27
66
|
| Error(_) as err => err
|
|
28
67
|
}
|
|
29
68
|
|
|
30
|
-
let codec:
|
|
69
|
+
let codec: Spice.codec<date> = (encoder, decoder)
|
|
31
70
|
|
|
32
|
-
@
|
|
33
|
-
type t = @
|
|
71
|
+
@spice
|
|
72
|
+
type t = @spice.codec(codec) date
|
|
34
73
|
}
|
|
35
74
|
|
|
36
|
-
module
|
|
37
|
-
|
|
75
|
+
module DatetimeTimeSlot = {
|
|
76
|
+
@spice
|
|
77
|
+
type t = {
|
|
78
|
+
start: Datetime.t,
|
|
79
|
+
@as("end") @spice.key("end")
|
|
80
|
+
end_: Datetime.t,
|
|
81
|
+
}
|
|
38
82
|
|
|
39
|
-
let
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
| Error(_) as error => error
|
|
45
|
-
}
|
|
46
|
-
| JSONString(_) =>
|
|
47
|
-
switch Decco.stringFromJson(json) {
|
|
48
|
-
| Ok(value) =>
|
|
49
|
-
switch Decco.intFromJson(value->Js.Float.fromString->Js.Json.number) {
|
|
50
|
-
| Ok(_) as value => value
|
|
51
|
-
| Error(_) as error => error
|
|
52
|
-
}
|
|
53
|
-
| Error(_) => Decco.error(~path="", "Not an integer", json)
|
|
54
|
-
}
|
|
55
|
-
| _ => Decco.error(~path="", "Not a number", json)
|
|
56
|
-
}
|
|
83
|
+
let isEqual = (a: t, b: t): bool => {
|
|
84
|
+
a.start->Js.Date.toString === b.start->Js.Date.toString &&
|
|
85
|
+
a.end_->Js.Date.toString === b.end_->Js.Date.toString
|
|
86
|
+
}
|
|
87
|
+
}
|
|
57
88
|
|
|
58
|
-
|
|
89
|
+
module DateTimeSlot = {
|
|
90
|
+
@spice
|
|
91
|
+
type t = {
|
|
92
|
+
start: Date.t,
|
|
93
|
+
@as("end") @spice.key("end")
|
|
94
|
+
end_: Date.t,
|
|
95
|
+
}
|
|
59
96
|
|
|
60
|
-
|
|
61
|
-
|
|
97
|
+
let isEqual = (a: t, b: t): bool => {
|
|
98
|
+
a.start->Js.Date.toString === b.start->Js.Date.toString &&
|
|
99
|
+
a.end_->Js.Date.toString === b.end_->Js.Date.toString
|
|
100
|
+
}
|
|
62
101
|
}
|
|
63
102
|
|
|
64
|
-
module
|
|
65
|
-
let encoder = value => value->
|
|
103
|
+
module Float = {
|
|
104
|
+
let encoder = value => value->Spice.floatToJson
|
|
66
105
|
|
|
67
106
|
let decoder = json =>
|
|
68
107
|
switch Js.Json.classify(json) {
|
|
69
|
-
|
|
|
70
|
-
|
|
108
|
+
| JSONNumber(_) =>
|
|
109
|
+
switch Spice.floatFromJson(json) {
|
|
110
|
+
| Ok(_) as value => value
|
|
111
|
+
| Error(_) as error => error
|
|
112
|
+
}
|
|
71
113
|
| JSONString(_) =>
|
|
72
|
-
switch
|
|
114
|
+
switch Spice.stringFromJson(json) {
|
|
73
115
|
| Ok(value) =>
|
|
74
|
-
switch
|
|
116
|
+
switch Spice.floatFromJson(value->Js.Float.fromString->Js.Json.number) {
|
|
75
117
|
| Ok(_) as value => value
|
|
76
118
|
| Error(_) as error => error
|
|
77
119
|
}
|
|
78
|
-
| Error(_) =>
|
|
120
|
+
| Error(_) => Spice.error(~path="", "Not a number", json)
|
|
79
121
|
}
|
|
80
|
-
| _ =>
|
|
122
|
+
| _ => Spice.error(~path="", "Not a number", json)
|
|
81
123
|
}
|
|
82
124
|
|
|
83
125
|
let codec = (encoder, decoder)
|
|
84
126
|
|
|
85
|
-
@
|
|
86
|
-
type t = @
|
|
127
|
+
@spice
|
|
128
|
+
type t = @spice.codec(codec) float
|
|
87
129
|
}
|
|
88
130
|
|
|
89
|
-
module
|
|
90
|
-
let encoder = value => value->
|
|
131
|
+
module Int = {
|
|
132
|
+
let encoder = value => value->Spice.intToJson
|
|
91
133
|
|
|
92
134
|
let decoder = json =>
|
|
93
135
|
switch Js.Json.classify(json) {
|
|
94
136
|
| JSONNumber(_) =>
|
|
95
|
-
switch
|
|
137
|
+
switch Spice.intFromJson(json) {
|
|
96
138
|
| Ok(_) as value => value
|
|
97
139
|
| Error(_) as error => error
|
|
98
140
|
}
|
|
99
141
|
| JSONString(_) =>
|
|
100
|
-
switch
|
|
142
|
+
switch Spice.stringFromJson(json) {
|
|
101
143
|
| Ok(value) =>
|
|
102
|
-
switch
|
|
144
|
+
switch Spice.intFromJson(value->Js.Float.fromString->Js.Json.number) {
|
|
103
145
|
| Ok(_) as value => value
|
|
104
146
|
| Error(_) as error => error
|
|
105
147
|
}
|
|
106
|
-
| Error(_) =>
|
|
148
|
+
| Error(_) => Spice.error(~path="", "Not an integer", json)
|
|
107
149
|
}
|
|
108
|
-
| _ =>
|
|
150
|
+
| _ => Spice.error(~path="", "Not a number", json)
|
|
109
151
|
}
|
|
110
152
|
|
|
111
153
|
let codec = (encoder, decoder)
|
|
112
154
|
|
|
113
|
-
@
|
|
114
|
-
type t = @
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
module type EnumConfig = {
|
|
118
|
-
type enum
|
|
119
|
-
let enumToJs: enum => string
|
|
120
|
-
let enumFromJs: string => option<enum>
|
|
155
|
+
@spice
|
|
156
|
+
type t = @spice.codec(codec) int
|
|
121
157
|
}
|
|
122
158
|
|
|
123
|
-
module
|
|
124
|
-
|
|
125
|
-
let encoder = value => value->Config.enumToJs->Decco.stringToJson
|
|
159
|
+
module Boolean = {
|
|
160
|
+
let encoder = value => value->Spice.boolToJson
|
|
126
161
|
|
|
127
|
-
|
|
128
|
-
|
|
162
|
+
let decoder = json =>
|
|
163
|
+
switch Js.Json.classify(json) {
|
|
164
|
+
| JSONFalse => Ok(false)
|
|
165
|
+
| JSONTrue => Ok(true)
|
|
166
|
+
| JSONString(_) =>
|
|
167
|
+
switch Spice.stringFromJson(json) {
|
|
129
168
|
| Ok(value) =>
|
|
130
|
-
switch
|
|
131
|
-
|
|
|
132
|
-
|
|
|
169
|
+
switch Spice.boolFromJson(value->bool_of_string->Js.Json.boolean) {
|
|
170
|
+
| Ok(_) as value => value
|
|
171
|
+
| Error(_) as error => error
|
|
133
172
|
}
|
|
134
|
-
| Error(_)
|
|
173
|
+
| Error(_) => Spice.error(~path="", "Not a boolean", json)
|
|
135
174
|
}
|
|
136
|
-
|
|
137
|
-
let codec = (encoder, decoder)
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
let toString = v => v->Config.enumToJs
|
|
141
|
-
let fromString = v => v->Config.enumFromJs
|
|
142
|
-
|
|
143
|
-
@decco
|
|
144
|
-
type t = @decco.codec(codec) Config.enum
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
module Option = {
|
|
148
|
-
let encoder = (encoder, value) =>
|
|
149
|
-
switch value {
|
|
150
|
-
| None => %raw("undefined")
|
|
151
|
-
| Some(value) => encoder(value)
|
|
175
|
+
| _ => Spice.error(~path="", "Not a boolean", json)
|
|
152
176
|
}
|
|
153
177
|
|
|
154
|
-
let decoder = (decoder, json) =>
|
|
155
|
-
json !== %raw("undefined") ? Decco.optionFromJson(decoder, json) : Ok(None)
|
|
156
|
-
|
|
157
178
|
let codec = (encoder, decoder)
|
|
158
179
|
|
|
159
|
-
@
|
|
160
|
-
type t
|
|
180
|
+
@spice
|
|
181
|
+
type t = @spice.codec(codec) bool
|
|
161
182
|
}
|
|
162
183
|
|
|
163
|
-
module UnitMeasure =
|
|
164
|
-
module type MakeConfig = {
|
|
165
|
-
type t
|
|
166
|
-
let toString: t => string
|
|
167
|
-
let toValue: t => float
|
|
168
|
-
let display: (t, ~digits: int=?, unit) => string
|
|
169
|
-
|
|
170
|
-
let wrapValue: float => t
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
module Make = (C: MakeConfig) => {
|
|
174
|
-
type dimension = C.t
|
|
175
|
-
|
|
176
|
-
let encoder: Decco.encoder<C.t> = value => value->C.toString->Decco.stringToJson
|
|
177
|
-
|
|
178
|
-
let decoder: Decco.decoder<C.t> = json =>
|
|
179
|
-
switch Decco.floatFromJson(json) {
|
|
180
|
-
| Ok(v) => v->C.wrapValue->Ok
|
|
181
|
-
| Error(_) as err => err
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
let codec: Decco.codec<dimension> = (encoder, decoder)
|
|
185
|
-
|
|
186
|
-
let toValue = C.toValue
|
|
187
|
-
let display = C.display
|
|
188
|
-
let toString = C.toString
|
|
189
|
-
|
|
190
|
-
@decco
|
|
191
|
-
type t = @decco.codec(codec) C.t
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
module type MakeWithUnitConfig = {
|
|
195
|
-
type t
|
|
196
|
-
let toString: t => string
|
|
197
|
-
let toValue: t => float
|
|
198
|
-
let display: (t, ~digits: int=?, unit) => string
|
|
199
|
-
|
|
200
|
-
type unitEnum
|
|
201
|
-
let unitEnum_decode: Js.Json.t => result<unitEnum, Decco.decodeError>
|
|
202
|
-
let unitEnum_encode: unitEnum => Js.Json.t
|
|
203
|
-
|
|
204
|
-
let wrapValue: (unitEnum, float) => t
|
|
205
|
-
|
|
206
|
-
let errorPrefix: string
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
module MakeWithUnit = (Config: MakeWithUnitConfig) => {
|
|
210
|
-
let decodeFromString = (string: string) => {
|
|
211
|
-
// match a positive int or float followed by it's unit (capturing int/float in group1 and unit in group2)
|
|
212
|
-
let regexp = %re("/^(\d+(?:\.\d*)?)\s*(\D*)$/")
|
|
213
|
-
|
|
214
|
-
// regexpCaptures: [match , captureGroup1, captureGroup2]
|
|
215
|
-
let regexpCaptures =
|
|
216
|
-
Js.Re.exec_(regexp, string)->Belt.Option.map(r =>
|
|
217
|
-
r->Js.Re.captures->Array.map(Js.Nullable.toOption)
|
|
218
|
-
)
|
|
219
|
-
|
|
220
|
-
let jsonString = string->Js.Json.string
|
|
221
|
-
|
|
222
|
-
let errorPrefix = Config.errorPrefix
|
|
223
|
-
|
|
224
|
-
switch regexpCaptures {
|
|
225
|
-
| None => Decco.error(`${errorPrefix} unhandled format`, jsonString)
|
|
226
|
-
| Some([None, _value, _unit]) => Decco.error(`${errorPrefix} unhandled format`, jsonString)
|
|
227
|
-
| Some([_match, _value, None]) => Decco.error(`${errorPrefix} unhandled no unit`, jsonString)
|
|
228
|
-
| Some([_match, None, _unit]) => Decco.error(`${errorPrefix} unhandled no value`, jsonString)
|
|
229
|
-
| Some([Some(_match), Some(value), Some(unit)]) => {
|
|
230
|
-
let value = value->Js.Float.fromString
|
|
231
|
-
switch unit
|
|
232
|
-
// regex captures adjacent to spaces to slashes and deletes them (for composite units)
|
|
233
|
-
->Js.String2.replaceByRe(%re("/ *\/ */"), "/")
|
|
234
|
-
->Js.Json.string
|
|
235
|
-
->Config.unitEnum_decode {
|
|
236
|
-
| Ok(unit) => Config.wrapValue(unit, value)->Ok
|
|
237
|
-
| Error(_) => Decco.error(`${errorPrefix} unhandled unit '${unit}'`, jsonString)
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
| Some(_) => Decco.error(`${errorPrefix} regex capture group error`, jsonString)
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
%%private(
|
|
246
|
-
let encoder: Decco.encoder<Config.t> = value => value->Config.toString->Decco.stringToJson
|
|
247
|
-
let decoder: Decco.decoder<Config.t> = json =>
|
|
248
|
-
switch Decco.stringFromJson(json) {
|
|
249
|
-
| Ok(v) => v->decodeFromString
|
|
250
|
-
| Error(_) as err => err
|
|
251
|
-
}
|
|
252
|
-
let codec: Decco.codec<Config.t> = (encoder, decoder)
|
|
253
|
-
)
|
|
254
|
-
|
|
255
|
-
let toValue = Config.toValue
|
|
256
|
-
let toString = Config.toString
|
|
257
|
-
let display = Config.display
|
|
258
|
-
|
|
259
|
-
@decco
|
|
260
|
-
type t = @decco.codec(codec) Config.t
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
module Dimension = {
|
|
264
|
-
module Config = Toolkit__Utils_UnitMeasure.Dimension
|
|
265
|
-
|
|
266
|
-
module WithUnit = MakeWithUnit({
|
|
267
|
-
include Config
|
|
268
|
-
let errorPrefix = "Dimension with unit"
|
|
269
|
-
})
|
|
270
|
-
|
|
271
|
-
module Mm = Make({
|
|
272
|
-
include Config
|
|
273
|
-
let wrapValue = Config.wrapValue(#mm)
|
|
274
|
-
})
|
|
275
|
-
module Cm = Make({
|
|
276
|
-
include Config
|
|
277
|
-
let wrapValue = Config.wrapValue(#cm)
|
|
278
|
-
})
|
|
279
|
-
module Dm = Make({
|
|
280
|
-
include Config
|
|
281
|
-
let wrapValue = Config.wrapValue(#dm)
|
|
282
|
-
})
|
|
283
|
-
module M = Make({
|
|
284
|
-
include Config
|
|
285
|
-
let wrapValue = Config.wrapValue(#m)
|
|
286
|
-
})
|
|
287
|
-
module Km = Make({
|
|
288
|
-
include Config
|
|
289
|
-
let wrapValue = Config.wrapValue(#km)
|
|
290
|
-
})
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
module Speed = {
|
|
294
|
-
module Config = Toolkit__Utils_UnitMeasure.Speed
|
|
295
|
-
|
|
296
|
-
module WithUnit = MakeWithUnit({
|
|
297
|
-
include Config
|
|
298
|
-
let errorPrefix = "Speed with unit"
|
|
299
|
-
})
|
|
300
|
-
|
|
301
|
-
module Km_h = Make({
|
|
302
|
-
include Config
|
|
303
|
-
let wrapValue = Config.wrapValue(#km_h)
|
|
304
|
-
})
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
module Volume = {
|
|
308
|
-
module Config = Toolkit__Utils_UnitMeasure.Volume
|
|
309
|
-
|
|
310
|
-
module WithUnit = MakeWithUnit({
|
|
311
|
-
include Config
|
|
312
|
-
let errorPrefix = "Volume with unit"
|
|
313
|
-
})
|
|
314
|
-
|
|
315
|
-
module M3 = Make({
|
|
316
|
-
include Config
|
|
317
|
-
let wrapValue = Config.wrapValue(#m3)
|
|
318
|
-
})
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
module EnergyCapacity = {
|
|
322
|
-
module Config = Toolkit__Utils_UnitMeasure.EnergyCapacity
|
|
323
|
-
|
|
324
|
-
module WithUnit = MakeWithUnit({
|
|
325
|
-
include Config
|
|
326
|
-
let errorPrefix = "EnergyCapacity with unit"
|
|
327
|
-
})
|
|
328
|
-
|
|
329
|
-
module KWh = Make({
|
|
330
|
-
include Config
|
|
331
|
-
let wrapValue = Config.wrapValue(#kWh)
|
|
332
|
-
})
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
module Weight = {
|
|
336
|
-
module Config = Toolkit__Utils_UnitMeasure.Weight
|
|
337
|
-
|
|
338
|
-
module WithUnit = MakeWithUnit({
|
|
339
|
-
include Config
|
|
340
|
-
let errorPrefix = "Weight with unit"
|
|
341
|
-
})
|
|
342
|
-
|
|
343
|
-
module G = Make({
|
|
344
|
-
include Config
|
|
345
|
-
let wrapValue = Config.wrapValue(#g)
|
|
346
|
-
})
|
|
347
|
-
module Kg = Make({
|
|
348
|
-
include Config
|
|
349
|
-
let wrapValue = Config.wrapValue(#kg)
|
|
350
|
-
})
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
module Time = {
|
|
354
|
-
module Config = Toolkit__Utils_UnitMeasure.Time
|
|
355
|
-
|
|
356
|
-
module WithUnit = MakeWithUnit({
|
|
357
|
-
include Config
|
|
358
|
-
let errorPrefix = "Time with unit"
|
|
359
|
-
})
|
|
360
|
-
|
|
361
|
-
module S = Make({
|
|
362
|
-
include Config
|
|
363
|
-
let wrapValue = Config.wrapValue(#s)
|
|
364
|
-
})
|
|
365
|
-
module Min = Make({
|
|
366
|
-
include Config
|
|
367
|
-
let wrapValue = Config.wrapValue(#min)
|
|
368
|
-
})
|
|
369
|
-
module H = Make({
|
|
370
|
-
include Config
|
|
371
|
-
let wrapValue = Config.wrapValue(#h)
|
|
372
|
-
})
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
module Currency = {
|
|
376
|
-
module Config = Toolkit__Utils_UnitMeasure.Currency
|
|
377
|
-
|
|
378
|
-
module WithUnit = MakeWithUnit({
|
|
379
|
-
include Config
|
|
380
|
-
let errorPrefix = "Curency with unit"
|
|
381
|
-
})
|
|
382
|
-
|
|
383
|
-
module EUR = Make({
|
|
384
|
-
include Config
|
|
385
|
-
let wrapValue = Config.wrapValue(#EUR)
|
|
386
|
-
})
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
module CompositeUnits = {
|
|
390
|
-
module CurrencyPerDistance = {
|
|
391
|
-
module Config = Toolkit__Utils_UnitMeasure.CompositeUnits.CurrencyPerDistance
|
|
392
|
-
|
|
393
|
-
module WithUnit = MakeWithUnit({
|
|
394
|
-
include Config
|
|
395
|
-
let errorPrefix = "Curency per distance with unit"
|
|
396
|
-
})
|
|
397
|
-
|
|
398
|
-
module EUR_km = Make({
|
|
399
|
-
include Config
|
|
400
|
-
let wrapValue = Config.wrapValue(#EUR_km)
|
|
401
|
-
})
|
|
402
|
-
}
|
|
403
|
-
module CurrencyPerTime = {
|
|
404
|
-
module Config = Toolkit__Utils_UnitMeasure.CompositeUnits.CurrencyPerTime
|
|
405
|
-
|
|
406
|
-
module WithUnit = MakeWithUnit({
|
|
407
|
-
include Config
|
|
408
|
-
let errorPrefix = "Curency per time with unit"
|
|
409
|
-
})
|
|
410
|
-
|
|
411
|
-
module EUR_h = Make({
|
|
412
|
-
include Config
|
|
413
|
-
let wrapValue = Config.wrapValue(#EUR_h)
|
|
414
|
-
})
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
// StringArray
|
|
420
|
-
// This coddec is intended for encoding the array params of API requests of scala services
|
|
421
|
-
// Ex decode: Js.Json.string("1 cm,40 m,3 km") => [|`cm(1),`m(40),`km(3)|]: array(Toolkit.Utils.UnitMeasure.Dimension.t)
|
|
422
|
-
// Ex encode: [|`cm(1.),`m(40.),`km(3.)|] => "1.00 cm,40.00 m,3.00 km": Js.Json.t
|
|
184
|
+
module UnitMeasure = Decoders__UnitMeasure
|
|
423
185
|
|
|
424
186
|
module StringArray = {
|
|
425
187
|
let encoder = (encoder, value) =>
|
|
426
|
-
value->Array.map(encoder)->Js.Array2.joinWith(",")->
|
|
188
|
+
value->Array.map(encoder)->Js.Array2.joinWith(",")->Spice.stringToJson
|
|
427
189
|
|
|
428
190
|
let decoder = (decoder, json) =>
|
|
429
|
-
switch json->
|
|
191
|
+
switch json->Spice.stringFromJson {
|
|
430
192
|
| Ok(string) =>
|
|
431
193
|
let resultArray = string->Js.String2.split(",")->Array.map(e => e->Js.Json.string->decoder)
|
|
432
194
|
let error = resultArray->Array.getBy(Result.isError)
|
|
433
195
|
switch error {
|
|
434
|
-
| Some(_) =>
|
|
196
|
+
| Some(_) => Spice.error(~path="", "Invalid content", json)
|
|
435
197
|
| None => Ok(resultArray->Array.map(Result.getExn))
|
|
436
198
|
}
|
|
437
199
|
| Error(_) as error => error
|
|
@@ -439,62 +201,6 @@ module StringArray = {
|
|
|
439
201
|
|
|
440
202
|
let codec = (encoder, decoder)
|
|
441
203
|
|
|
442
|
-
@
|
|
443
|
-
type t<'a> = @
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
module SortOrder = Enum({
|
|
447
|
-
@deriving(jsConverter)
|
|
448
|
-
type enum = [#asc | #desc]
|
|
449
|
-
})
|
|
450
|
-
|
|
451
|
-
module Coordinates = {
|
|
452
|
-
@decco
|
|
453
|
-
type t = {
|
|
454
|
-
latitude: float,
|
|
455
|
-
longitude: float,
|
|
456
|
-
}
|
|
457
|
-
let make = (~lat: float, ~lng: float): t => {latitude: lat, longitude: lng}
|
|
458
|
-
let areEquals = (a: t, b: t): bool => a.latitude === b.latitude && a.longitude === b.longitude
|
|
459
|
-
let fromJs = value => {
|
|
460
|
-
latitude: (value->Obj.magic)["lat"](),
|
|
461
|
-
longitude: (value->Obj.magic)["lng"](),
|
|
462
|
-
}
|
|
463
|
-
type gmaps = {
|
|
464
|
-
lat: float,
|
|
465
|
-
lng: float,
|
|
466
|
-
}
|
|
467
|
-
let toGmaps = (t: t): gmaps => {lat: t.latitude, lng: t.longitude}
|
|
468
|
-
let fromGmaps = (gmaps: gmaps) => {
|
|
469
|
-
latitude: gmaps.lat,
|
|
470
|
-
longitude: gmaps.lng,
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
module DatetimeTimeSlot = {
|
|
475
|
-
@decco
|
|
476
|
-
type t = {
|
|
477
|
-
start: Datetime.t,
|
|
478
|
-
@as("end") @decco.key("end")
|
|
479
|
-
end_: Datetime.t,
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
let isEqual = (a: t, b: t): bool => {
|
|
483
|
-
a.start->Js.Date.toString === b.start->Js.Date.toString &&
|
|
484
|
-
a.end_->Js.Date.toString === b.end_->Js.Date.toString
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
module DateTimeSlot = {
|
|
489
|
-
@decco
|
|
490
|
-
type t = {
|
|
491
|
-
start: Date.t,
|
|
492
|
-
@as("end") @decco.key("end")
|
|
493
|
-
end_: Date.t,
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
let isEqual = (a: t, b: t): bool => {
|
|
497
|
-
a.start->Js.Date.toString === b.start->Js.Date.toString &&
|
|
498
|
-
a.end_->Js.Date.toString === b.end_->Js.Date.toString
|
|
499
|
-
}
|
|
204
|
+
@spice
|
|
205
|
+
type t<'a> = @spice.codec((encoder, decoder)) array<'a>
|
|
500
206
|
}
|
package/src/decoders/index.md
CHANGED
|
@@ -19,7 +19,7 @@ module Lift = Toolkit.Decoder.Enum(LiftEnum);
|
|
|
19
19
|
/**
|
|
20
20
|
* Later
|
|
21
21
|
**/
|
|
22
|
-
[@
|
|
22
|
+
[@spice]
|
|
23
23
|
type response = {
|
|
24
24
|
lift: Lift.t
|
|
25
25
|
}
|
|
@@ -28,7 +28,7 @@ type response = {
|
|
|
28
28
|
### Decode a date
|
|
29
29
|
|
|
30
30
|
```rescript
|
|
31
|
-
[@
|
|
31
|
+
[@spice]
|
|
32
32
|
type response = {
|
|
33
33
|
createdAt: Toolkit.Decoder.Date.t
|
|
34
34
|
}
|
|
@@ -44,7 +44,7 @@ There are 2 options :
|
|
|
44
44
|
#### Automatic unit handling
|
|
45
45
|
|
|
46
46
|
```rescript
|
|
47
|
-
[@
|
|
47
|
+
[@spice]
|
|
48
48
|
type response = {
|
|
49
49
|
length: Toolkit.Decoder.UnitMeasure.Dimension.WithUnit.t
|
|
50
50
|
}
|
|
@@ -53,7 +53,7 @@ type response = {
|
|
|
53
53
|
#### Known unit
|
|
54
54
|
|
|
55
55
|
```rescript
|
|
56
|
-
[@
|
|
56
|
+
[@spice]
|
|
57
57
|
type response = {
|
|
58
58
|
weight: Toolkit.Decoder.UnitMeasure.Weight.Kg.t
|
|
59
59
|
}
|
|
@@ -64,7 +64,7 @@ type response = {
|
|
|
64
64
|
This codec is intended for encoding the array params of API requests of scala services.
|
|
65
65
|
|
|
66
66
|
```rescript
|
|
67
|
-
[@
|
|
67
|
+
[@spice]
|
|
68
68
|
type params = {
|
|
69
69
|
lengths: Toolkit.Decoder.StringArray(Toolkit.Decoder.UnitMeasure.Dimension.WithUnit.t)
|
|
70
70
|
};
|