@kaiko.io/rescript-deser 4.0.0-rc.4 → 4.0.0-rc.5

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/lib/bs/.bsdeps CHANGED
@@ -1,8 +1,8 @@
1
- 11.0.0-rc.6
1
+ 11.0.0-rc.7
2
2
  /home/manu/src/kaiko/rescript-deser
3
3
  0
4
- rescript.json 0x1.94b3a6a1d2ba4p+30
4
+ rescript.json 0x1.95f132e38e01fp+30
5
5
  tests 0x1.93fb8b23e3f01p+30
6
- src/ 0x1.957e56214e505p+30
6
+ src/ 0x1.95f132e38e01fp+30
7
7
  ===
8
- /home/manu/src/kaiko/rescript-deser/node_modules/rescript/linux/rescript.exe 0x1.9578a22fcfdf4p+30
8
+ /home/manu/src/kaiko/rescript-deser/node_modules/rescript/linux/rescript.exe 0x1.95f128136353bp+30
@@ -1,2 +1,2 @@
1
- #Start(1700765549343)
2
- #Done(1700765549343)
1
+ #Start(1702644950015)
2
+ #Done(1702644950052)
package/lib/bs/.ninja_log CHANGED
@@ -1,27 +1,19 @@
1
1
  # ninja log v6
2
- 0 7 1700763106509919117 src/JSON.ast 3df97f11bfe4e9b4
3
- 7 9 1700763106513252576 src/JSON.d 54f2190af6eab30f
4
- 9 26 1700763106529919867 src/JSON.cmj f5326fd4af8f39e2
5
- 9 26 1700763106529919867 src/JSON.cmi f5326fd4af8f39e2
6
- 9 26 1700763106529919867 ../es6/src/JSON.js f5326fd4af8f39e2
7
- 0 16 1700763106513252576 src/JSON.cmj 9477bd76994296b7
8
- 0 16 1700763106513252576 src/JSON.cmi 9477bd76994296b7
9
- 0 16 1700763106513252576 ../es6/src/JSON.js 9477bd76994296b7
10
- 0 6 1700765531805623915 tests/QUnit.ast a6a94a20e20f8557
11
- 1 6 1700765531805623915 tests/index.ast 3c91d8240b8bb4b8
12
- 0 8 1700765531808957333 src/JSON.ast 54dacc9e71f78ec4
13
- 6 8 1700765531808957333 tests/QUnit.d 4a2631c992d93ce7
14
- 6 8 1700765531808957333 tests/index.d 5a4db9cdecd186b3
15
- 8 10 1700765531808957333 src/JSON.d cd2d6773c781340f
16
- 8 15 1700765531815624169 tests/QUnit.cmj e2ba8efce8af03b9
17
- 8 15 1700765531815624169 tests/QUnit.cmi e2ba8efce8af03b9
18
- 8 15 1700765531815624169 ../es6/tests/QUnit.js e2ba8efce8af03b9
19
- 8 15 1700765531815624169 ../js/tests/QUnit.js e2ba8efce8af03b9
20
- 10 28 1700765531828957841 src/JSON.cmj 3da9e5f359841f1a
21
- 10 28 1700765531828957841 src/JSON.cmi 3da9e5f359841f1a
22
- 10 28 1700765531828957841 ../es6/src/JSON.js 3da9e5f359841f1a
23
- 10 28 1700765531828957841 ../js/src/JSON.js 3da9e5f359841f1a
24
- 28 38 1700765531838958094 tests/index.cmj 630554c615a94d8d
25
- 28 38 1700765531838958094 tests/index.cmi 630554c615a94d8d
26
- 28 38 1700765531838958094 ../es6/tests/index.js 630554c615a94d8d
27
- 28 38 1700765531838958094 ../js/tests/index.js 630554c615a94d8d
2
+ 0 6 1702644950019435248 tests/QUnit.ast 7223a540e3832541
3
+ 1 6 1702644950019435248 tests/index.ast c5f8a64ed4e3d886
4
+ 0 7 1702644950019435248 src/JSON.ast e5463df0847655c1
5
+ 6 8 1702644950022768668 tests/QUnit.d 4a2631c992d93ce7
6
+ 6 9 1702644950022768668 tests/index.d 5a4db9cdecd186b3
7
+ 8 10 1702644950022768668 src/JSON.d cd2d6773c781340f
8
+ 9 15 1702644950029435508 tests/QUnit.cmj 2795770c04d7b464
9
+ 9 15 1702644950029435508 tests/QUnit.cmi 2795770c04d7b464
10
+ 9 15 1702644950029435508 ../es6/tests/QUnit.js 2795770c04d7b464
11
+ 9 15 1702644950029435508 ../js/tests/QUnit.js 2795770c04d7b464
12
+ 10 27 1702644950039435767 src/JSON.cmj 7dad91a190b50ccb
13
+ 10 27 1702644950039435767 src/JSON.cmi 7dad91a190b50ccb
14
+ 10 27 1702644950039435767 ../es6/src/JSON.js 7dad91a190b50ccb
15
+ 10 27 1702644950039435767 ../js/src/JSON.js 7dad91a190b50ccb
16
+ 27 37 1702644950049436026 tests/index.cmj df4ef497c56ee724
17
+ 27 37 1702644950049436026 tests/index.cmi df4ef497c56ee724
18
+ 27 37 1702644950049436026 ../es6/tests/index.js df4ef497c56ee724
19
+ 27 37 1702644950049436026 ../js/tests/index.js df4ef497c56ee724
@@ -1,7 +1,7 @@
1
1
  rescript = 1
