From 44e551f96359ab9ba74e32386573d3bbb7456c94 Mon Sep 17 00:00:00 2001 From: David Blass Date: Tue, 26 Nov 2024 16:02:19 -0500 Subject: [PATCH] add ranges --- ark/docs/src/content/docs/objects.mdx | 133 +++++++++++++++++++++-- ark/docs/src/content/docs/primitives.mdx | 121 ++++++++++++++++++++- ark/repo/scratch.ts | 22 ++++ 3 files changed, 267 insertions(+), 9 deletions(-) diff --git a/ark/docs/src/content/docs/objects.mdx b/ark/docs/src/content/docs/objects.mdx index b76e232d47..73cd252252 100644 --- a/ark/docs/src/content/docs/objects.mdx +++ b/ark/docs/src/content/docs/objects.mdx @@ -287,7 +287,69 @@ const arrays = type({ ##### lengths -🚧 Coming soon ™️🚧 +Constrain an array with an inclusive or exclusive min or max length. + + + + +```ts +const bounded = type({ + nonEmptyStringArray: "string[] > 0" + atLeast3Integers: "number.integer[] >= 3", + lessThan10Emails: "string.email[] < 10", + atMost5Booleans: "boolean[] <= 5" +}) +``` + + + + + +```ts +const bounded = type({ + nonEmptyStringArray: type.string.array().moreThanLength(0), + atLeast3Integers: type.keywords.number.integer.array().atLeastLength(3), + lessThan10Emails: type.keywords.string.email.array().lessThanLength(10), + atMost5Booleans: type.boolean.array().atMostLength(5) +}) +``` + + + + + +Range expressions allow you to specify both a min and max length and use the same syntax for exclusivity. + + + + +```ts +const range = type({ + nonEmptyStringArrayAtMostLength10: "0 < string[] <= 10", + twoToFiveIntegers: "2 <= number.integer[] < 6" +}) +``` + + + + + +```ts +const range = type({ + nonEmptyStringArrayAtMostLength10: type.string + .array() + .moreThanLength(0) + .atMostLength(10), + twoToFiveIntegers: type.keywords.number.integer + .array() + .atLeastLength(2) + .lessThanLength(6) +}) +``` + + + + ## tuples @@ -447,11 +509,6 @@ const myTuple = type(["...", type.number.array(), type.boolean, type.string]) ## dates - -##### keywords - -🚧 Coming soon ™️🚧 - ##### literals @@ -469,7 +526,69 @@ const literals = type({ ##### ranges -🚧 Coming soon ™️🚧 +Constrain a Date with an inclusive or exclusive min or max. + +Bounds can be expressed as either a [number](/primitives#number/literals) representing its corresponding Unix epoch value or a [Date literal](/objects#dates/literals). + + + + +```ts +const bounded = type({ + dateInThePast: `Date < ${Date.now()}`, + dateAfter2000: "Date > d'2000-01-01'", + dateAtOrAfter1970: "Date >= 0" +}) +``` + + + + + +```ts +const bounded = type({ + dateInThePast: type.Date.earlierThan(Date.now()), + dateAfter2000: type.Date.laterThan("2000-01-01"), + dateAtOrAfter1970: type.Date.atOrAfter(0) +}) +``` + + + + + +Range expressions allow you to specify both a min and max and use the same syntax for exclusivity. + + + + +```ts +const tenYearsAgo = new Date() + .setFullYear(new Date().getFullYear() - 10) + .valueOf() + +const bounded = type({ + dateInTheLast10Years: `${tenYearsAgo} <= Date < ${Date.now()}` +}) +``` + + + + + +```ts +const tenYearsAgo = new Date() + .setFullYear(new Date().getFullYear() - 10) + .valueOf() + +const bounded = type({ + dateInTheLast10Years: type.Date.atOrAfter(tenYearsAgo).earlierThan(Date.now()) +}) +``` + + + + ## instanceof diff --git a/ark/docs/src/content/docs/primitives.mdx b/ark/docs/src/content/docs/primitives.mdx index 732a3325d7..0954ef625c 100644 --- a/ark/docs/src/content/docs/primitives.mdx +++ b/ark/docs/src/content/docs/primitives.mdx @@ -39,7 +39,65 @@ const literals = type({ ##### lengths -🚧 Coming soon ™️🚧 +Constrain a string with an inclusive or exclusive min or max length. + + + + +```ts +const bounded = type({ + nonEmpty: "string > 0" + atLeastLength3: "string.alphanumeric >= 3", + lessThanLength10: "string < 10", + atMostLength5: "string <= 5" +}) +``` + + + + + +```ts +const bounded = type({ + nonEmpty: type.string.moreThanLength(0) + atLeastLength3: type.keywords.string.alphanumeric.atLeastLength(3), + lessThanLength10: type.string.lessThanLength(10), + atMostLength5: type.string.atMostLength(5) +}) +``` + + + + + +Range expressions allow you to specify both a min and max length and use the same syntax for exclusivity. + + + + +```ts +const range = type({ + nonEmptyAtMostLength10: "0 < string <= 10", + integerStringWith2To5Digits: "2 <= string.integer < 6" +}) +``` + + + + + +```ts +const range = type({ + nonEmptyAtMostLength10: type.string.moreThanLength(0).atMostLength(10), + integerStringWith2To5Digits: type.keywords.string.integer + .atLeastLength(2) + .lessThanLength(6) +}) +``` + + + + ## number @@ -60,7 +118,66 @@ const literals = type({ ##### ranges -🚧 Coming soon ™️🚧 +Constrain a number with an inclusive or exclusive min or max. + + + + +```ts +const bounded = type({ + positive: "number > 0" + atLeast3: "number.integer >= 3", + lessThanPi: "number < 3.14159", + atMost5: "number <= 5" +}) +``` + + + + + +```ts +const bounded = type({ + positive: type.number.moreThan(0) + atLeast3: type.keywords.number.integer.atLeast(3), + lessThanPi: type.number.lessThan(3.14159), + atMost5: type.number.atMost(5) +}) +``` + + + + + +Range expressions allow you to specify both a min and max and use the same syntax for exclusivity. + + + + +```ts +const range = type({ + positiveAtMostE: "0 < number <= 2.71828", + evenNumberAbsoluteValueLessThan50: "-50 < (number % 2) < 50" +}) +``` + + + + + +```ts +const range = type({ + positiveAtMostE: type.number.moreThan(0).atMost(2.71828), + evenNumberAbsoluteValueLessThan50: type.number + .divisibleBy(2) + .moreThan(-50) + .lessThan(50) +}) +``` + + + + ##### divisors diff --git a/ark/repo/scratch.ts b/ark/repo/scratch.ts index e00bc67dc7..3f18077c2c 100644 --- a/ark/repo/scratch.ts +++ b/ark/repo/scratch.ts @@ -9,3 +9,25 @@ interface User extends type.infer {} const user: type = _user user({}).toString() + +Date.now() + +const tenYearsAgo = new Date() + .setFullYear(new Date().getFullYear() - 10) + .valueOf() + +const bounded = type({ + dateInTheLast10Years: `${tenYearsAgo} <= Date < ${Date.now()}` +}) + +Date.now() //? + +//? + +type.Date.laterThan("") + +const out = bounded.assert({ + dateInThePast: new Date(0), + dateAfter2000: new Date(), + dateAtOrAfter1970: new Date(0) +})