Skip to content

Commit 153aa0d

Browse files
committed
Improve S.port
1 parent 8a3c0bf commit 153aa0d

File tree

11 files changed

+272
-176
lines changed

11 files changed

+272
-176
lines changed

IDEAS.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@
22

33
## v10
44

5-
### rc.6
5+
### rc.7
66

7-
- Fix union bug with `S.unknown` (https://github.com/DZakh/sury/issues/121)
8-
- (rescript) Renamed `S.nullish` back to `S.nullable`
9-
- (rescript) Added `S.nullableAsOption` to replace `S.nullable` from V9
10-
- (ppx) Returned back `@s.nullable` attribute
11-
- (ppx) Added support for `Js.nullable` type
12-
- Add `title` field to schema and allow to set it via `S.meta`
7+
- Improve JSONSchema of `S.port` to include `minimum` and `maximum`
8+
- Expose `port` as `format` field on `number` schemas
9+
- (rescript) Deprecate `Port` refinement metadata in favor of `format` field on `number` schemas
10+
- Fix port to not allow decimal numbers
11+
- Improved the default error message for `S.port`
1312

1413
### Final release fixes
1514

packages/sury/src/S.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ export type Schema<Output, Input = unknown> = {
151151
}
152152
| {
153153
readonly type: "number";
154-
readonly format?: "int32";
154+
readonly format?: "int32" | "port";
155155
readonly const?: number;
156156
}
157157
| {

packages/sury/src/S.resi

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ module Path: {
2020
let concat: (t, t) => t
2121
}
2222

23-
type numberFormat = | @as("int32") Int32
23+
type numberFormat = | @as("int32") Int32 | @as("port") Port
24+
25+
type format = numberFormat
2426

2527
@unboxed
2628
type additionalItemsMode = | @as("strip") Strip | @as("strict") Strict
@@ -197,6 +199,7 @@ and untagged = private {
197199
tag: tag,
198200
const?: unknown,
199201
class?: unknown,
202+
format?: format,
200203
name?: string,
201204
title?: string,
202205
description?: string,
@@ -443,7 +446,7 @@ module Int: {
443446
type kind =
444447
| Min({value: int})
445448
| Max({value: int})
446-
| Port
449+
447450
type t = {
448451
kind: kind,
449452
message: string,

packages/sury/src/Sury.res

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -240,9 +240,9 @@ type standard = {
240240
validate: 'any 'value. 'any => {"value": 'value},
241241
}
242242

243-
type numberFormat = | @as("int32") Int32
243+
type numberFormat = | @as("int32") Int32 | @as("port") Port
244244

245-
type internalFormat = numberFormat
245+
type format = numberFormat
246246

247247
@unboxed
248248
type additionalItemsMode = | @as("strip") Strip | @as("strict") Strict
@@ -403,7 +403,7 @@ and internal = {
403403
mutable description?: string,
404404
mutable deprecated?: bool,
405405
mutable examples?: array<unknown>,
406-
format?: internalFormat,
406+
mutable format?: format,
407407
mutable has?: dict<bool>,
408408
advanced?: bool, // TODO: Rename/remove it when have a chance
409409
mutable anyOf?: array<internal>,
@@ -434,6 +434,7 @@ and untagged = private {
434434
tag: tag,
435435
const?: unknown,
436436
class?: unknown,
437+
format?: format,
437438
name?: string,
438439
title?: string,
439440
description?: string,
@@ -2876,7 +2877,7 @@ module Int = {
28762877
type kind =
28772878
| Min({value: int})
28782879
| Max({value: int})
2879-
| Port
2880+
28802881
type t = {
28812882
kind: kind,
28822883
message: string,
@@ -2993,7 +2994,7 @@ let rec to = (from, target) => {
29932994
b.code ++
29942995
switch format {
29952996
| None => `Number.isNaN(${outputVar})`
2996-
| Some(Int32) =>
2997+
| Some(_) =>
29972998
`(${b
29982999
->B.refinement(~inputVar=outputVar, ~schema=target, ~negative=true)
29993000
->Js.String2.sliceToEnd(~from=2)})`
@@ -4611,17 +4612,29 @@ let intMax = (schema, maxValue, ~message as maybeMessage=?) => {
46114612
)
46124613
}
46134614

4614-
let port = (schema, ~message="Invalid port") => {
4615-
schema->addRefinement(
4616-
~metadataId=Int.Refinement.metadataId,
4617-
~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => {
4618-
`if(${inputVar}<1||${inputVar}>65535){${b->B.fail(~message, ~path)}}`
4619-
},
4620-
~refinement={
4621-
kind: Port,
4622-
message,
4623-
},
4624-
)
4615+
let port = (schema, ~message=?) => {
4616+
let mutStandard =
4617+
schema
4618+
->internalRefine((b, ~inputVar, ~selfSchema, ~path) => {
4619+
`${inputVar}>0&&${inputVar}<65536&&${inputVar}%1===0||${switch message {
4620+
| Some(m) => b->B.fail(~message=m, ~path)
4621+
| None =>
4622+
b->B.failWithArg(
4623+
~path,
4624+
input => InvalidType({
4625+
expected: selfSchema->fromInternal,
4626+
received: input,
4627+
}),
4628+
inputVar,
4629+
)
4630+
}};`
4631+
})
4632+
->toInternal
4633+
4634+
mutStandard.format = Some(Port)
4635+
(mutStandard->reverse).format = Some(Port)
4636+
4637+
mutStandard->fromInternal
46254638
}
46264639

46274640
let floatMin = (schema, minValue, ~message as maybeMessage=?) => {
@@ -5029,11 +5042,15 @@ module RescriptJSONSchema = {
50295042
->Int.refinements
50305043
->Js.Array2.forEach(refinement => {
50315044
switch refinement {
5032-
| {kind: Port} => ()
50335045
| {kind: Max({value})} => jsonSchema.maximum = Some(value->Js.Int.toFloat)
50345046
| {kind: Min({value})} => jsonSchema.minimum = Some(value->Js.Int.toFloat)
50355047
}
50365048
})
5049+
| Some(Port) => {
5050+
jsonSchema.type_ = Some(Arrayable.single(#integer))
5051+
jsonSchema.maximum = Some(65535.)
5052+
jsonSchema.minimum = Some(0.)
5053+
}
50375054
| None =>
50385055
jsonSchema.type_ = Some(Arrayable.single(#number))
50395056
schema
@@ -5526,7 +5543,7 @@ let min = (schema, minValue, ~message as maybeMessage=?) => {
55265543
switch schema {
55275544
| String(_) => schema->stringMinLength(minValue, ~message=?maybeMessage)
55285545
| Array(_) => schema->arrayMinLength(minValue, ~message=?maybeMessage)
5529-
| Number({format: Int32}) => schema->intMin(minValue, ~message=?maybeMessage)
5546+
| Number({format: Int32 | Port}) => schema->intMin(minValue, ~message=?maybeMessage)
55305547
| Number(_) => schema->floatMin(minValue->Obj.magic, ~message=?maybeMessage)
55315548
| _ =>
55325549
InternalError.panic(
@@ -5539,7 +5556,7 @@ let max = (schema, maxValue, ~message as maybeMessage=?) => {
55395556
switch schema {
55405557
| String(_) => schema->stringMaxLength(maxValue, ~message=?maybeMessage)
55415558
| Array(_) => schema->arrayMaxLength(maxValue, ~message=?maybeMessage)
5542-
| Number({format: Int32}) => schema->intMax(maxValue, ~message=?maybeMessage)
5559+
| Number({format: Int32 | Port}) => schema->intMax(maxValue, ~message=?maybeMessage)
55435560
| Number(_) => schema->floatMax(maxValue->Obj.magic, ~message=?maybeMessage)
55445561
| _ =>
55455562
InternalError.panic(

0 commit comments

Comments
 (0)