2
2
  g_finger := /home/manu/src/kaiko/rescript-deser/node_modules/@kaiko.io/rescript-prelude/lib/ocaml/install.stamp
3
3
  rule astj
4
- command = /home/manu/src/kaiko/rescript-deser/node_modules/rescript/linux/bsc.exe -warn-error +8+11+26+27+33+56 -bs-v 11.0.0-rc.6 -uncurried -absname -bs-ast -o $out $i
4
+ command = /home/manu/src/kaiko/rescript-deser/node_modules/rescript/linux/bsc.exe -warn-error +8+11+26+27+33+56 -bs-v 11.0.0-rc.7 -uncurried -absname -bs-ast -o $out $i
5
5
  o tests/index.ast : astj ../../tests/index.res
6
6
  rule deps_dev
7
7
  command = /home/manu/src/kaiko/rescript-deser/node_modules/rescript/linux/bsb_helper.exe -g -hash 84aecc33f8594375b23a1a137b057f93 $in
Binary file
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaiko.io/rescript-deser",
3
- "version": "4.0.0-rc.4",
3
+ "version": "4.0.0-rc.5",
4
4
  "keywords": [
5
5
  "json",
6
6
  "deserializer",
@@ -20,11 +20,11 @@
20
20
  "README.md"
21
21
  ],
22
22
  "dependencies": {
23
- "@kaiko.io/rescript-prelude": "7.0.0-rc.4"
23
+ "@kaiko.io/rescript-prelude": "7.0.0-rc.6"
24
24
  },
25
25
  "devDependencies": {
26
26
  "esbuild": "^0.15.7",
27
27
  "qunit": "^2.16.0",
28
- "rescript": "11.0.0-rc.6"
28
+ "rescript": "11.0.0-rc.7"
29
29
  }
30
30
  }
