@colisweb/rescript-toolkit 5.3.4 → 5.4.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@colisweb/rescript-toolkit",
3
- "version": "5.3.4",
3
+ "version": "5.4.0",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "clean": "rescript clean",
@@ -11,14 +11,15 @@ type childFieldError = {
11
11
  name: string,
12
12
  }
13
13
 
14
- type fieldState =
14
+ type rec fieldState<'a> =
15
15
  | Valid
16
16
  | NestedErrors(array<childFieldError>)
17
+ | NestedErrors2(array<array<('a, fieldState<'a>)>>)
17
18
  | Error(string)
18
19
 
19
20
  type recordValidationState<'a> =
20
21
  | Valid
21
- | Errors(array<('a, fieldState)>)
22
+ | Errors(array<('a, fieldState<'a>)>)
22
23
 
23
24
  module Make = (Lenses: Lenses) => {
24
25
  type rec field = Field(Lenses.field<'a>): field
@@ -35,11 +36,15 @@ module Make = (Lenses: Lenses) => {
35
36
  | IntMax({field: Lenses.field<int>, max: int, error: option<string>}): t
36
37
  | FloatMin({field: Lenses.field<float>, min: float, error: option<string>}): t
37
38
  | FloatMax({field: Lenses.field<float>, max: float, error: option<string>}): t
38
- | Custom({field: Lenses.field<'a>, predicate: Lenses.state => fieldState}): t
39
+ | Custom({field: Lenses.field<'a>, predicate: Lenses.state => fieldState<field>}): t
39
40
  | CustomNestedSchema({
40
41
  field: Lenses.field<'a>,
41
42
  predicate: Lenses.state => array<(int, recordValidationState<'a>)>,
42
43
  }): t
44
+ | CustomNestedSchema2({
45
+ field: Lenses.field<'a>,
46
+ predicate: Lenses.state => array<array<(field, fieldState<field>)>>,
47
+ }): t
43
48
  | True({field: Lenses.field<bool>, error: option<string>}): t
44
49
  | False({field: Lenses.field<bool>, error: option<string>}): t
45
50
  | OptionNonEmpty({field: Lenses.field<option<'a>>, error: option<string>}): t
@@ -63,6 +68,9 @@ module Make = (Lenses: Lenses) => {
63
68
  let customNestedSchema = (field, predicate) => {
64
69
  [CustomNestedSchema({field, predicate})]
65
70
  }
71
+ let customNestedSchema2 = (field, predicate) => {
72
+ [CustomNestedSchema2({field, predicate})]
73
+ }
66
74
 
67
75
  let optionNonEmpty = (~error=?, field) => [OptionNonEmpty({field, error})]
68
76
 
@@ -142,7 +150,7 @@ module Make = (Lenses: Lenses) => {
142
150
  }
143
151
  }
144
152
 
145
- let validateField = (~validator, ~values, ~i18n: ReSchemaI18n.t): (field, fieldState) =>
153
+ let validateField = (~validator, ~values, ~i18n: ReSchemaI18n.t): (field, fieldState<field>) =>
146
154
  switch validator {
147
155
  | Validation.True({field, error}) =>
148
156
  let value = Lenses.get(values, field)
@@ -251,6 +259,11 @@ module Make = (Lenses: Lenses) => {
251
259
 
252
260
  (Field(field)->Obj.magic, errors->Array.length > 0 ? NestedErrors(errors) : Valid)
253
261
  }
262
+ | Validation.CustomNestedSchema2({field, predicate}) => {
263
+ let results = predicate(values)
264
+
265
+ (Field(field), NestedErrors2(results))
266
+ }
254
267
  | Validation.OptionNonEmpty({field, error}) => {
255
268
  let value = Lenses.get(values, field)
256
269
 
@@ -292,6 +305,7 @@ module Make = (Lenses: Lenses) => {
292
305
  | Validation.CustomNestedSchema({field}) => Field(field) == fieldName
293
306
  | Validation.OptionNonEmpty({field}) => Field(field) == fieldName
294
307
  | Validation.ArrayNonEmpty({field}) => Field(field) == fieldName
308
+ | Validation.CustomNestedSchema2({field}) => Field(field) == fieldName
295
309
  }
296
310
  )
297
311
 
@@ -312,6 +326,7 @@ module Make = (Lenses: Lenses) => {
312
326
  | Validation.StringMax({field}) => Field(field) == fieldName
313
327
  | Validation.Custom({field}) => Field(field) == fieldName
314
328
  | Validation.CustomNestedSchema({field}) => Field(field) == fieldName
329
+ | Validation.CustomNestedSchema2({field}) => Field(field) == fieldName
315
330
  | Validation.OptionNonEmpty({field}) => Field(field) == fieldName
316
331
  | Validation.ArrayNonEmpty({field}) => Field(field) == fieldName
317
332
  }
@@ -333,7 +348,12 @@ module Make = (Lenses: Lenses) => {
333
348
  })
334
349
  }
335
350
 
336
- let validateFields = (~fields, ~values, ~i18n, schema: Validation.schema) => {
351
+ let validateFields = (
352
+ ~fields,
353
+ ~values,
354
+ ~i18n=ReSchemaI18n.default,
355
+ schema: Validation.schema,
356
+ ) => {
337
357
  Belt.Array.map(fields, field =>
338
358
  getFieldValidator(~validators=schema, ~fieldName=field)->Belt.Option.map(validator =>
339
359
  validateField(~validator, ~values, ~i18n)
@@ -349,10 +369,40 @@ module Make = (Lenses: Lenses) => {
349
369
  switch fieldState {
350
370
  | Error(_) as e => Some((field, e))
351
371
  | NestedErrors(_) as e => Some((field, e))
372
+ | NestedErrors2(nestedErrors2) as e =>
373
+ {
374
+ let rec getIsErrored = nestedErrors2 =>
375
+ nestedErrors2->Array.some(form => {
376
+ form->Array.some(
377
+ ((_, fieldState)) => {
378
+ switch fieldState {
379
+ | Error(_)
380
+ | NestedErrors(_) => true
381
+ | NestedErrors2(nextLevel) => getIsErrored(nextLevel)
382
+ | _ => false
383
+ }
384
+ },
385
+ )
386
+ })
387
+ getIsErrored(nestedErrors2)
388
+ }
389
+ ? Some((field, e))
390
+ : None
352
391
  | _ => None
353
392
  }
354
393
  )
355
394
 
356
395
  Belt.Array.length(errors) > 0 ? Errors(errors) : Valid
357
396
  }
397
+
398
+ let validateAndReturn = (
399
+ ~i18n=ReSchemaI18n.default,
400
+ values: Lenses.state,
401
+ schema: Validation.schema,
402
+ ) => {
403
+ let validationList =
404
+ schema->Belt.Array.map(validator => validateField(~validator, ~values, ~i18n))
405
+
406
+ validationList
407
+ }
358
408
  }
@@ -6,13 +6,6 @@ module type Config = {
6
6
  type error
7
7
  }
8
8
 
9
- type childFieldError = ReSchema.childFieldError
10
-
11
- type fieldState =
12
- | Pristine
13
- | Valid
14
- | NestedErrors(array<ReSchema.childFieldError>)
15
- | Error(string)
16
9
  type formState<'error> =
17
10
  | Pristine
18
11
  | Dirty
@@ -22,6 +15,8 @@ type formState<'error> =
22
15
  | SubmitFailed(option<'error>)
23
16
  | SubmitSucceed
24
17
 
18
+ type childFieldError = ReSchema.childFieldError
19
+
25
20
  module Make = (Config: Config) => {
26
21
  module ReSchema = ReSchema.Make(Config)
27
22
  module Validation = ReSchema.Validation
@@ -29,6 +24,15 @@ module Make = (Config: Config) => {
29
24
  type field = ReSchema.field
30
25
  type formState = formState<Config.error>
31
26
 
27
+ type rec fieldState =
28
+ | Pristine
29
+ | Valid
30
+ | NestedErrors(array<childFieldError>)
31
+ | NestedErrors2(array<array<(field, fieldState)>>)
32
+ | Error(string)
33
+
34
+ type path = {index: int, subfield: field}
35
+
32
36
  type rec action =
33
37
  | ValidateField(field)
34
38
  | ValidateForm(bool)
@@ -58,6 +62,7 @@ module Make = (Config: Config) => {
58
62
  getFieldState: field => fieldState,
59
63
  getFieldError: field => option<string>,
60
64
  getNestedFieldError: (field, string, int) => option<string>,
65
+ getNestedFieldError2: (field, array<path>, ~fieldState: fieldState=?, unit) => option<string>,
61
66
  handleChange: 'a. (Config.field<'a>, 'a) => unit,
62
67
  arrayPush: 'a. (Config.field<array<'a>>, 'a) => unit,
63
68
  arrayUpdateByIndex: 'a. (~field: Config.field<array<'a>>, ~index: int, 'a) => unit,
@@ -113,6 +118,7 @@ module Make = (Config: Config) => {
113
118
  | Validation.StringMax({field}) => (Field(field), Pristine)
114
119
  | Validation.Custom({field}) => (Field(field), Pristine)
115
120
  | Validation.CustomNestedSchema({field}) => (Field(field), Pristine)
121
+ | Validation.CustomNestedSchema2({field}) => (Field(field), Pristine)
116
122
  | Validation.OptionNonEmpty({field}) => (Field(field), Pristine)
117
123
  | Validation.ArrayNonEmpty({field}) => (Field(field), Pristine)
118
124
  }
@@ -228,6 +234,7 @@ module Make = (Config: Config) => {
228
234
  switch fieldState {
229
235
  | (_, Error(message)) => Error(message)
230
236
  | (_, NestedErrors(errors)) => NestedErrors(errors)
237
+ | (_, NestedErrors2(errors)) => NestedErrors2(errors->Obj.magic)
231
238
  | (_, Valid) => Valid
232
239
  }
233
240
  }
@@ -267,6 +274,7 @@ module Make = (Config: Config) => {
267
274
  switch err {
268
275
  | Error(e) => Error(e)
269
276
  | NestedErrors(e) => NestedErrors(e)
277
+ | NestedErrors2(e) => NestedErrors2(e->Obj.magic)
270
278
  | Valid => Valid
271
279
  },
272
280
  ))
@@ -402,13 +410,42 @@ module Make = (Config: Config) => {
402
410
  errors
403
411
  ->Array.getBy(error => error.index === index && error.name === subfield)
404
412
  ->Option.map(({error}) => error)
405
-
413
+ | NestedErrors2(_) => None
406
414
  | Pristine
407
415
  | Valid
408
416
  | Error(_) =>
409
417
  None
410
418
  }
411
419
 
420
+ let rec getNestedFieldError2 = (field, path: array<path>, ~fieldState=?, ()) => {
421
+ switch fieldState->Option.getWithDefault(getFieldState(field)) {
422
+ | NestedErrors2(nestedFieldStates) =>
423
+ nestedFieldStates[(path[0]->Option.getExn).index]->Option.mapWithDefault(None, subform => {
424
+ let subfield = subform->Array.getBy(((subfield, subfieldState)) => {
425
+ switch (path, subfield, (path[0]->Option.getExn).subfield, subfieldState) {
426
+ | ([_], _, _, NestedErrors2(_))
427
+ | (_, _, _, Valid)
428
+ | (_, _, _, Pristine) => false
429
+ | (arr, _, _, Error(_)) if arr->Array.length >= 2 => false
430
+ | (_, ReSchema.Field(field), ReSchema.Field(field2), _) => field === field2->Obj.magic
431
+ }
432
+ })
433
+
434
+ switch subfield {
435
+ | None => getNestedFieldError2(field, [], ~fieldState=Valid, ())
436
+ | Some((_subfield, subfieldState)) =>
437
+ getNestedFieldError2(field, path->Array.sliceToEnd(1), ~fieldState=subfieldState, ())
438
+ }
439
+ })
440
+
441
+ | Pristine
442
+ | Valid
443
+ | NestedErrors(_) =>
444
+ None
445
+ | Error(err) => Some(err)
446
+ }
447
+ }
448
+
412
449
  let validateFields = (fields: array<field>) => {
413
450
  let fieldsValidated = ReSchema.validateFields(~fields, ~values=state.values, ~i18n, schema)
414
451
 
@@ -432,6 +469,7 @@ module Make = (Config: Config) => {
432
469
  | Valid => [(field, (Valid: fieldState))]
433
470
  | Error(message) => [(field, Error(message))]
434
471
  | NestedErrors(message) => [(field, NestedErrors(message))]
472
+ | NestedErrors2(a) => [(field, NestedErrors2(a->Obj.magic))]
435
473
  }
436
474
 
437
475
  | None => []
@@ -465,6 +503,7 @@ module Make = (Config: Config) => {
465
503
  getFieldState,
466
504
  getFieldError,
467
505
  getNestedFieldError,
506
+ getNestedFieldError2,
468
507
  handleChange: (field, value) => send(FieldChangeValue(field, value)),
469
508
  arrayPush: (field, value) => send(FieldArrayAdd(field, value)),
470
509
  arrayUpdateByIndex: (~field, ~index, value) =>
@@ -50,7 +50,7 @@ module Msg = {
50
50
  let invalidValue = {defaultMessage: "Valeur non valide."}
51
51
  }
52
52
 
53
- let toReSchemaResult = (opt: option<string>): ReSchema.fieldState =>
53
+ let toReSchemaResult = (opt: option<string>): ReSchema.fieldState<'a> =>
54
54
  switch opt {
55
55
  | Some(e) => Error(e)
56
56
  | None => Valid
@@ -11,7 +11,7 @@ let wait = ms =>
11
11
  ->Promise.Js.fromBsPromise
12
12
  ->Promise.Js.toResult
13
13
 
14
- let durationMinutesToHourMinutesString = (durationMinutes: float) => {
14
+ let durationMinutesToHourMinutesString = (durationMinutes: float, ~separator=":", ()) => {
15
15
  let hours = (durationMinutes /. 60.)->Js.Math.trunc
16
16
  let minutes = (durationMinutes -. hours *. 60.)->Js.Math.round
17
17
 
@@ -22,7 +22,9 @@ let durationMinutesToHourMinutesString = (durationMinutes: float) => {
22
22
  | (0., min) => min->Js.Float.toFixed ++ " min"
23
23
  | (h, 0.) => h->Js.Float.toFixed ++ " h"
24
24
  | (h, min) =>
25
- `${h < 10. ? "0" : ""}${h->Js.Float.toFixed}:${min < 10. ? "0" : ""}${min->Js.Float.toFixed}`
25
+ `${h < 10. ? "0" : ""}${h->Js.Float.toFixed}${separator}${min < 10.
26
+ ? "0"
27
+ : ""}${min->Js.Float.toFixed}`
26
28
  }
27
29
  }
28
30