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

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.8
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.960678820e55cp+30
@@ -1,2 +1,2 @@
1
- #Start(1700765549343)
2
- #Done(1700765549343)
1
+ #Start(1702993871083)
2
+ #Done(1702993871083)
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 1702993853375601095 tests/QUnit.ast 2e0ab126f969eb05
3
+ 0 7 1702993853375601095 tests/index.ast 71b3927cad444e4e
4
+ 0 8 1702993853378934529 src/JSON.ast 9351863d7438f8a8
5
+ 6 8 1702993853378934529 tests/QUnit.d 4a2631c992d93ce7
6
+ 7 9 1702993853378934529 tests/index.d 5a4db9cdecd186b3
7
+ 8 10 1702993853378934529 src/JSON.d cd2d6773c781340f
8
+ 8 15 1702993853385601399 tests/QUnit.cmj 1edb54518110233d
9
+ 8 15 1702993853385601399 tests/QUnit.cmi 1edb54518110233d
10
+ 8 15 1702993853385601399 ../es6/tests/QUnit.js 1edb54518110233d
11
+ 8 15 1702993853385601399 ../js/tests/QUnit.js 1edb54518110233d
12
+ 10 28 1702993853398935137 src/JSON.cmj 8c11ebba20f6863e
13
+ 10 28 1702993853398935137 src/JSON.cmi 8c11ebba20f6863e
14
+ 10 28 1702993853398935137 ../es6/src/JSON.js 8c11ebba20f6863e
15
+ 10 28 1702993853398935137 ../js/src/JSON.js 8c11ebba20f6863e
16
+ 28 38 1702993853408935441 tests/index.cmj ef71549c32d73e54
17
+ 28 38 1702993853408935441 tests/index.cmi ef71549c32d73e54
18
+ 28 38 1702993853408935441 ../es6/tests/index.js ef71549c32d73e54
19
+ 28 38 1702993853408935441 ../js/tests/index.js ef71549c32d73e54
@@ -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.8 -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.6",
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.7"
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.8"
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