@@ -1,2 +0,0 @@
1
- #Start(1700763494807)
2
- #Done(1700763494809)
@@ -1,7 +0,0 @@
1
- # ninja log v6
2
- 0 3 1700763106533253326 JSON.cmi bafb789a597a23fb
3
- 0 3 1700763106533253326 JSON.cmj e0df0c7e15c09f8e
4
- 0 3 1700763106533253326 JSON.cmt cb51be205f02087e
5
- 1 3 1700763106533253326 JSON.res b4c17270ea3dc72d
6
- 3 4 1700763106536586783 install.stamp cff5a5b4c02d30cf
7
- 0 2 1700763494803628812 JSON.cmt cb51be205f02087e
Binary file
Binary file
Binary file
@@ -1,343 +0,0 @@
1
- @@uncurried
2
- open Prelude
3
-
4
- module FieldValue = {
5
- type t
6
- external string: string => t = "%identity"
7
- external int: int => t = "%identity"
8
- external float: float => t = "%identity"
9
- external boolean: bool => t = "%identity"
10
- external array: array<t> => t = "%identity"
11
- external object: Dict.t<t> => t = "%identity"
12
- external mapping: Dict.t<t> => t = "%identity"
13
- external any: 'a => t = "%identity"
14
- @val external null: t = "undefined"
15
-
16
- external asString: t => string = "%identity"
17
- external asInt: t => int = "%identity"
18
- external asFloat: t => float = "%identity"
19
- external asBoolean: t => bool = "%identity"
20
- external asArray: t => array<'a> = "%identity"
21
- external asObject: t => 'a = "%identity"
22
- }
23
-
24
- exception TypeError(string)
25
-
26
- @doc("The module type of a built deserializer which is suitable to add as a subparser.")
27
- module type Deserializer = {
28
- type t
29
- let name: string
30
- let fromJSON: Js.Json.t => result<t, string>
31
- let checkFieldsSanity: unit => result<unit, string>
32
- }
33
-
34
- module Field = {
35
- type rec t =
36
- | Any
37
- | String
38
- | Literal(string)
39
- | Int
40
- | Float
41
- | Boolean
42
- | Array(t)
43
- /// These SHOULD strings in ISO format, but we only validate the string
44
- /// can be represented in Js.Date without spewing NaN all over the place;
45
- /// Js.Date.fromString("xxx") returns an object that is mostly unusable.
46
- ///
47
- /// We also allow floats and then use Js.Date.fromFloat.
48
- | Date
49
- | Datetime // alias of Date
50
-
51
- | Tuple(array<t>)
52
- | Object(array<(string, t)>)
53
- | Optional(t)
54
- | OptionalWithDefault(t, FieldValue.t)
55
- /// An arbitrary mapping from names to other arbitrary fields. The
56
- /// difference with Object, is that you don't know the names of the
57
- /// expected entries.
58
- | Mapping(t)
59
-
60
- | Deserializer(module(Deserializer))
61
-
62
- /// A specialized Array of deserialized items that ignores unparsable
63
- /// items and returns the valid collection. This saves the user from
64
- /// writing 'Array(DefaultWhenInvalid(Optional(Deserializer(module(M)))))'
65
- /// and then post-process the list of items with 'Array.keepSome'
66
- | Collection(module(Deserializer))
67
- | DefaultWhenInvalid(t, FieldValue.t)
68
-
69
- // FIXME: this is used to add additional restrictions like variadictInt or
70
- // variadicString; but I find it too type-unsafe. I might consider having
71
- // a Constraints for this in the future.
72
- | Morphism(t, FieldValue.t => FieldValue.t)
73
-
74
- | Self
75
-
76
- let usingString = (f: string => 'a) => value => value->FieldValue.asString->f->FieldValue.any
77
- let usingInt = (f: int => 'a) => value => value->FieldValue.asInt->f->FieldValue.any
78
- let usingFloat = (f: float => 'a) => value => value->FieldValue.asFloat->f->FieldValue.any
79
- let usingBoolean = (f: bool => 'a) => value => value->FieldValue.asBoolean->f->FieldValue.any
80
- let usingArray = (f: array<'a> => 'b) => value => value->FieldValue.asArray->f->FieldValue.any
81
- let usingObject = (f: 'a => 'b) => value => value->FieldValue.asObject->f->FieldValue.any
82
-
83
- let variadicInt = (hint: string, fromJs: int => option<'variadicType>) => Morphism(
84
- Int,
85
- usingInt(i => {
86
- switch i->fromJs {
87
- | Some(internalValue) => internalValue
88
- | None =>
89
- raise(TypeError(`This Int(${i->Int.toString}) not a valid value here. Hint: ${hint}`))
90
- }
91
- }),
92
- )
93
- let variadicString = (hint: string, fromJs: string => option<'variadicType>) => Morphism(
94
- String,
95
- usingString(i => {
96
- switch i->fromJs {
97
- | Some(internalValue) => internalValue
98
- | None => raise(TypeError(`This String("${i}") not a valid value here. Hint: ${hint}`))
99
- }
100
- }),
101
- )
102
-
103
- let rec toString = (type_: t) =>
104
- switch type_ {
105
- | Any => "Any"
106
- | String => "String"
107
- | Literal(lit) => `Literal: ${lit}`
108
- | Int => "Integer"
109
- | Float => "Float"
110
- | Boolean => "Boolean"
111
- | Datetime
112
- | Date => "Date"
113
- | Self => "Self (recursive)"
114
- | Collection(m) => {
115
- module M = unpack(m: Deserializer)
116
- "Collection of " ++ M.name
117
- }
118
-
119
- | Array(t) => "Array of " ++ t->toString
120
- | Tuple(bases) => `Tuple of (${bases->Array.map(toString)->Array.join(", ")})`
121
- | Object(fields) => {
122
- let desc = fields->Array.map(((field, t)) => `${field}: ${t->toString}`)->Array.join(", ")
123
- `Object of {${desc}}`
124
- }
125
-
126
- | OptionalWithDefault(t, _)
127
- | Optional(t) =>
128
- "Null of " ++ t->toString
129
- | Mapping(t) => `Mapping of ${t->toString}`
130
- | Morphism(t, _) => t->toString ++ " to apply a morphism"
131
- | Deserializer(m) => {
132
- module M = unpack(m: Deserializer)
133
- M.name
134
- }
135
-
136
- | DefaultWhenInvalid(t, _) => `Protected ${t->toString}`
137
- }
138
-
139
- let _taggedToString = (tagged: Js.Json.tagged_t) => {
140
- switch tagged {
141
- | Js.Json.JSONFalse => "Boolean(false)"
142
- | Js.Json.JSONTrue => "Boolean(true)"
143
- | Js.Json.JSONNull => "Null"
144
- | Js.Json.JSONString(text) => `String("${text}")`
145
- | Js.Json.JSONNumber(number) => `Number(${number->Float.toString})`
146
- | Js.Json.JSONObject(obj) => `Object(${obj->Js.Json.stringifyAny->default("...")})`
147
- | Js.Json.JSONArray(array) => `Array(${array->Js.Json.stringifyAny->default("...")})`
148
- }
149
- }
150
-
151
- let rec extractValue = (
152
- values: Dict.t<Js.Json.t>,
153
- field: string,
154
- shape: t,
155
- self: t,
156
- ): FieldValue.t => {
157
- switch values->Dict.get(field) {
158
- | Some(value) => value->fromUntagged(shape, self)
159
- | None =>
160
- switch shape {
161
- | DefaultWhenInvalid(_, _) => Js.Json.null->fromUntagged(shape, self)
162
- | Optional(_) => Js.Json.null->fromUntagged(shape, self)
163
- | OptionalWithDefault(_, default) => default
164
- | _ => raise(TypeError(`Missing non-optional field '${field}'`))
165
- }
166
- }
167
- }
168
- and fromUntagged = (untagged: Js.Json.t, shape: t, self: t): FieldValue.t => {
169
- switch (shape, untagged->Js.Json.classify) {
170
- | (Any, _) => untagged->FieldValue.any
171
- | (Literal(expected), Js.Json.JSONString(text)) =>
172
- if text == expected {
173
- FieldValue.string(text)
174
- } else {
175
- raise(TypeError(`Expecting literal ${expected}, got ${text}`))
176
- }
177
- | (String, Js.Json.JSONString(text)) => FieldValue.string(text)
178
- | (Int, Js.Json.JSONNumber(number)) => FieldValue.int(number->Float.toInt)
179
- | (Float, Js.Json.JSONNumber(number)) => FieldValue.float(number)
180
- | (Boolean, Js.Json.JSONTrue) => FieldValue.boolean(true)
181
- | (Boolean, Js.Json.JSONFalse) => FieldValue.boolean(false)
182
- | (Tuple(bases), Js.Json.JSONArray(items)) => {
183
- let lenbases = bases->Array.length
184
- let lenitems = items->Array.length
185
- if lenbases == lenitems {
186
- let values = Array.zipBy(items, bases, (i, b) => fromUntagged(i, b, self))
187
- values->FieldValue.array
188
- } else {
189
- raise(
190
- TypeError(`Expecting ${lenbases->Int.toString} items, got ${lenitems->Int.toString}`),
191
- )
192
- }
193
- }
194
-
195
- | (Datetime, Js.Json.JSONString(s))
196
- | (Date, Js.Json.JSONString(s)) => {
197
- let r = Js.Date.fromString(s)
198
- if r->Js.Date.getDate->Js.Float.isNaN {
199
- raise(TypeError(`Invalid date ${s}`))
200
- }
201
- r->FieldValue.any
202
- }
203
-
204
- | (Datetime, Js.Json.JSONNumber(f))
205
- | (Date, Js.Json.JSONNumber(f)) => {
206
- let r = Js.Date.fromFloat(f)
207
- if r->Js.Date.getDate->Js.Float.isNaN {
208
- raise(TypeError(`Invalid date ${f->Js.Float.toString}`))
209
- }
210
- r->FieldValue.any
211
- }
212
-
213
- | (Array(shape), Js.Json.JSONArray(items)) =>
214
- FieldValue.array(items->Array.map(item => item->fromUntagged(shape, self)))
215
- | (Mapping(f), Js.Json.JSONObject(values)) =>
216
- values->Dict.mapValues(v => v->fromUntagged(f, self))->FieldValue.mapping
217
- | (Object(fields), Js.Json.JSONObject(values)) =>
218
- FieldValue.object(
219
- fields
220
- ->Array.map(((field, shape)) => {
221
- let value = switch extractValue(values, field, shape, self) {
222
- | value => value
223
- | exception TypeError(msg) => raise(TypeError(`Field "${field}": ${msg}`))
224
- }
225
- (field, value)
226
- })
227
- ->Dict.fromArray,
228
- )
229
-
230
- | (OptionalWithDefault(_, value), Js.Json.JSONNull) => value
231
- | (OptionalWithDefault(shape, _), _) => untagged->fromUntagged(shape, self)
232
- | (Optional(_), Js.Json.JSONNull) => FieldValue.null
233
- | (Optional(shape), _) => untagged->fromUntagged(shape, self)
234
- | (Morphism(shape, f), _) => untagged->fromUntagged(shape, self)->f->FieldValue.any
235
-
236
- | (Collection(m), Js.Json.JSONArray(items)) => {
237
- module M = unpack(m: Deserializer)
238
- items
239
- ->Array.map(M.fromJSON)
240
- ->Array.map(Result.warn)
241
- ->Array.keepSome
242
- ->Array.map(FieldValue.any)
243
- ->FieldValue.array
244
- }
245
-
246
- | (Deserializer(m), _) => {
247
- module M = unpack(m: Deserializer)
248
- switch untagged->M.fromJSON {
249
- | Ok(res) => res->FieldValue.any
250
- | Error(msg) => raise(TypeError(msg))
251
- }
252
- }
253
-
254
- | (DefaultWhenInvalid(t, default), _) =>
255
- switch untagged->fromUntagged(t, self) {
256
- | res => res
257
- | exception TypeError(msg) => {
258
- Js.Console.warn2("Detected and ignore (with default): ", msg)
259
- default
260
- }
261
- }
262
- | (Self, _) => untagged->fromUntagged(self, self)
263
- | (expected, actual) =>
264
- raise(TypeError(`Expected ${expected->toString}, but got ${actual->_taggedToString} instead`))
265
- }
266
- }
267
-
268
- let rec checkFieldsSanity = (name: string, fields: t, optional: bool): result<unit, string> =>
269
- switch (fields, optional) {
270
- | (Self, false) => Error(`${name}: Trivial infinite recursion 'let fields = Self'`)
271
- | (Self, true) => Ok()
272
-
273
- | (Any, _) => Ok()
274
- | (String, _) | (Float, _) | (Int, _) | (Literal(_), _) => Ok()
275
- | (Boolean, _) | (Date, _) | (Datetime, _) => Ok()
276
- | (Morphism(_, _), _) => Ok()
277
-
278
- | (Collection(mod), _)
279
- | (Deserializer(mod), _) => {
280
- module M = unpack(mod: Deserializer)
281
- switch M.checkFieldsSanity() {
282
- | Ok() => Ok()
283
- | Error(msg) => Error(`${name}/ ${msg}`)
284
- }
285
- }
286
-
287
- | (DefaultWhenInvalid(fields, _), _)
288
- | (OptionalWithDefault(fields, _), _)
289
- | (Optional(fields), _) =>
290
- checkFieldsSanity(name, fields, true)
291
-
292
- | (Object(fields), optional) =>
293
- fields
294
- ->Array.map(((fieldName, field)) => () =>
295
- checkFieldsSanity(`${name}::${fieldName}`, field, optional))
296
- ->ManyResults.bailU
297
- ->ManyResults.map(_ => ())
298
-
299
- /// Mappings and arrays can be empty, so their payloads are
300
- /// automatically optional.
301
- | (Mapping(field), _) | (Array(field), _) => checkFieldsSanity(name, field, true)
302
-
303
- | (Tuple(fields), optional) =>
304
- fields
305
- ->Array.mapWithIndex((field, index) => () =>
306
- checkFieldsSanity(`${name}[${index->Int.toString}]`, field, optional))
307
- ->ManyResults.bailU
308
- ->ManyResults.map(_ => ())
309
- }
310
- }
311
-
312
- module type Serializable = {
313
- type t
314
- let fields: Field.t
315
- }
316
-
317
- module MakeDeserializer = (S: Serializable): (Deserializer with type t = S.t) => {
318
- type t = S.t
319
- let fields = S.fields
320
- %%private(let (loc, _f) = __LOC_OF__(module(S: Serializable)))
321
- let name = `Deserializer ${__MODULE__}, ${loc}`
322
-
323
- %%private(external _toNativeType: FieldValue.t => t = "%identity")
324
-
325
- @doc("Checks for trivial infinite-recursion in the fields of the module.
326
-
327
- Notice this algorithm is just an heuristic, and it might happen that are
328
- cases of infinite-recursion not detected and cases where detection is a
329
- false positive.
330
-
331
- You should use this only while debugging/developing to verify your data.
332
-
333
- ")
334
- let checkFieldsSanity = () => Field.checkFieldsSanity(name, fields, false)
335
-
336
- @doc("Parse a `Js.Json.t` into `result<t, string>`")
337
- let fromJSON = (json: Js.Json.t): result<t, _> => {
338
- switch json->Field.fromUntagged(fields, fields) {
339
- | res => Ok(res->_toNativeType)
340
- | exception TypeError(e) => Error(e)
341
- }
342
- }
343
- }
File without changes