From e5e2b19a2ae742f3f06ddb8d6c484778a73a92c0 Mon Sep 17 00:00:00 2001 From: Jacob Alford Date: Thu, 26 Oct 2023 16:42:37 -0600 Subject: [PATCH 01/16] feat(type-string): make output struct props display optionality --- docs/schemata/index.md | 30 +++++++++---------- .../struct/instances/type-string.ts | 6 ++-- tests/CamelCaseKeys.test.ts | 25 ++++++++++++++-- tests/Partial.test.ts | 2 +- tests/Strict.test.ts | 2 +- tests/Struct.test.ts | 2 +- tests/Union.test.ts | 2 +- tests/intersect_.test.ts | 3 +- tests/partialOption.test.ts | 9 +++++- tests/partial_.test.ts | 9 +++++- tests/strict_.test.ts | 2 +- tests/transcode-errors.test.ts | 6 ++-- 12 files changed, 67 insertions(+), 31 deletions(-) diff --git a/docs/schemata/index.md b/docs/schemata/index.md index 7c1c0a4f..84b840d0 100644 --- a/docs/schemata/index.md +++ b/docs/schemata/index.md @@ -82,23 +82,23 @@ has_children: true ### String (17) -* Ascii ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Ascii.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Ascii.ts)) (e.g: `.2~pj`, `Xzicp`, `(<{nIBab`) -* Base64 ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Base64.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Base64.ts)) (e.g: `C6/h//++`, `8Z/AD/6p++==`, `phn/++/+/m++8+8W4//vQ2++/EDH`) -* Base64Url ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Base64Url.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Base64Url.ts)) (e.g: `1w__-e0-_`, `l_-_VZ5_-_`, `pHz7_b5`) -* BitcoinAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/BitcoinAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/BitcoinAddress.ts)) (e.g: `3CXSUGbZ85hnkAcLaLL2wRc3FpK8R`, `2J5rM1HcLAKA2CLyhRmsKHJA3wwUWLQn`, `bc1os8pxxfe76tsa6l91nsp518bqh549y`) +* Ascii ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Ascii.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Ascii.ts)) (e.g: `~RzlW9n=`, `A|.y]`, `|~wi^)|`) +* Base64 ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Base64.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Base64.ts)) (e.g: `d+J/2/C0/e+6++jC3++=`, `/+r449yX+/2+`, `K//+l+moTG+c0qX/7+++N3+++3/A4/PK`) +* Base64Url ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Base64Url.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Base64Url.ts)) (e.g: `D1AT-p6`, `2q-1-yc0C_`, `-tQ_uT_-_4`) +* BitcoinAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/BitcoinAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/BitcoinAddress.ts)) (e.g: `bc1ylybl1cr798dcai2z313vi2d2bbcz023fd2zw`, `bc1u0f4w6j4ffz0l9uq39lca4d2me6qz10t`, `bc1bz25560kt237c85xytn2452a3l08755557`) * CamelCaseString ([docs](https://jacob-alford.github.io/schemata-ts/schemata/CamelCaseString.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/CamelCaseString.ts)) (e.g: `Camel_case-string` → `camelCaseString`) -* CreditCard ([docs](https://jacob-alford.github.io/schemata-ts/schemata/CreditCard.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/CreditCard.ts)) (e.g: `62411770467721586`, `3528751036300588292`, `50864381596660195`) -* EmailAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/EmailAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/EmailAddress.ts)) (e.g: `{#/_/!__.$?C.?~{5_-%=.$?'=^?*.7/_'}=~$}%.-.=.^|_+&&^#-!.{}#|%}=!+@[6.39.1.537]`, `!^-A&zs#|}.#%$?+W^{/+~%.+-.}{+''!8{P._#*'~.$?$~_.|8~&@I5w.6-fQ44O-q..u7-fE..195-M-Ei03.0XC-76-c5.-x-C.gMYwxOeuJIHhaF`, `"뾰㷯鏎￳￰"@[30.49.838.25]`) -* EthereumAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/EthereumAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/EthereumAddress.ts)) (e.g: `0xAB05bEd1ADA0ADa39ddeFBABEAa0af8300CFbAC9`, `0xC39f07eEc1f5B0d17C3d2FbcddbDBDC0bEAaccCd`, `0xC8AC7ECbC47DFD82e5cF8Beb3eF0fDDDdBB1EAAf`) -* HexColor ([docs](https://jacob-alford.github.io/schemata-ts/schemata/HexColor.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/HexColor.ts)) (e.g: `12d1f625`, `0713CDBA`, `#F1CaCFe9`) -* Hexadecimal ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Hexadecimal.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Hexadecimal.ts)) (e.g: `2c21AdFd815`, `0Hb21A`, `0H38EBAAd`) -* HslColor ([docs](https://jacob-alford.github.io/schemata-ts/schemata/HslColor.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/HslColor.ts)) (e.g: `hsla(.4384991e+058689613121,0.7438854870%,95e-37766%,8727511084e0)`, `hsl(242.2323248grad00000000.7039915138e+3889361%0100e+97581358157%/187.9e808)`, `hsl(.51e+10turn,00000100%,000.6879%)`) -* Jwt ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Jwt.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Jwt.ts)) (e.g: `8-._X._3f`, `._aA_s7-`, `_-5-9-_nD.30-PZ`) -* LatLong ([docs](https://jacob-alford.github.io/schemata-ts/schemata/LatLong.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/LatLong.ts)) (e.g: `-90.000000,98.6358`, `90.000,180`, `90.00000,178`) -* NonEmptyString ([docs](https://jacob-alford.github.io/schemata-ts/schemata/NonEmptyString.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/NonEmptyString.ts)) (e.g: `,hP5brRD2W`, `"\_M{#@~!`, `CW`) -* RGB ([docs](https://jacob-alford.github.io/schemata-ts/schemata/RGB.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/RGB.ts)) (e.g: `rgb(206,112,200)`, `rgba(82%,100%,96%,.80)`, `rgba(206,71,200,0.6815)`) +* CreditCard ([docs](https://jacob-alford.github.io/schemata-ts/schemata/CreditCard.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/CreditCard.ts)) (e.g: `50828982804187171`, `650839232707231898`, `656700805495129821`) +* EmailAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/EmailAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/EmailAddress.ts)) (e.g: `{#?=b&_~??./?{$-/@..mWz`, `+/.u{=%?&^'.-'^B5=}!+1._+*.|}?.#}$|=#.*}#^B.6^#!.q'--=^/#~.*~%#}@[563.33.07.57]`, `"ﭼ"@P.-.19q-e672q.-6I-8.6-Fv0C-k.-Jcd.6-uS.fMrlmUZjdiHi`) +* EthereumAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/EthereumAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/EthereumAddress.ts)) (e.g: `0xCc1D30Fa0b23Cc80fCEfAEeAAecEcaBAaa7B8EBD`, `0x8babd8Bf09Cbd32D3dc3ADCbAfbB3AB9BaFc1AEF`, `0xaBAFeaAcDFbAc8eCffb4DEEabBAbBaecF0a2c1BC`) +* HexColor ([docs](https://jacob-alford.github.io/schemata-ts/schemata/HexColor.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/HexColor.ts)) (e.g: `9e8bdaCC`, `ad96cC86`, `DeBBbD`) +* Hexadecimal ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Hexadecimal.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Hexadecimal.ts)) (e.g: `0h4008ab6DD`, `0Hcd7cF7BDfEB`, `FaA5b7a1ae1c`) +* HslColor ([docs](https://jacob-alford.github.io/schemata-ts/schemata/HslColor.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/HslColor.ts)) (e.g: `hsl(458256454,00.233911930e+74%,+000000000.8382e+219%,83772976015e+789640804216%)`, `hsl(-.3274turn,+00.6073%,0.2970851426%,1247238529e249)`, `hsl(.3831130202e+244366761790,+00088%,00.3259556e+384%,79014e11)`) +* Jwt ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Jwt.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Jwt.ts)) (e.g: `d1eG-rLH6._S7_rfx_.wX_R-`, `o9-Qy-._3_-__7D-.Z`, `-a.s.YO_`) +* LatLong ([docs](https://jacob-alford.github.io/schemata-ts/schemata/LatLong.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/LatLong.ts)) (e.g: `(-80,+99)`, `(57,-180.00)`, `(6.83,179)`) +* NonEmptyString ([docs](https://jacob-alford.github.io/schemata-ts/schemata/NonEmptyString.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/NonEmptyString.ts)) (e.g: `k-3`, `IHa9i3W3dd1yNfkTyJ==`, `s~4:K'k:`) +* RGB ([docs](https://jacob-alford.github.io/schemata-ts/schemata/RGB.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/RGB.ts)) (e.g: `rgba(39%,100%,100%,1.0)`, `rgba(120,253,252,1)`, `rgba(100%,100%,100%,1.0)`) * String ([docs](https://jacob-alford.github.io/schemata-ts/schemata/String.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/String.ts)) -* UUID ([docs](https://jacob-alford.github.io/schemata-ts/schemata/UUID.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/UUID.ts)) (e.g: `eCcAfcbB-b8e5-2CeC-f20c-Bda9DAca8Af9`, `f5ccB60e-9AAC-C68a-Bf1b-F8CEE23Bf9aA`, `8fC88f3F-462b-ecc1-aaA5-bDCacEfbAA2f`) +* UUID ([docs](https://jacob-alford.github.io/schemata-ts/schemata/UUID.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/UUID.ts)) (e.g: `770E2Eab-aB0A-8aE2-6AB5-DbdD2CCA89CA`, `2BA1DDCd-A3BB-81aF-BA64-dC3afEEdbACC`, `E327f1bB-C3BF-0AE8-bcbc-f2ecbAd0F2A3`) ### Unit (1) diff --git a/src/schemables/struct/instances/type-string.ts b/src/schemables/struct/instances/type-string.ts index cf578d52..4e48132a 100644 --- a/src/schemables/struct/instances/type-string.ts +++ b/src/schemables/struct/instances/type-string.ts @@ -57,8 +57,10 @@ export const StructTypeString: WithStruct = { _.length === 1 && RA.isNonEmpty(_) && RNEA.head(_[0]).inputKey !== outputKey - ? `[${RNEA.head(_[0]).inputKey}->${outputKey}]: ${unionString}` - : `${outputKey}: ${unionString}`, + ? `[${RNEA.head(_[0]).inputKey}->${outputKey}]${ + unionString.includes('?') ? '?' : '' + }: ${unionString}` + : `${outputKey}${unionString.includes('?') ? '?' : ''}: ${unionString}`, ), ), ), diff --git a/tests/CamelCaseKeys.test.ts b/tests/CamelCaseKeys.test.ts index 6479fd9a..b6f06516 100644 --- a/tests/CamelCaseKeys.test.ts +++ b/tests/CamelCaseKeys.test.ts @@ -47,7 +47,20 @@ test('Unlawful Camelcase types', () => { >() }) -const expectedTypeString = `{ APPLE_BANANA: Integer, BAZ_QUUX_FOO: IsoDateTimeStringZ, apple-banana: string, baz-quux-foo: Float, foo bar baz: string, foo_bar_baz?: null | boolean?, prickly-pear: FloatString } → { appleBanana: (:apple-banana)string | (:APPLE_BANANA)Integer, bazQuuxFoo: (:BAZ_QUUX_FOO)SafeDate | (:baz-quux-foo)Float, fooBarBaz: (:foo_bar_baz)null | boolean? | (:foo bar baz)string, [prickly-pear->pricklyPear]: Float }` +const expectedTypeString = + `{ APPLE_BANANA: Integer,` + + ` BAZ_QUUX_FOO: IsoDateTimeStringZ,` + + ` apple-banana: string,` + + ` baz-quux-foo: Float,` + + ` foo bar baz: string,` + + ` foo_bar_baz?: null | boolean?,` + + ` prickly-pear: FloatString` + + ` } → {` + + ` appleBanana: (:apple-banana)string | (:APPLE_BANANA)Integer,` + + ` bazQuuxFoo: (:BAZ_QUUX_FOO)SafeDate | (:baz-quux-foo)Float,` + + ` fooBarBaz?: (:foo_bar_baz)null | boolean? | (:foo bar baz)string,` + + ` [prickly-pear->pricklyPear]: Float` + + ` }` runStandardTestSuite( UnlawfulSchema, @@ -173,7 +186,15 @@ test('Lawful Camelcase types', () => { >() }) -const expectedLawfulTypeString = `{ FIVE_SIX: boolean, ThreeFour?: null | boolean?, one-two: Float } → { [FIVE_SIX->fiveSix]: boolean, [one-two->oneTwo]: Float, [ThreeFour->threeFour]: null | boolean? }` +const expectedLawfulTypeString = + `{ FIVE_SIX: boolean,` + + ` ThreeFour?: null | boolean?,` + + ` one-two: Float` + + ` } → {` + + ` [FIVE_SIX->fiveSix]: boolean,` + + ` [one-two->oneTwo]: Float,` + + ` [ThreeFour->threeFour]?: null | boolean?` + + ` }` runStandardTestSuite(LawfulSchema, _ => ({ decoderTests: [ diff --git a/tests/Partial.test.ts b/tests/Partial.test.ts index 8dfe4bb2..796a79ac 100644 --- a/tests/Partial.test.ts +++ b/tests/Partial.test.ts @@ -34,7 +34,7 @@ const expectedJsonSchema = JS.annotate({ }), ) -const expectedTypeString = `{ a?: Array[1,]?, b?: Integer<69,420>? } → { a: Array[1,]?, b: TestNt? }` +const expectedTypeString = `{ a?: Array[1,]?, b?: Integer<69,420>? } → { a?: Array[1,]?, b?: TestNt? }` test('types', () => { expectTypeOf(Schema).toEqualTypeOf< diff --git a/tests/Strict.test.ts b/tests/Strict.test.ts index c9ad9195..930499d5 100644 --- a/tests/Strict.test.ts +++ b/tests/Strict.test.ts @@ -39,7 +39,7 @@ const expectedJsonSchema = JS.struct( false, ) -const expectedTypeString = `{ a: string, b?: Float?, c: boolean } → { a: string, b: Float?, c: boolean }` +const expectedTypeString = `{ a: string, b?: Float?, c: boolean }` runStandardTestSuite(Schema, _ => ({ decoderTests: [ diff --git a/tests/Struct.test.ts b/tests/Struct.test.ts index 5d2cf87e..9928406b 100644 --- a/tests/Struct.test.ts +++ b/tests/Struct.test.ts @@ -43,7 +43,7 @@ const expectedJsonSchema: Const> = JS.st const expectedTypeString = // - `{ a?: null | string?, b: Float, c: boolean, d: Float<-8640000000000,8640000000000>, e?: Integer<0,2>?, f?: string | Float | null | DateString? } → { a: null | string?, b: Float, c: boolean, d: Date, e: Integer<0,2>?, f: string | Float | Option }` + `{ a?: null | string?, b: Float, c: boolean, d: Float<-8640000000000,8640000000000>, e?: Integer<0,2>?, f?: string | Float | null | DateString? } → { a?: null | string?, b: Float, c: boolean, d: Date, e?: Integer<0,2>?, f: string | Float | Option }` test('Struct types', () => { expectTypeOf(Schema).toMatchTypeOf< diff --git a/tests/Union.test.ts b/tests/Union.test.ts index fb8eb223..cbf58e05 100644 --- a/tests/Union.test.ts +++ b/tests/Union.test.ts @@ -170,7 +170,7 @@ runStandardTestSuite(NotMutex, _ => ({ false, ), ), - typeString: `{ a: string, b?: null | Integer?, c: Integer<-8640000000000000,8640000000000000> } | { a: EmailAddress, c: Float<-8640000000000,8640000000000> } → { a: string, b: null | Integer?, c: Integer<-8640000000000000,8640000000000000> } | { a: EmailAddress, c: Date }`, + typeString: `{ a: string, b?: null | Integer?, c: Integer<-8640000000000000,8640000000000000> } | { a: EmailAddress, c: Float<-8640000000000,8640000000000> } → { a: string, b?: null | Integer?, c: Integer<-8640000000000000,8640000000000000> } | { a: EmailAddress, c: Date }`, }))() runStandardTestSuite( diff --git a/tests/intersect_.test.ts b/tests/intersect_.test.ts index 8171e39a..9fe8c8de 100644 --- a/tests/intersect_.test.ts +++ b/tests/intersect_.test.ts @@ -72,6 +72,5 @@ runStandardTestSuite(Intersected, _ => ({ required: ['a', 'c'], readOnly: true, }, - typeString: - '{ a: string, b?: Integer<0,>?, c: string } → { a: string, b: Integer<0,>?, c: string }', + typeString: '{ a: string, b?: Integer<0,>?, c: string }', }))() diff --git a/tests/partialOption.test.ts b/tests/partialOption.test.ts index 0aeab648..a38f8c8d 100644 --- a/tests/partialOption.test.ts +++ b/tests/partialOption.test.ts @@ -38,7 +38,14 @@ const expectedJsonSchema = JS.annotate({ }), ) -const expectedTypeString = `{ a?: Array[1,]?, b?: Integer<69,420>? } → { a: Array[1,]?, b: TestNt? }` +const expectedTypeString = + `{` + + ` a?: Array[1,]?,` + + ` b?: Integer<69,420>?` + + ` } → {` + + ` a?: Array[1,]?,` + + ` b?: TestNt?` + + ` }` test('types', () => { expectTypeOf(CombinedSchema).toEqualTypeOf< diff --git a/tests/partial_.test.ts b/tests/partial_.test.ts index d4d05e1e..67c7a3b7 100644 --- a/tests/partial_.test.ts +++ b/tests/partial_.test.ts @@ -37,7 +37,14 @@ const expectedJsonSchema = JS.annotate({ }), ) -const expectedTypeString = `{ a?: Array[1,]?, b?: Integer<69,420>? } → { a: Array[1,]?, b: TestNt? }` +const expectedTypeString = + `{` + + ` a?: Array[1,]?,` + + ` b?: Integer<69,420>?` + + ` } → {` + + ` a?: Array[1,]?,` + + ` b?: TestNt?` + + ` }` test('types', () => { expectTypeOf(CombinedSchema).toEqualTypeOf< diff --git a/tests/strict_.test.ts b/tests/strict_.test.ts index 65616e30..fdc24f91 100644 --- a/tests/strict_.test.ts +++ b/tests/strict_.test.ts @@ -43,7 +43,7 @@ const expectedJsonSchema = JS.annotate({ readOnly: true })( ), ) -const expectedTypeString = `{ a: string, b?: Float?, c: boolean } → { a: string, b: Float?, c: boolean }` +const expectedTypeString = `{ a: string, b?: Float?, c: boolean }` runStandardTestSuite(Schema, _ => ({ decoderTests: [ diff --git a/tests/transcode-errors.test.ts b/tests/transcode-errors.test.ts index ed5a3991..a76800ff 100644 --- a/tests/transcode-errors.test.ts +++ b/tests/transcode-errors.test.ts @@ -81,15 +81,15 @@ describe('transcode errors', () => { obj.obj = obj const testError = TC.transcodeErrors(TC.typeMismatch('string', obj)) expect(drawTree(testError, { showHeading: false })).toBe( - `─ Expected string but got [Circular object]`, + `─ Expected string but got {"obj":"[Circular object]"}`, ) }) it('shows circular arrays', () => { const arr: any = [] - arr[0] = arr + arr[1] = arr const testError = TC.transcodeErrors(TC.typeMismatch('string', arr)) expect(drawTree(testError, { showHeading: false })).toBe( - `─ Expected string but got [Circular Array]`, + `─ Expected string but got [null,"[Circular Array]"]`, ) }) it('shows maps', () => { From 656086f40c55932d82ff441c5faa9a70a464ccf1 Mon Sep 17 00:00:00 2001 From: Jacob Alford Date: Thu, 26 Oct 2023 16:43:44 -0600 Subject: [PATCH 02/16] feat(Asserts): add asserts derivation variations --- docs/Assert.md | 81 +++++++++++++++++ docs/Eq.md | 2 +- docs/Guard.md | 2 +- docs/JsonSchema.md | 2 +- docs/MergeSemigroup.md | 2 +- docs/Schema.md | 2 +- docs/TranscodeError.md | 2 +- docs/Transcoder.md | 2 +- docs/TranscoderPar.md | 2 +- docs/TypeString.md | 2 +- docs/brand.md | 2 +- docs/float.md | 2 +- docs/integer.md | 2 +- docs/newtype.md | 2 +- docs/schemata/Annotate.md | 2 +- docs/schemata/Array.md | 2 +- docs/schemata/Ascii.md | 2 +- docs/schemata/Base64.md | 2 +- docs/schemata/Base64Url.md | 2 +- docs/schemata/BigIntFromString.md | 2 +- docs/schemata/BitcoinAddress.md | 2 +- docs/schemata/Boolean.md | 2 +- docs/schemata/BooleanFromNumber.md | 2 +- docs/schemata/BooleanFromString.md | 2 +- docs/schemata/Brand.md | 2 +- docs/schemata/CamelCaseKeys.md | 2 +- docs/schemata/CamelCaseRecord.md | 2 +- docs/schemata/CamelCaseString.md | 2 +- docs/schemata/CheckDigit.md | 2 +- docs/schemata/CreditCard.md | 2 +- docs/schemata/Date.md | 2 +- docs/schemata/DateFromInt.md | 2 +- docs/schemata/DateFromIsoString.md | 2 +- docs/schemata/DateFromString.md | 2 +- docs/schemata/DateFromUnixTime.md | 2 +- docs/schemata/Either.md | 2 +- docs/schemata/EmailAddress.md | 2 +- docs/schemata/EthereumAddress.md | 2 +- docs/schemata/Float.md | 2 +- docs/schemata/FloatFromString.md | 2 +- docs/schemata/HexColor.md | 2 +- docs/schemata/Hexadecimal.md | 2 +- docs/schemata/HslColor.md | 2 +- docs/schemata/Imap.md | 2 +- docs/schemata/Int.md | 2 +- docs/schemata/IntFromString.md | 2 +- docs/schemata/Intersect.md | 2 +- docs/schemata/Jwt.md | 2 +- docs/schemata/LatLong.md | 2 +- docs/schemata/Lazy.md | 2 +- docs/schemata/Literal.md | 2 +- docs/schemata/MapFromEntries.md | 2 +- docs/schemata/Natural.md | 2 +- docs/schemata/NegativeFloat.md | 2 +- docs/schemata/NegativeInt.md | 2 +- docs/schemata/Newtype.md | 2 +- docs/schemata/NonEmptyArray.md | 2 +- docs/schemata/NonEmptyString.md | 2 +- docs/schemata/NonNegativeFloat.md | 2 +- docs/schemata/NonPositiveFloat.md | 2 +- docs/schemata/NonPositiveInt.md | 2 +- docs/schemata/Nullable.md | 2 +- docs/schemata/Number.md | 2 +- docs/schemata/Option.md | 2 +- docs/schemata/OptionFromNullable.md | 2 +- docs/schemata/Optional.md | 2 +- docs/schemata/Parse.md | 2 +- docs/schemata/ParseBase64Json.md | 2 +- docs/schemata/ParseEncodedJson.md | 2 +- docs/schemata/ParseJsonString.md | 2 +- docs/schemata/Partial.md | 2 +- docs/schemata/Pattern.md | 2 +- docs/schemata/PositiveFloat.md | 2 +- docs/schemata/PositiveInt.md | 2 +- docs/schemata/RGB.md | 2 +- docs/schemata/Readonly.md | 2 +- docs/schemata/Record.md | 2 +- docs/schemata/Refine.md | 2 +- docs/schemata/SetFromArray.md | 2 +- docs/schemata/Strict.md | 2 +- docs/schemata/String.md | 2 +- docs/schemata/Struct.md | 2 +- docs/schemata/Tuple.md | 2 +- docs/schemata/UUID.md | 2 +- docs/schemata/Union.md | 2 +- docs/schemata/Unit.md | 2 +- docs/schemata/Unknown.md | 2 +- docs/schemata/UnknownArray.md | 2 +- docs/schemata/UnknownRecord.md | 2 +- docs/schemata/index.md | 30 +++---- scripts/docs-config.ts | 1 + src/Assert.ts | 81 +++++++++++++++++ src/TranscodeError.ts | 19 +++- tests/assert.test.ts | 135 ++++++++++++++++++++++++++++ 94 files changed, 417 insertions(+), 106 deletions(-) create mode 100644 docs/Assert.md create mode 100644 src/Assert.ts create mode 100644 tests/assert.test.ts diff --git a/docs/Assert.md b/docs/Assert.md new file mode 100644 index 00000000..9ab64355 --- /dev/null +++ b/docs/Assert.md @@ -0,0 +1,81 @@ +--- +title: Assert.ts +nav_order: 2 +permalink: /assert/ +--- + +## Assert overview + +Added in v2.2.0 + +--- + +

Table of contents

+ +- [Interpreters](#interpreters) + - [deriveAssert](#deriveassert) + - [deriveInputAssert](#deriveinputassert) + - [deriveInputAssertTree](#deriveinputasserttree) +- [Models](#models) + - [Assert (interface)](#assert-interface) + +--- + +# Interpreters + +## deriveAssert + +A trait which will throw an error for when an expected "output" value does not match a +schema's output type + +**Signature** + +```ts +export declare const deriveAssert: (schema: Schema) => Assert +``` + +Added in v2.2.0 + +## deriveInputAssert + +A trait which will throw an error for when an expected "input" value does not match a +schema's input type + +**Signature** + +```ts +export declare const deriveInputAssert: (schema: Schema) => Assert +``` + +Added in v2.2.0 + +## deriveInputAssertTree + +A trait which will throw an error for when an expected "input" value does not match a +schema's input type + +Unlike `deriveInputAssert`, this will include the error tree in the error message + +**Signature** + +```ts +export declare const deriveInputAssertTree: (schema: Schema) => Assert +``` + +Added in v2.2.0 + +# Models + +## Assert (interface) + +A trait which will throw an error for when a value does not match a schema + +**Signature** + +```ts +export interface Assert { + readonly assert: (output: unknown) => asserts output is T +} +``` + +Added in v2.2.0 diff --git a/docs/Eq.md b/docs/Eq.md index 1151a067..77f70988 100644 --- a/docs/Eq.md +++ b/docs/Eq.md @@ -1,6 +1,6 @@ --- title: Eq.ts -nav_order: 3 +nav_order: 4 permalink: /eq/ --- diff --git a/docs/Guard.md b/docs/Guard.md index 7609a699..5b0f4aab 100644 --- a/docs/Guard.md +++ b/docs/Guard.md @@ -1,6 +1,6 @@ --- title: Guard.ts -nav_order: 5 +nav_order: 6 permalink: /guard/ --- diff --git a/docs/JsonSchema.md b/docs/JsonSchema.md index f38070f5..d9b8a123 100644 --- a/docs/JsonSchema.md +++ b/docs/JsonSchema.md @@ -1,6 +1,6 @@ --- title: JsonSchema.ts -nav_order: 7 +nav_order: 8 permalink: /json-schema/ --- diff --git a/docs/MergeSemigroup.md b/docs/MergeSemigroup.md index ae53825d..a6e6797b 100644 --- a/docs/MergeSemigroup.md +++ b/docs/MergeSemigroup.md @@ -1,6 +1,6 @@ --- title: MergeSemigroup.ts -nav_order: 8 +nav_order: 9 permalink: /merge-semigroup/ --- diff --git a/docs/Schema.md b/docs/Schema.md index 774616f2..4da9ef9a 100644 --- a/docs/Schema.md +++ b/docs/Schema.md @@ -1,6 +1,6 @@ --- title: Schema.ts -nav_order: 10 +nav_order: 11 permalink: /schema/ --- diff --git a/docs/TranscodeError.md b/docs/TranscodeError.md index 0dd208e6..eb746546 100644 --- a/docs/TranscodeError.md +++ b/docs/TranscodeError.md @@ -1,6 +1,6 @@ --- title: TranscodeError.ts -nav_order: 87 +nav_order: 88 permalink: /transcode-error/ --- diff --git a/docs/Transcoder.md b/docs/Transcoder.md index 7660a708..bf129f43 100644 --- a/docs/Transcoder.md +++ b/docs/Transcoder.md @@ -1,6 +1,6 @@ --- title: Transcoder.ts -nav_order: 88 +nav_order: 89 permalink: /transcoder/ --- diff --git a/docs/TranscoderPar.md b/docs/TranscoderPar.md index a3c3b4d3..c4b11a1d 100644 --- a/docs/TranscoderPar.md +++ b/docs/TranscoderPar.md @@ -1,6 +1,6 @@ --- title: TranscoderPar.ts -nav_order: 89 +nav_order: 90 permalink: /transcoder-par/ --- diff --git a/docs/TypeString.md b/docs/TypeString.md index 1cbe58d7..383f97f1 100644 --- a/docs/TypeString.md +++ b/docs/TypeString.md @@ -1,6 +1,6 @@ --- title: TypeString.ts -nav_order: 90 +nav_order: 91 permalink: /type-string/ --- diff --git a/docs/brand.md b/docs/brand.md index 2388d5c1..129382c7 100644 --- a/docs/brand.md +++ b/docs/brand.md @@ -1,6 +1,6 @@ --- title: brand.ts -nav_order: 2 +nav_order: 3 permalink: /brand/ --- diff --git a/docs/float.md b/docs/float.md index 54a362a9..776b62c7 100644 --- a/docs/float.md +++ b/docs/float.md @@ -1,6 +1,6 @@ --- title: float.ts -nav_order: 4 +nav_order: 5 permalink: /float/ --- diff --git a/docs/integer.md b/docs/integer.md index 4d62f0f8..00fc0114 100644 --- a/docs/integer.md +++ b/docs/integer.md @@ -1,6 +1,6 @@ --- title: integer.ts -nav_order: 6 +nav_order: 7 permalink: /integer/ --- diff --git a/docs/newtype.md b/docs/newtype.md index cd14248e..dfad11b5 100644 --- a/docs/newtype.md +++ b/docs/newtype.md @@ -1,6 +1,6 @@ --- title: newtype.ts -nav_order: 9 +nav_order: 10 permalink: /newtype/ --- diff --git a/docs/schemata/Annotate.md b/docs/schemata/Annotate.md index 81c2064d..fdd370bf 100644 --- a/docs/schemata/Annotate.md +++ b/docs/schemata/Annotate.md @@ -1,6 +1,6 @@ --- title: Annotate -nav_order: 11 +nav_order: 12 parent: schemata --- diff --git a/docs/schemata/Array.md b/docs/schemata/Array.md index 583582e6..7c2c7705 100644 --- a/docs/schemata/Array.md +++ b/docs/schemata/Array.md @@ -1,6 +1,6 @@ --- title: Array -nav_order: 12 +nav_order: 13 parent: schemata --- diff --git a/docs/schemata/Ascii.md b/docs/schemata/Ascii.md index f3dae68e..35d359f9 100644 --- a/docs/schemata/Ascii.md +++ b/docs/schemata/Ascii.md @@ -1,6 +1,6 @@ --- title: Ascii -nav_order: 13 +nav_order: 14 parent: schemata --- diff --git a/docs/schemata/Base64.md b/docs/schemata/Base64.md index c90d4326..b90eaf52 100644 --- a/docs/schemata/Base64.md +++ b/docs/schemata/Base64.md @@ -1,6 +1,6 @@ --- title: Base64 -nav_order: 14 +nav_order: 15 parent: schemata --- diff --git a/docs/schemata/Base64Url.md b/docs/schemata/Base64Url.md index 2d320313..5b28e767 100644 --- a/docs/schemata/Base64Url.md +++ b/docs/schemata/Base64Url.md @@ -1,6 +1,6 @@ --- title: Base64Url -nav_order: 15 +nav_order: 16 parent: schemata --- diff --git a/docs/schemata/BigIntFromString.md b/docs/schemata/BigIntFromString.md index 92a8642a..c5569199 100644 --- a/docs/schemata/BigIntFromString.md +++ b/docs/schemata/BigIntFromString.md @@ -1,6 +1,6 @@ --- title: BigIntFromString -nav_order: 16 +nav_order: 17 parent: schemata --- diff --git a/docs/schemata/BitcoinAddress.md b/docs/schemata/BitcoinAddress.md index 817aa3ab..3d187f7f 100644 --- a/docs/schemata/BitcoinAddress.md +++ b/docs/schemata/BitcoinAddress.md @@ -1,6 +1,6 @@ --- title: BitcoinAddress -nav_order: 17 +nav_order: 18 parent: schemata --- diff --git a/docs/schemata/Boolean.md b/docs/schemata/Boolean.md index 352dbcb0..e34d6ce1 100644 --- a/docs/schemata/Boolean.md +++ b/docs/schemata/Boolean.md @@ -1,6 +1,6 @@ --- title: Boolean -nav_order: 18 +nav_order: 19 parent: schemata --- diff --git a/docs/schemata/BooleanFromNumber.md b/docs/schemata/BooleanFromNumber.md index 84ced0c2..3fca6cee 100644 --- a/docs/schemata/BooleanFromNumber.md +++ b/docs/schemata/BooleanFromNumber.md @@ -1,6 +1,6 @@ --- title: BooleanFromNumber -nav_order: 19 +nav_order: 20 parent: schemata --- diff --git a/docs/schemata/BooleanFromString.md b/docs/schemata/BooleanFromString.md index 8bbcc8ef..1e07f6b4 100644 --- a/docs/schemata/BooleanFromString.md +++ b/docs/schemata/BooleanFromString.md @@ -1,6 +1,6 @@ --- title: BooleanFromString -nav_order: 20 +nav_order: 21 parent: schemata --- diff --git a/docs/schemata/Brand.md b/docs/schemata/Brand.md index f31555ff..bdb77b5c 100644 --- a/docs/schemata/Brand.md +++ b/docs/schemata/Brand.md @@ -1,6 +1,6 @@ --- title: Brand -nav_order: 21 +nav_order: 22 parent: schemata --- diff --git a/docs/schemata/CamelCaseKeys.md b/docs/schemata/CamelCaseKeys.md index 5df8eab2..32a37a7d 100644 --- a/docs/schemata/CamelCaseKeys.md +++ b/docs/schemata/CamelCaseKeys.md @@ -1,6 +1,6 @@ --- title: CamelCaseKeys -nav_order: 22 +nav_order: 23 parent: schemata --- diff --git a/docs/schemata/CamelCaseRecord.md b/docs/schemata/CamelCaseRecord.md index 45d0e930..c2e1ca83 100644 --- a/docs/schemata/CamelCaseRecord.md +++ b/docs/schemata/CamelCaseRecord.md @@ -1,6 +1,6 @@ --- title: CamelCaseRecord -nav_order: 23 +nav_order: 24 parent: schemata --- diff --git a/docs/schemata/CamelCaseString.md b/docs/schemata/CamelCaseString.md index 80030ecc..1c757ce5 100644 --- a/docs/schemata/CamelCaseString.md +++ b/docs/schemata/CamelCaseString.md @@ -1,6 +1,6 @@ --- title: CamelCaseString -nav_order: 24 +nav_order: 25 parent: schemata --- diff --git a/docs/schemata/CheckDigit.md b/docs/schemata/CheckDigit.md index 33589c2f..9b9d98f3 100644 --- a/docs/schemata/CheckDigit.md +++ b/docs/schemata/CheckDigit.md @@ -1,6 +1,6 @@ --- title: CheckDigit -nav_order: 25 +nav_order: 26 parent: schemata --- diff --git a/docs/schemata/CreditCard.md b/docs/schemata/CreditCard.md index fe9157e3..37d3bc27 100644 --- a/docs/schemata/CreditCard.md +++ b/docs/schemata/CreditCard.md @@ -1,6 +1,6 @@ --- title: CreditCard -nav_order: 26 +nav_order: 27 parent: schemata --- diff --git a/docs/schemata/Date.md b/docs/schemata/Date.md index d7adce20..ff13e054 100644 --- a/docs/schemata/Date.md +++ b/docs/schemata/Date.md @@ -1,6 +1,6 @@ --- title: Date -nav_order: 27 +nav_order: 28 parent: schemata --- diff --git a/docs/schemata/DateFromInt.md b/docs/schemata/DateFromInt.md index 083c5168..03a5cd81 100644 --- a/docs/schemata/DateFromInt.md +++ b/docs/schemata/DateFromInt.md @@ -1,6 +1,6 @@ --- title: DateFromInt -nav_order: 28 +nav_order: 29 parent: schemata --- diff --git a/docs/schemata/DateFromIsoString.md b/docs/schemata/DateFromIsoString.md index 7fb03a38..5c27cd47 100644 --- a/docs/schemata/DateFromIsoString.md +++ b/docs/schemata/DateFromIsoString.md @@ -1,6 +1,6 @@ --- title: DateFromIsoString -nav_order: 29 +nav_order: 30 parent: schemata --- diff --git a/docs/schemata/DateFromString.md b/docs/schemata/DateFromString.md index af1c603c..c3d6efde 100644 --- a/docs/schemata/DateFromString.md +++ b/docs/schemata/DateFromString.md @@ -1,6 +1,6 @@ --- title: DateFromString -nav_order: 30 +nav_order: 31 parent: schemata --- diff --git a/docs/schemata/DateFromUnixTime.md b/docs/schemata/DateFromUnixTime.md index 86fa9c0e..37bc311b 100644 --- a/docs/schemata/DateFromUnixTime.md +++ b/docs/schemata/DateFromUnixTime.md @@ -1,6 +1,6 @@ --- title: DateFromUnixTime -nav_order: 31 +nav_order: 32 parent: schemata --- diff --git a/docs/schemata/Either.md b/docs/schemata/Either.md index 50f8c35f..16c94b4a 100644 --- a/docs/schemata/Either.md +++ b/docs/schemata/Either.md @@ -1,6 +1,6 @@ --- title: Either -nav_order: 32 +nav_order: 33 parent: schemata --- diff --git a/docs/schemata/EmailAddress.md b/docs/schemata/EmailAddress.md index 9dbb9fd2..33b4cff4 100644 --- a/docs/schemata/EmailAddress.md +++ b/docs/schemata/EmailAddress.md @@ -1,6 +1,6 @@ --- title: EmailAddress -nav_order: 33 +nav_order: 34 parent: schemata --- diff --git a/docs/schemata/EthereumAddress.md b/docs/schemata/EthereumAddress.md index da6cf9e8..1916d681 100644 --- a/docs/schemata/EthereumAddress.md +++ b/docs/schemata/EthereumAddress.md @@ -1,6 +1,6 @@ --- title: EthereumAddress -nav_order: 34 +nav_order: 35 parent: schemata --- diff --git a/docs/schemata/Float.md b/docs/schemata/Float.md index 2245aa93..f45680fd 100644 --- a/docs/schemata/Float.md +++ b/docs/schemata/Float.md @@ -1,6 +1,6 @@ --- title: Float -nav_order: 35 +nav_order: 36 parent: schemata --- diff --git a/docs/schemata/FloatFromString.md b/docs/schemata/FloatFromString.md index a42c47cd..1cf4bc7c 100644 --- a/docs/schemata/FloatFromString.md +++ b/docs/schemata/FloatFromString.md @@ -1,6 +1,6 @@ --- title: FloatFromString -nav_order: 36 +nav_order: 37 parent: schemata --- diff --git a/docs/schemata/HexColor.md b/docs/schemata/HexColor.md index 9269c26c..26acfaa0 100644 --- a/docs/schemata/HexColor.md +++ b/docs/schemata/HexColor.md @@ -1,6 +1,6 @@ --- title: HexColor -nav_order: 38 +nav_order: 39 parent: schemata --- diff --git a/docs/schemata/Hexadecimal.md b/docs/schemata/Hexadecimal.md index 692983bd..f8e46200 100644 --- a/docs/schemata/Hexadecimal.md +++ b/docs/schemata/Hexadecimal.md @@ -1,6 +1,6 @@ --- title: Hexadecimal -nav_order: 37 +nav_order: 38 parent: schemata --- diff --git a/docs/schemata/HslColor.md b/docs/schemata/HslColor.md index 4fecede8..85660653 100644 --- a/docs/schemata/HslColor.md +++ b/docs/schemata/HslColor.md @@ -1,6 +1,6 @@ --- title: HslColor -nav_order: 39 +nav_order: 40 parent: schemata --- diff --git a/docs/schemata/Imap.md b/docs/schemata/Imap.md index 064224c4..c8d365ab 100644 --- a/docs/schemata/Imap.md +++ b/docs/schemata/Imap.md @@ -1,6 +1,6 @@ --- title: Imap -nav_order: 40 +nav_order: 41 parent: schemata --- diff --git a/docs/schemata/Int.md b/docs/schemata/Int.md index 4353b581..1dd3a48f 100644 --- a/docs/schemata/Int.md +++ b/docs/schemata/Int.md @@ -1,6 +1,6 @@ --- title: Int -nav_order: 42 +nav_order: 43 parent: schemata --- diff --git a/docs/schemata/IntFromString.md b/docs/schemata/IntFromString.md index 00404790..03df8b13 100644 --- a/docs/schemata/IntFromString.md +++ b/docs/schemata/IntFromString.md @@ -1,6 +1,6 @@ --- title: IntFromString -nav_order: 44 +nav_order: 45 parent: schemata --- diff --git a/docs/schemata/Intersect.md b/docs/schemata/Intersect.md index cb59e299..6b32a05d 100644 --- a/docs/schemata/Intersect.md +++ b/docs/schemata/Intersect.md @@ -1,6 +1,6 @@ --- title: Intersect -nav_order: 43 +nav_order: 44 parent: schemata --- diff --git a/docs/schemata/Jwt.md b/docs/schemata/Jwt.md index e5d25a00..cc845b29 100644 --- a/docs/schemata/Jwt.md +++ b/docs/schemata/Jwt.md @@ -1,6 +1,6 @@ --- title: Jwt -nav_order: 45 +nav_order: 46 parent: schemata --- diff --git a/docs/schemata/LatLong.md b/docs/schemata/LatLong.md index 4dc37b94..6c4385d0 100644 --- a/docs/schemata/LatLong.md +++ b/docs/schemata/LatLong.md @@ -1,6 +1,6 @@ --- title: LatLong -nav_order: 46 +nav_order: 47 parent: schemata --- diff --git a/docs/schemata/Lazy.md b/docs/schemata/Lazy.md index cd423a4c..847d4c11 100644 --- a/docs/schemata/Lazy.md +++ b/docs/schemata/Lazy.md @@ -1,6 +1,6 @@ --- title: Lazy -nav_order: 47 +nav_order: 48 parent: schemata --- diff --git a/docs/schemata/Literal.md b/docs/schemata/Literal.md index a55b5116..ba7cce2d 100644 --- a/docs/schemata/Literal.md +++ b/docs/schemata/Literal.md @@ -1,6 +1,6 @@ --- title: Literal -nav_order: 48 +nav_order: 49 parent: schemata --- diff --git a/docs/schemata/MapFromEntries.md b/docs/schemata/MapFromEntries.md index 1f1f722c..414f285e 100644 --- a/docs/schemata/MapFromEntries.md +++ b/docs/schemata/MapFromEntries.md @@ -1,6 +1,6 @@ --- title: MapFromEntries -nav_order: 49 +nav_order: 50 parent: schemata --- diff --git a/docs/schemata/Natural.md b/docs/schemata/Natural.md index fb6435f5..1e70a1ca 100644 --- a/docs/schemata/Natural.md +++ b/docs/schemata/Natural.md @@ -1,6 +1,6 @@ --- title: Natural -nav_order: 50 +nav_order: 51 parent: schemata --- diff --git a/docs/schemata/NegativeFloat.md b/docs/schemata/NegativeFloat.md index 02ec1e36..9022d577 100644 --- a/docs/schemata/NegativeFloat.md +++ b/docs/schemata/NegativeFloat.md @@ -1,6 +1,6 @@ --- title: NegativeFloat -nav_order: 51 +nav_order: 52 parent: schemata --- diff --git a/docs/schemata/NegativeInt.md b/docs/schemata/NegativeInt.md index 55c2ee7b..ebb04b91 100644 --- a/docs/schemata/NegativeInt.md +++ b/docs/schemata/NegativeInt.md @@ -1,6 +1,6 @@ --- title: NegativeInt -nav_order: 52 +nav_order: 53 parent: schemata --- diff --git a/docs/schemata/Newtype.md b/docs/schemata/Newtype.md index e4e6a5e7..a25e77c4 100644 --- a/docs/schemata/Newtype.md +++ b/docs/schemata/Newtype.md @@ -1,6 +1,6 @@ --- title: Newtype -nav_order: 53 +nav_order: 54 parent: schemata --- diff --git a/docs/schemata/NonEmptyArray.md b/docs/schemata/NonEmptyArray.md index 4ca3e407..113cc61a 100644 --- a/docs/schemata/NonEmptyArray.md +++ b/docs/schemata/NonEmptyArray.md @@ -1,6 +1,6 @@ --- title: NonEmptyArray -nav_order: 54 +nav_order: 55 parent: schemata --- diff --git a/docs/schemata/NonEmptyString.md b/docs/schemata/NonEmptyString.md index c3789357..5661f86f 100644 --- a/docs/schemata/NonEmptyString.md +++ b/docs/schemata/NonEmptyString.md @@ -1,6 +1,6 @@ --- title: NonEmptyString -nav_order: 55 +nav_order: 56 parent: schemata --- diff --git a/docs/schemata/NonNegativeFloat.md b/docs/schemata/NonNegativeFloat.md index ffb9a1f0..574b635c 100644 --- a/docs/schemata/NonNegativeFloat.md +++ b/docs/schemata/NonNegativeFloat.md @@ -1,6 +1,6 @@ --- title: NonNegativeFloat -nav_order: 56 +nav_order: 57 parent: schemata --- diff --git a/docs/schemata/NonPositiveFloat.md b/docs/schemata/NonPositiveFloat.md index d9dd4f21..ce1a1004 100644 --- a/docs/schemata/NonPositiveFloat.md +++ b/docs/schemata/NonPositiveFloat.md @@ -1,6 +1,6 @@ --- title: NonPositiveFloat -nav_order: 57 +nav_order: 58 parent: schemata --- diff --git a/docs/schemata/NonPositiveInt.md b/docs/schemata/NonPositiveInt.md index 1ba0489b..e40f030c 100644 --- a/docs/schemata/NonPositiveInt.md +++ b/docs/schemata/NonPositiveInt.md @@ -1,6 +1,6 @@ --- title: NonPositiveInt -nav_order: 58 +nav_order: 59 parent: schemata --- diff --git a/docs/schemata/Nullable.md b/docs/schemata/Nullable.md index 7b772c99..c64f30b5 100644 --- a/docs/schemata/Nullable.md +++ b/docs/schemata/Nullable.md @@ -1,6 +1,6 @@ --- title: Nullable -nav_order: 59 +nav_order: 60 parent: schemata --- diff --git a/docs/schemata/Number.md b/docs/schemata/Number.md index ce46b29b..328ce62a 100644 --- a/docs/schemata/Number.md +++ b/docs/schemata/Number.md @@ -1,6 +1,6 @@ --- title: Number -nav_order: 60 +nav_order: 61 parent: schemata --- diff --git a/docs/schemata/Option.md b/docs/schemata/Option.md index 2332faf1..0447a985 100644 --- a/docs/schemata/Option.md +++ b/docs/schemata/Option.md @@ -1,6 +1,6 @@ --- title: Option -nav_order: 61 +nav_order: 62 parent: schemata --- diff --git a/docs/schemata/OptionFromNullable.md b/docs/schemata/OptionFromNullable.md index 1bbf6246..fd820106 100644 --- a/docs/schemata/OptionFromNullable.md +++ b/docs/schemata/OptionFromNullable.md @@ -1,6 +1,6 @@ --- title: OptionFromNullable -nav_order: 63 +nav_order: 64 parent: schemata --- diff --git a/docs/schemata/Optional.md b/docs/schemata/Optional.md index 8b5b081d..a53b6b2d 100644 --- a/docs/schemata/Optional.md +++ b/docs/schemata/Optional.md @@ -1,6 +1,6 @@ --- title: Optional -nav_order: 62 +nav_order: 63 parent: schemata --- diff --git a/docs/schemata/Parse.md b/docs/schemata/Parse.md index d39b6930..5fd6ed22 100644 --- a/docs/schemata/Parse.md +++ b/docs/schemata/Parse.md @@ -1,6 +1,6 @@ --- title: Parse -nav_order: 64 +nav_order: 65 parent: schemata --- diff --git a/docs/schemata/ParseBase64Json.md b/docs/schemata/ParseBase64Json.md index 7d58c6fd..1edffbca 100644 --- a/docs/schemata/ParseBase64Json.md +++ b/docs/schemata/ParseBase64Json.md @@ -1,6 +1,6 @@ --- title: ParseBase64Json -nav_order: 65 +nav_order: 66 parent: schemata --- diff --git a/docs/schemata/ParseEncodedJson.md b/docs/schemata/ParseEncodedJson.md index 09669574..3d3ac6ad 100644 --- a/docs/schemata/ParseEncodedJson.md +++ b/docs/schemata/ParseEncodedJson.md @@ -1,6 +1,6 @@ --- title: ParseEncodedJson -nav_order: 66 +nav_order: 67 parent: schemata --- diff --git a/docs/schemata/ParseJsonString.md b/docs/schemata/ParseJsonString.md index 3a416e5a..90df8a42 100644 --- a/docs/schemata/ParseJsonString.md +++ b/docs/schemata/ParseJsonString.md @@ -1,6 +1,6 @@ --- title: ParseJsonString -nav_order: 67 +nav_order: 68 parent: schemata --- diff --git a/docs/schemata/Partial.md b/docs/schemata/Partial.md index 12bbc589..55684b3f 100644 --- a/docs/schemata/Partial.md +++ b/docs/schemata/Partial.md @@ -1,6 +1,6 @@ --- title: Partial -nav_order: 68 +nav_order: 69 parent: schemata --- diff --git a/docs/schemata/Pattern.md b/docs/schemata/Pattern.md index d1f72c91..4d14bb82 100644 --- a/docs/schemata/Pattern.md +++ b/docs/schemata/Pattern.md @@ -1,6 +1,6 @@ --- title: Pattern -nav_order: 69 +nav_order: 70 parent: schemata --- diff --git a/docs/schemata/PositiveFloat.md b/docs/schemata/PositiveFloat.md index ae7e4d7b..ef59bce3 100644 --- a/docs/schemata/PositiveFloat.md +++ b/docs/schemata/PositiveFloat.md @@ -1,6 +1,6 @@ --- title: PositiveFloat -nav_order: 70 +nav_order: 71 parent: schemata --- diff --git a/docs/schemata/PositiveInt.md b/docs/schemata/PositiveInt.md index 5ea903e4..c054d47a 100644 --- a/docs/schemata/PositiveInt.md +++ b/docs/schemata/PositiveInt.md @@ -1,6 +1,6 @@ --- title: PositiveInt -nav_order: 71 +nav_order: 72 parent: schemata --- diff --git a/docs/schemata/RGB.md b/docs/schemata/RGB.md index cdc31e31..99c640ec 100644 --- a/docs/schemata/RGB.md +++ b/docs/schemata/RGB.md @@ -1,6 +1,6 @@ --- title: RGB -nav_order: 75 +nav_order: 76 parent: schemata --- diff --git a/docs/schemata/Readonly.md b/docs/schemata/Readonly.md index 08537614..3657b5ba 100644 --- a/docs/schemata/Readonly.md +++ b/docs/schemata/Readonly.md @@ -1,6 +1,6 @@ --- title: Readonly -nav_order: 72 +nav_order: 73 parent: schemata --- diff --git a/docs/schemata/Record.md b/docs/schemata/Record.md index 135b0638..3b49d7f3 100644 --- a/docs/schemata/Record.md +++ b/docs/schemata/Record.md @@ -1,6 +1,6 @@ --- title: Record -nav_order: 73 +nav_order: 74 parent: schemata --- diff --git a/docs/schemata/Refine.md b/docs/schemata/Refine.md index 1e7a6a17..ae27a75c 100644 --- a/docs/schemata/Refine.md +++ b/docs/schemata/Refine.md @@ -1,6 +1,6 @@ --- title: Refine -nav_order: 74 +nav_order: 75 parent: schemata --- diff --git a/docs/schemata/SetFromArray.md b/docs/schemata/SetFromArray.md index 2e9041d8..f6de3325 100644 --- a/docs/schemata/SetFromArray.md +++ b/docs/schemata/SetFromArray.md @@ -1,6 +1,6 @@ --- title: SetFromArray -nav_order: 76 +nav_order: 77 parent: schemata --- diff --git a/docs/schemata/Strict.md b/docs/schemata/Strict.md index 25b31b67..99338c99 100644 --- a/docs/schemata/Strict.md +++ b/docs/schemata/Strict.md @@ -1,6 +1,6 @@ --- title: Strict -nav_order: 77 +nav_order: 78 parent: schemata --- diff --git a/docs/schemata/String.md b/docs/schemata/String.md index a4a1f125..cae84938 100644 --- a/docs/schemata/String.md +++ b/docs/schemata/String.md @@ -1,6 +1,6 @@ --- title: String -nav_order: 78 +nav_order: 79 parent: schemata --- diff --git a/docs/schemata/Struct.md b/docs/schemata/Struct.md index 9b843f1d..ac6381c2 100644 --- a/docs/schemata/Struct.md +++ b/docs/schemata/Struct.md @@ -1,6 +1,6 @@ --- title: Struct -nav_order: 79 +nav_order: 80 parent: schemata --- diff --git a/docs/schemata/Tuple.md b/docs/schemata/Tuple.md index 83506c35..d9224b44 100644 --- a/docs/schemata/Tuple.md +++ b/docs/schemata/Tuple.md @@ -1,6 +1,6 @@ --- title: Tuple -nav_order: 80 +nav_order: 81 parent: schemata --- diff --git a/docs/schemata/UUID.md b/docs/schemata/UUID.md index 6a8cd5c7..6b163195 100644 --- a/docs/schemata/UUID.md +++ b/docs/schemata/UUID.md @@ -1,6 +1,6 @@ --- title: UUID -nav_order: 86 +nav_order: 87 parent: schemata --- diff --git a/docs/schemata/Union.md b/docs/schemata/Union.md index 075e1ba6..bd477498 100644 --- a/docs/schemata/Union.md +++ b/docs/schemata/Union.md @@ -1,6 +1,6 @@ --- title: Union -nav_order: 81 +nav_order: 82 parent: schemata --- diff --git a/docs/schemata/Unit.md b/docs/schemata/Unit.md index f24dbcb8..86bc79db 100644 --- a/docs/schemata/Unit.md +++ b/docs/schemata/Unit.md @@ -1,6 +1,6 @@ --- title: Unit -nav_order: 82 +nav_order: 83 parent: schemata --- diff --git a/docs/schemata/Unknown.md b/docs/schemata/Unknown.md index 4f8a2e63..08708662 100644 --- a/docs/schemata/Unknown.md +++ b/docs/schemata/Unknown.md @@ -1,6 +1,6 @@ --- title: Unknown -nav_order: 83 +nav_order: 84 parent: schemata --- diff --git a/docs/schemata/UnknownArray.md b/docs/schemata/UnknownArray.md index 3d167d9b..08b6b78c 100644 --- a/docs/schemata/UnknownArray.md +++ b/docs/schemata/UnknownArray.md @@ -1,6 +1,6 @@ --- title: UnknownArray -nav_order: 84 +nav_order: 85 parent: schemata --- diff --git a/docs/schemata/UnknownRecord.md b/docs/schemata/UnknownRecord.md index 981cf59f..e47e283a 100644 --- a/docs/schemata/UnknownRecord.md +++ b/docs/schemata/UnknownRecord.md @@ -1,6 +1,6 @@ --- title: UnknownRecord -nav_order: 85 +nav_order: 86 parent: schemata --- diff --git a/docs/schemata/index.md b/docs/schemata/index.md index 84b840d0..0e739302 100644 --- a/docs/schemata/index.md +++ b/docs/schemata/index.md @@ -82,23 +82,23 @@ has_children: true ### String (17) -* Ascii ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Ascii.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Ascii.ts)) (e.g: `~RzlW9n=`, `A|.y]`, `|~wi^)|`) -* Base64 ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Base64.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Base64.ts)) (e.g: `d+J/2/C0/e+6++jC3++=`, `/+r449yX+/2+`, `K//+l+moTG+c0qX/7+++N3+++3/A4/PK`) -* Base64Url ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Base64Url.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Base64Url.ts)) (e.g: `D1AT-p6`, `2q-1-yc0C_`, `-tQ_uT_-_4`) -* BitcoinAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/BitcoinAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/BitcoinAddress.ts)) (e.g: `bc1ylybl1cr798dcai2z313vi2d2bbcz023fd2zw`, `bc1u0f4w6j4ffz0l9uq39lca4d2me6qz10t`, `bc1bz25560kt237c85xytn2452a3l08755557`) +* Ascii ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Ascii.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Ascii.ts)) (e.g: `l4~1`, `)|z~}`, `O4Z@`) +* Base64 ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Base64.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Base64.ts)) (e.g: `eQ+++05/dp/+9j+3dl+6aw+/zU5/O6d/+6e9lQv8`, `+n///Yv+bx0=`, `9/S/AW+2/e3Zfmx/eBEexHEe5x5+f+BTt1p=`) +* Base64Url ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Base64Url.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Base64Url.ts)) (e.g: `e__9-I`, `3_-a_-_X`, `_T-7--_-5`) +* BitcoinAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/BitcoinAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/BitcoinAddress.ts)) (e.g: `3kYASqPstWdVZA65uoVuAEFMg4TvAUekJXXNHRS`, `bc1f1y0a3ada9cc5a04z1523qa5abeezw92x`, `bc1xe0u2z02awy802i2o1d64c321ra3`) * CamelCaseString ([docs](https://jacob-alford.github.io/schemata-ts/schemata/CamelCaseString.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/CamelCaseString.ts)) (e.g: `Camel_case-string` → `camelCaseString`) -* CreditCard ([docs](https://jacob-alford.github.io/schemata-ts/schemata/CreditCard.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/CreditCard.ts)) (e.g: `50828982804187171`, `650839232707231898`, `656700805495129821`) -* EmailAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/EmailAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/EmailAddress.ts)) (e.g: `{#?=b&_~??./?{$-/@..mWz`, `+/.u{=%?&^'.-'^B5=}!+1._+*.|}?.#}$|=#.*}#^B.6^#!.q'--=^/#~.*~%#}@[563.33.07.57]`, `"ﭼ"@P.-.19q-e672q.-6I-8.6-Fv0C-k.-Jcd.6-uS.fMrlmUZjdiHi`) -* EthereumAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/EthereumAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/EthereumAddress.ts)) (e.g: `0xCc1D30Fa0b23Cc80fCEfAEeAAecEcaBAaa7B8EBD`, `0x8babd8Bf09Cbd32D3dc3ADCbAfbB3AB9BaFc1AEF`, `0xaBAFeaAcDFbAc8eCffb4DEEabBAbBaecF0a2c1BC`) -* HexColor ([docs](https://jacob-alford.github.io/schemata-ts/schemata/HexColor.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/HexColor.ts)) (e.g: `9e8bdaCC`, `ad96cC86`, `DeBBbD`) -* Hexadecimal ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Hexadecimal.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Hexadecimal.ts)) (e.g: `0h4008ab6DD`, `0Hcd7cF7BDfEB`, `FaA5b7a1ae1c`) -* HslColor ([docs](https://jacob-alford.github.io/schemata-ts/schemata/HslColor.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/HslColor.ts)) (e.g: `hsl(458256454,00.233911930e+74%,+000000000.8382e+219%,83772976015e+789640804216%)`, `hsl(-.3274turn,+00.6073%,0.2970851426%,1247238529e249)`, `hsl(.3831130202e+244366761790,+00088%,00.3259556e+384%,79014e11)`) -* Jwt ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Jwt.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Jwt.ts)) (e.g: `d1eG-rLH6._S7_rfx_.wX_R-`, `o9-Qy-._3_-__7D-.Z`, `-a.s.YO_`) -* LatLong ([docs](https://jacob-alford.github.io/schemata-ts/schemata/LatLong.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/LatLong.ts)) (e.g: `(-80,+99)`, `(57,-180.00)`, `(6.83,179)`) -* NonEmptyString ([docs](https://jacob-alford.github.io/schemata-ts/schemata/NonEmptyString.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/NonEmptyString.ts)) (e.g: `k-3`, `IHa9i3W3dd1yNfkTyJ==`, `s~4:K'k:`) -* RGB ([docs](https://jacob-alford.github.io/schemata-ts/schemata/RGB.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/RGB.ts)) (e.g: `rgba(39%,100%,100%,1.0)`, `rgba(120,253,252,1)`, `rgba(100%,100%,100%,1.0)`) +* CreditCard ([docs](https://jacob-alford.github.io/schemata-ts/schemata/CreditCard.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/CreditCard.ts)) (e.g: `8179596818132214`, `3932220044003541706`, `62292072866283597`) +* EmailAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/EmailAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/EmailAddress.ts)) (e.g: `d?|#|_b?.*/.&}@[50.9.0.9]`, `NtI|/.~*-|.={?&'.%+?L*.?$&.=*Q*.&^_!_}&~.}/~}?/_+?'.^*E%|@[26.31.22.62]`, `"￸㶸"@o-.-l-q9.h0-g6QOk..-PVMUK-1-W.6TyUi--S.dwI`) +* EthereumAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/EthereumAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/EthereumAddress.ts)) (e.g: `0x61F4eC9Db99dfA89faAf1bDecFBEaAbDBa7cC4C7`, `0x9CEdea92deBBfdB13851Dd2a2ce6dFF1379ED3F3`, `0x1AEaDfdCACcC202628F6DE9aC19d80505DB3AE4a`) +* HexColor ([docs](https://jacob-alford.github.io/schemata-ts/schemata/HexColor.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/HexColor.ts)) (e.g: `Ac928fd2`, `#3Bfb33`, `#a7CAF29D`) +* Hexadecimal ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Hexadecimal.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Hexadecimal.ts)) (e.g: `d1efc4`, `FCf0B9EB`, `Bb827A`) +* HslColor ([docs](https://jacob-alford.github.io/schemata-ts/schemata/HslColor.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/HslColor.ts)) (e.g: `hsla(-.5317678028e+13965811099turn+51e55475989152%0000000000.037%/39%)`, `hsla(-.2,000100e-5%,+000000000.21998890675%,6715839.158922788)`, `hsl(-0037517617+0000100%0.01%)`) +* Jwt ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Jwt.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Jwt.ts)) (e.g: `..-_lJH_`, `0i8--.eXwxk--_7`, `1_F.VdxTXKlCU`) +* LatLong ([docs](https://jacob-alford.github.io/schemata-ts/schemata/LatLong.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/LatLong.ts)) (e.g: `-2.49281137,92`, `-90.0000,180.000000000`, `90,-120`) +* NonEmptyString ([docs](https://jacob-alford.github.io/schemata-ts/schemata/NonEmptyString.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/NonEmptyString.ts)) (e.g: `0kVIVeCc`, `B.1Av}wn`, `y7namenamepr`) +* RGB ([docs](https://jacob-alford.github.io/schemata-ts/schemata/RGB.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/RGB.ts)) (e.g: `rgb(8,195,252)`, `rgba(100%,3%,100%,1)`, `rgba(100%,99%,99%,0.0367943763)`) * String ([docs](https://jacob-alford.github.io/schemata-ts/schemata/String.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/String.ts)) -* UUID ([docs](https://jacob-alford.github.io/schemata-ts/schemata/UUID.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/UUID.ts)) (e.g: `770E2Eab-aB0A-8aE2-6AB5-DbdD2CCA89CA`, `2BA1DDCd-A3BB-81aF-BA64-dC3afEEdbACC`, `E327f1bB-C3BF-0AE8-bcbc-f2ecbAd0F2A3`) +* UUID ([docs](https://jacob-alford.github.io/schemata-ts/schemata/UUID.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/UUID.ts)) (e.g: `bB98f8ca-ccfd-ed3B-9fB4-b1aeA8009DeC`, `eAbEdEC6-bc5F-eCcB-021f-3FB1c20aCFdB`, `acEEC83c-1F17-dBCb-abfE-3DD1C8Cf8dEB`) ### Unit (1) diff --git a/scripts/docs-config.ts b/scripts/docs-config.ts index d7e928d4..2adc99bb 100644 --- a/scripts/docs-config.ts +++ b/scripts/docs-config.ts @@ -3,6 +3,7 @@ export const SCHEMA_SRC_DIR = './src/schemata' export const SCHEMA_OUT_DIR = './docs/schemata' export const autogeneratedDocs: ReadonlyArray = [ + 'Assert.ts', 'Arbitrary.ts', 'brand.ts', 'Eq.ts', diff --git a/src/Assert.ts b/src/Assert.ts new file mode 100644 index 00000000..d2236181 --- /dev/null +++ b/src/Assert.ts @@ -0,0 +1,81 @@ +/** @since 2.2.0 */ +import * as E from 'fp-ts/Either' +import { deriveGuard, deriveInputGuard } from 'schemata-ts/Guard' +import { type Schema } from 'schemata-ts/Schema' +import { drawTree, safeShow } from 'schemata-ts/TranscodeError' +import { deriveTranscoder } from 'schemata-ts/Transcoder' +import { deriveTypeString } from 'schemata-ts/TypeString' + +/** + * A trait which will throw an error for when a value does not match a schema + * + * @since 2.2.0 + * @category Models + */ +export interface Assert { + readonly assert: (output: unknown) => asserts output is T +} + +/** + * A trait which will throw an error for when an expected "output" value does not match a + * schema's output type + * + * @since 2.2.0 + * @category Interpreters + */ +export const deriveAssert = (schema: Schema): Assert => { + const guard = deriveGuard(schema) + const [, name] = deriveTypeString(schema) + return { + assert: (output): asserts output is O => { + if (!guard.is(output)) { + throw new TypeError(`Expected ${name}, but got ${safeShow(output)}`) + } + }, + } +} + +/** + * A trait which will throw an error for when an expected "input" value does not match a + * schema's input type + * + * @since 2.2.0 + * @category Interpreters + */ +export const deriveInputAssert = (schema: Schema): Assert => { + const guard = deriveInputGuard(schema) + const [name] = deriveTypeString(schema) + return { + assert: (input): asserts input is I => { + if (!guard.is(input)) { + throw new TypeError(`Expected ${name}, but got ${safeShow(input)}`) + } + }, + } +} + +/** + * A trait which will throw an error for when an expected "input" value does not match a + * schema's input type + * + * Unlike `deriveInputAssert`, this will include the error tree in the error message + * + * @since 2.2.0 + * @category Interpreters + */ +export const deriveInputAssertTree = (schema: Schema): Assert => { + const transcoder = deriveTranscoder(schema) + const [name] = deriveTypeString(schema) + return { + assert: (input): asserts input is I => { + const result = transcoder.decode(input) + if (E.isLeft(result)) { + throw new TypeError( + `Expected ${name}, but received the following errors:\n${drawTree(result.left, { + showHeading: false, + })}`, + ) + } + }, + } +} diff --git a/src/TranscodeError.ts b/src/TranscodeError.ts index 71a9c6d9..9c8ec11a 100644 --- a/src/TranscodeError.ts +++ b/src/TranscodeError.ts @@ -386,7 +386,7 @@ const typeOf = (a: unknown): string => { } /** @internal */ -const safeShow = (a: unknown): string => { +export const safeShow = (a: unknown): string => { if ( a instanceof Error || typeof a === 'symbol' || @@ -401,7 +401,20 @@ const safeShow = (a: unknown): string => { return `[Function ${a.name === '' ? '(anonymous)' : a.name}]` const tA = typeOf(a) return pipe( - O.tryCatch(() => JSON.stringify(a, (_, v) => (typeof v === 'bigint' ? `${v}n` : v))), - O.getOrElse(() => `[Circular ${tA}]`), + O.tryCatch(() => { + const seen = new WeakSet() + return JSON.stringify(a, (_, v) => { + if (typeof v === 'object' && v !== null) { + if (seen.has(v)) return `[Circular ${tA}]` + seen.add(v) + } + return typeof v === 'bigint' ? `${v}n` : v + }) + }), + // unreachable case, such as if a circular object does not have a constant reference (???) + O.getOrElse( + // istanbul ignore next + () => `[Circular ${tA}]`, + ), ) } diff --git a/tests/assert.test.ts b/tests/assert.test.ts new file mode 100644 index 00000000..0014f16f --- /dev/null +++ b/tests/assert.test.ts @@ -0,0 +1,135 @@ +import * as S from 'schemata-ts' +import { + deriveAssert, + deriveInputAssert, + deriveInputAssertTree, +} from 'schemata-ts/Assert' +import { type Integer } from 'schemata-ts/integer' + +const Schema = S.Struct({ + foo: S.Union(S.NonEmptyString, S.Boolean), + bar: S.Array(S.Tuple(S.Natural, S.UUID(5)), { minLength: 2, maxLength: 5 }), + baz: S.Record(S.String(), S.Boolean), + qaz: S.Optional(S.UnknownArray), +}) + +type Input = S.InputOf +type Output = S.OutputOf + +describe('Assert', () => { + it('should not assert', () => { + const output: Output = { + foo: ' ' as S.NonEmptyString, + bar: [ + [1 as Integer<0>, S.isoUUID<5>().wrap('00000000-0000-5000-8000-000000000000')], + [2 as Integer<0>, S.isoUUID<5>().wrap('00000000-0000-5000-8000-000000000000')], + ], + baz: { foo: true }, + qaz: undefined, + } + + const assert = deriveAssert(Schema) + + expect(() => assert.assert(output)).not.toThrow() + }) + + it('should assert', () => { + const output: Output = { + foo: true, + bar: [ + [1 as Integer<0>, S.isoUUID<5>().wrap('00000000-0000-5000-8000-000000000000')], + ], + baz: { foo: true }, + qaz: undefined, + } + + output.qaz = [output] + + const assert = deriveAssert(Schema) + + expect(() => assert.assert(output)).toThrow( + new TypeError( + 'Expected { bar: Array[2,5]<[Integer<0,>, UUID version 5]>, baz: Record, foo: string<1,> | boolean, qaz?: Array? },' + + ' but got {"foo":true,"bar":[[1,"00000000-0000-5000-8000-000000000000"]],"baz":{"foo":true},"qaz":["[Circular object]"]}', + ), + ) + }) +}) + +describe('deriveInputAssert', () => { + it('should not assert', () => { + const input: Input = { + foo: ' ' as S.NonEmptyString, + bar: [ + [1 as Integer<0>, '00000000-0000-5000-8000-000000000000'], + [2 as Integer<0>, '00000000-0000-5000-8000-000000000000'], + ], + baz: { foo: true }, + qaz: undefined, + } + + const assert = deriveInputAssert(Schema) + + expect(() => assert.assert(input)).not.toThrow() + }) + + it('should assert', () => { + const input: Input = { + foo: true, + bar: [[1 as Integer<0>, '00000000-0000-5000-8000-000000000000']], + baz: { foo: true }, + qaz: undefined, + } + + input.qaz = [input] + + const assert = deriveInputAssert(Schema) + + expect(() => assert.assert(input)).toThrow( + new TypeError( + 'Expected { bar: Array[2,5]<[Integer<0,>, UUID version 5]>, baz: Record, foo: string<1,> | boolean, qaz?: Array? }, ' + + 'but got {"foo":true,"bar":[[1,"00000000-0000-5000-8000-000000000000"]],"baz":{"foo":true},"qaz":["[Circular object]"]}', + ), + ) + }) +}) + +describe('deriveTreeInputAssert', () => { + it('should not assert', () => { + const input: Input = { + foo: ' ' as S.NonEmptyString, + bar: [ + [1 as Integer<0>, '00000000-0000-5000-8000-000000000000'], + [2 as Integer<0>, '00000000-0000-5000-8000-000000000000'], + ], + baz: { foo: true }, + qaz: undefined, + } + + const assert = deriveInputAssertTree(Schema) + + expect(() => assert.assert(input)).not.toThrow() + }) + + it('should assert', () => { + const input: Input = { + foo: true, + bar: [[1 as Integer<0>, '00000000-0000-5000-8000-000000000000']], + baz: { foo: true }, + qaz: undefined, + } + + input.qaz = [input] + + const assert = deriveInputAssertTree(Schema) + + expect(() => assert.assert(input)).toThrow( + new TypeError( + 'Expected { bar: Array[2,5]<[Integer<0,>, UUID version 5]>, baz: Record, foo: string<1,> | boolean, qaz?: Array? }, ' + + 'but received the following errors:\n' + + '┌ at key bar:\n' + + '└── Expected Array[2,5]<[Integer<0,>, UUID version 5]> but got "Array(1)"', + ), + ) + }) +}) From e8070b7f5b99e4d0173f6b116dff19b73ac77bb9 Mon Sep 17 00:00:00 2001 From: Jacob Alford Date: Wed, 1 Nov 2023 16:35:33 -0600 Subject: [PATCH 03/16] feat(transcode-errors): add string introspection to transcode-errors --- docs/TranscodeError.md | 33 +++++++++++++++++++++++++++++++++ src/TranscodeError.ts | 15 +++++++++++++++ tests/transcode-errors.test.ts | 12 ++++++++++++ 3 files changed, 60 insertions(+) diff --git a/docs/TranscodeError.md b/docs/TranscodeError.md index eb746546..9d2ec301 100644 --- a/docs/TranscodeError.md +++ b/docs/TranscodeError.md @@ -34,6 +34,9 @@ Added in v2.0.0 - [\_tag (property)](#_tag-property-3) - [TranscodeError (type alias)](#transcodeerror-type-alias) - [TranscodeErrors (class)](#transcodeerrors-class) + - [toJSON (method)](#tojson-method) + - [toString (method)](#tostring-method) + - [[Symbol.for('nodejs.util.inspect.custom')] (method)](#symbolfornodejsutilinspectcustom-method) - [\_tag (property)](#_tag-property-4) - [TypeMismatch (class)](#typemismatch-class) - [\_tag (property)](#_tag-property-5) @@ -309,6 +312,36 @@ export declare class TranscodeErrors { Added in v2.0.0 +### toJSON (method) + +**Signature** + +```ts +public toJSON(this: TranscodeErrors) +``` + +Added in v2.2.0 + +### toString (method) + +**Signature** + +```ts +public toString(this: TranscodeErrors) +``` + +Added in v2.2.0 + +### [Symbol.for('nodejs.util.inspect.custom')] (method) + +**Signature** + +```ts +public [Symbol.for('nodejs.util.inspect.custom')](this: TranscodeErrors) +``` + +Added in v2.2.0 + ### \_tag (property) **Signature** diff --git a/src/TranscodeError.ts b/src/TranscodeError.ts index 9c8ec11a..b6cf30ea 100644 --- a/src/TranscodeError.ts +++ b/src/TranscodeError.ts @@ -35,6 +35,21 @@ export class TranscodeErrors { /** @since 2.0.0 */ readonly _tag = 'TranscodeErrors' constructor(readonly errors: RNEA.ReadonlyNonEmptyArray) {} + + /** @since 2.2.0 */ + public toJSON(this: TranscodeErrors) { + return draw(this) + } + + /** @since 2.2.0 */ + public toString(this: TranscodeErrors) { + return draw(this) + } + + /** @since 2.2.0 */ + public [Symbol.for('nodejs.util.inspect.custom')](this: TranscodeErrors) { + return draw(this) + } } /** diff --git a/tests/transcode-errors.test.ts b/tests/transcode-errors.test.ts index a76800ff..7c344af5 100644 --- a/tests/transcode-errors.test.ts +++ b/tests/transcode-errors.test.ts @@ -2,6 +2,7 @@ import * as E from 'fp-ts/Either' import * as S from 'schemata-ts' import { drawTree } from 'schemata-ts/TranscodeError' import * as TC from 'schemata-ts/Transcoder' +import * as util from 'util' const Schema = S.Strict({ foo: S.Union(S.NonEmptyString, S.Boolean), @@ -156,4 +157,15 @@ describe('transcode errors', () => { `─ Expected string but got {"foo":{"bar":{"baz":"42n"}}}`, ) }) + describe('introspection', () => { + test('JSON.stringify', () => { + expect(JSON.stringify(result.left)).toBe(JSON.stringify(expectedError)) + }) + test('toString', () => { + expect(result.left.toString()).toBe(expectedError) + }) + test('inspect', () => { + expect(util.inspect(result.left)).toBe(expectedError) + }) + }) }) From 11999d53160c7de04042a61e60d4920f2fd8a569 Mon Sep 17 00:00:00 2001 From: Jacob Alford Date: Mon, 16 Oct 2023 19:39:12 -0600 Subject: [PATCH 04/16] feat(array): add ArraySchema Schema transformer --- docs/schemata/Array.md | 65 +++++++++++++++++++++++- docs/schemata/NonEmptyArray.md | 4 +- src/schemata/Array.ts | 90 ++++++++++++++++++++++++++-------- src/schemata/NonEmptyArray.ts | 1 + tests/Array.test.ts | 27 ++++++++++ 5 files changed, 164 insertions(+), 23 deletions(-) diff --git a/docs/schemata/Array.md b/docs/schemata/Array.md index 7c2c7705..9836fac9 100644 --- a/docs/schemata/Array.md +++ b/docs/schemata/Array.md @@ -14,6 +14,11 @@ Added in v1.4.0 - [Combinators](#combinators) - [Array](#array) +- [Transformations](#transformations) + - [ArraySchema (class)](#arrayschema-class) + - [minLength (property)](#minlength-property) + - [maxLength (property)](#maxlength-property) + - [nonEmpty (property)](#nonempty-property) --- @@ -26,7 +31,65 @@ An array type of known values. **Signature** ```ts -export declare const Array: (codomain: Schema, params?: ArrayParams) => Schema +export declare const Array: (codomain: Schema, params?: ArrayParams | undefined) => ArraySchema ``` Added in v1.0.0 + +# Transformations + +## ArraySchema (class) + +The ArraySchema schema transformer, to construct an ArraySchema use `S.Array` combinator instead. + +**Signature** + +```ts +export declare class ArraySchema { + constructor(private readonly codomain: Schema, private readonly params: ArrayParams = {}) +} +``` + +Added in v2.2.0 + +### minLength (property) + +Requires a minimum array length + +Returns a new ArraySchema + +**Signature** + +```ts +readonly minLength: (minLength: number) => ArraySchema +``` + +Added in v2.2.0 + +### maxLength (property) + +Requires a maximum array length + +Returns a new ArraySchema + +**Signature** + +```ts +readonly maxLength: (maxLength: number) => ArraySchema +``` + +Added in v2.2.0 + +### nonEmpty (property) + +Converts an array schema to a non-empty array schema + +Returns a new Schema + +**Signature** + +```ts +readonly nonEmpty: () => Schema, RNEA.ReadonlyNonEmptyArray> +``` + +Added in v2.2.0 diff --git a/docs/schemata/NonEmptyArray.md b/docs/schemata/NonEmptyArray.md index 113cc61a..da70d140 100644 --- a/docs/schemata/NonEmptyArray.md +++ b/docs/schemata/NonEmptyArray.md @@ -13,13 +13,13 @@ Added in v1.1.0

Table of contents

- [Combinators](#combinators) - - [NonEmptyArray](#nonemptyarray) + - [~~NonEmptyArray~~](#nonemptyarray) --- # Combinators -## NonEmptyArray +## ~~NonEmptyArray~~ A read-only Array containing one or more elements. diff --git a/src/schemata/Array.ts b/src/schemata/Array.ts index 54373e92..1359a48a 100644 --- a/src/schemata/Array.ts +++ b/src/schemata/Array.ts @@ -1,8 +1,8 @@ /** @since 1.4.0 */ -import { pipe } from 'fp-ts/function' +import { pipe, unsafeCoerce } from 'fp-ts/function' +import type * as RNEA from 'fp-ts/ReadonlyNonEmptyArray' import { deriveTypeString } from 'schemata-ts/derivations/type-string-schemable' -import { make } from 'schemata-ts/internal/schema' -import { type Schema } from 'schemata-ts/Schema' +import { type Schema, SchemaImplementation } from 'schemata-ts/Schema' import { ArrayTypeString } from 'schemata-ts/schemables/array/instances/type-string' type ArrayParams = { @@ -17,21 +17,71 @@ type ArrayParams = { * @since 1.0.0 * @category Combinators */ -export const Array = ( - codomain: Schema, - params: ArrayParams = {}, -): Schema, ReadonlyArray> => { - const { errorName: errorName_ } = params - const expectedName = - errorName_ ?? - pipe( - deriveTypeString(codomain), - ArrayTypeString.array({ ...params, expectedName: '' }), - )[0] - return make(_ => - _.array({ - ...params, - expectedName, - })(codomain.runSchema(_)), - ) +export const Array = ( + codomain: Schema, + params?: ArrayParams, +): ArraySchema => new ArraySchema(codomain, params) + +/** + * The ArraySchema schema transformer, to construct an ArraySchema use `S.Array` combinator instead. + * + * @since 2.2.0 + * @category Transformations + */ +export class ArraySchema extends SchemaImplementation< + ReadonlyArray, + ReadonlyArray +> { + constructor( + private readonly codomain: Schema, + private readonly params: ArrayParams = {}, + ) { + const { errorName: errorName_ } = params + + const expectedName = + errorName_ ?? + pipe( + deriveTypeString(codomain), + ArrayTypeString.array({ ...params, expectedName: '' }), + )[0] + + super(_ => + _.array({ + ...params, + expectedName, + })(codomain.runSchema(_)), + ) + } + + /** + * Requires a minimum array length + * + * Returns a new ArraySchema + * + * @since 2.2.0 + */ + public readonly minLength: (minLength: number) => ArraySchema = minLength => + new ArraySchema(this.codomain, { ...this.params, minLength }) + + /** + * Requires a maximum array length + * + * Returns a new ArraySchema + * + * @since 2.2.0 + */ + public readonly maxLength: (maxLength: number) => ArraySchema = maxLength => + new ArraySchema(this.codomain, { ...this.params, maxLength }) + + /** + * Converts an array schema to a non-empty array schema + * + * Returns a new Schema + * + * @since 2.2.0 + */ + public readonly nonEmpty: () => Schema< + RNEA.ReadonlyNonEmptyArray, + RNEA.ReadonlyNonEmptyArray + > = () => unsafeCoerce(this.minLength(1)) } diff --git a/src/schemata/NonEmptyArray.ts b/src/schemata/NonEmptyArray.ts index 7a2636d5..42ff0407 100644 --- a/src/schemata/NonEmptyArray.ts +++ b/src/schemata/NonEmptyArray.ts @@ -6,6 +6,7 @@ import { Array as ArrayS } from 'schemata-ts/schemata/Array' /** * A read-only Array containing one or more elements. * + * @deprecated Use `Array().nonEmpty()` instead * @since 1.1.0 * @category Combinators */ diff --git a/tests/Array.test.ts b/tests/Array.test.ts index 03829535..e4cec46c 100644 --- a/tests/Array.test.ts +++ b/tests/Array.test.ts @@ -1,4 +1,7 @@ +import { expectTypeOf } from 'expect-type' +import type * as RNEA from 'fp-ts/ReadonlyNonEmptyArray' import * as S from 'schemata-ts' +import { type Integer } from 'schemata-ts/integer' import * as JS from 'schemata-ts/JsonSchema' import * as TC from 'schemata-ts/Transcoder' @@ -106,3 +109,27 @@ runStandardTestSuite(S.Tuple(), () => ({ typeString: '[]', jsonSchema: JS.tuple(), }))() + +const SchemaModiferTest_ = S.Array(S.Natural).maxLength(5) + +test('SchemaModiferTest_', () => { + expectTypeOf(SchemaModiferTest_).toMatchTypeOf>>>() +}) + +const SchemaModiferTest = SchemaModiferTest_.nonEmpty() + +test('SchemaModiferTest', () => { + expectTypeOf(SchemaModiferTest).toMatchTypeOf< + S.Schema>> + >() +}) + +runStandardTestSuite(SchemaModiferTest, _ => ({ + decoderTests: [ + _.decoder.pass([0]), + _.decoder.pass([1, 2, 3, 4, 5]), + _.decoder.fail([1, 2, 3, 4, 5, 6], () => + TC.transcodeErrors(TC.typeMismatch('Array[1,5]>', 'Array(6)')), + ), + ], +}))() From 5c24b770af6095f78560d9134a29f6f73463da5f Mon Sep 17 00:00:00 2001 From: Jacob Alford Date: Wed, 18 Oct 2023 19:21:54 -0600 Subject: [PATCH 05/16] feat(Class): add Class schema --- docs/schemata/Class.md | 36 ++++++++++++++++++++++++++++++++++++ docs/schemata/index.md | 3 ++- src/schemata/Class.ts | 22 ++++++++++++++++++++++ src/schemata/index.ts | 1 + tests/Class.test.ts | 22 ++++++++++++++++++++++ 5 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 docs/schemata/Class.md create mode 100644 src/schemata/Class.ts create mode 100644 tests/Class.test.ts diff --git a/docs/schemata/Class.md b/docs/schemata/Class.md new file mode 100644 index 00000000..57b57bb7 --- /dev/null +++ b/docs/schemata/Class.md @@ -0,0 +1,36 @@ +--- +title: Class +nav_order: 26 +parent: schemata +--- + +## Class overview + +Added in v2.2.0 + +--- + +

Table of contents

+ +- [Combinators](#combinators) + - [Class](#class) + +--- + +# Combinators + +## Class + +A schema combinator which transforms the output type of a schema to a specified class + +**Signature** + +```ts +export declare const Class: ( + constructor: new (...args: ReadonlyArray) => T, + toClass: (output: O) => T, + fromClass: (class_: T) => O +) => (schema: Schema) => Schema +``` + +Added in v2.2.0 diff --git a/docs/schemata/index.md b/docs/schemata/index.md index 0e739302..e73ec054 100644 --- a/docs/schemata/index.md +++ b/docs/schemata/index.md @@ -9,7 +9,7 @@ has_children: true * Boolean ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Boolean.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Boolean.ts)) -### Combinators (27) +### Combinators (28) * Annotate ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Annotate.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Annotate.ts)) * Array ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Array.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Array.ts)) @@ -17,6 +17,7 @@ has_children: true * CamelCaseKeys ([docs](https://jacob-alford.github.io/schemata-ts/schemata/CamelCaseKeys.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/CamelCaseKeys.ts)) * CamelCaseRecord ([docs](https://jacob-alford.github.io/schemata-ts/schemata/CamelCaseRecord.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/CamelCaseRecord.ts)) * CheckDigit ([docs](https://jacob-alford.github.io/schemata-ts/schemata/CheckDigit.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/CheckDigit.ts)) +* Class ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Class.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Class.ts)) * Either ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Either.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Either.ts)) * Intersect ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Intersect.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Intersect.ts)) * Lazy ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Lazy.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Lazy.ts)) diff --git a/src/schemata/Class.ts b/src/schemata/Class.ts new file mode 100644 index 00000000..eabe2eb7 --- /dev/null +++ b/src/schemata/Class.ts @@ -0,0 +1,22 @@ +/** @since 2.2.0 */ +import { type Schema } from 'schemata-ts/Schema' +import { Imap } from 'schemata-ts/schemata/Imap' + +/** + * A schema combinator which transforms the output type of a schema to a specified class + * + * @since 2.2.0 + * @category Combinators + */ +export const Class = ( + constructor: new (...args: ReadonlyArray) => T, + toClass: (output: O) => T, + fromClass: (class_: T) => O, +): ((schema: Schema) => Schema) => + Imap( + { + is: (input: unknown): input is T => input instanceof constructor, + }, + toClass, + fromClass, + ) diff --git a/src/schemata/index.ts b/src/schemata/index.ts index 9f16ea1d..546e7f0e 100644 --- a/src/schemata/index.ts +++ b/src/schemata/index.ts @@ -21,6 +21,7 @@ export * from 'schemata-ts/schemata/CamelCaseKeys' export * from 'schemata-ts/schemata/CamelCaseRecord' export * from 'schemata-ts/schemata/CamelCaseString' export * from 'schemata-ts/schemata/CheckDigit' +export * from 'schemata-ts/schemata/Class' export * from 'schemata-ts/schemata/CreditCard' export * from 'schemata-ts/schemata/Date' export * from 'schemata-ts/schemata/DateFromInt' diff --git a/tests/Class.test.ts b/tests/Class.test.ts new file mode 100644 index 00000000..a7431ff6 --- /dev/null +++ b/tests/Class.test.ts @@ -0,0 +1,22 @@ +import { identity, pipe } from 'fp-ts/function' +import * as S from 'schemata-ts' + +import { runStandardTestSuite } from '../test-utils/test-suite' + +class ErrorClass { + constructor(public readonly error: string) {} +} + +const SchemaInput = S.Struct({ + error: S.String(), +}) + +const Schema = pipe( + SchemaInput, + S.Class(ErrorClass, _ => new ErrorClass(_.error), identity), +) + +runStandardTestSuite(Schema, _ => ({ + decoderTests: [_.decoder.pass({ error: 'foo' }, new ErrorClass('foo'))], + encoderTests: [_.encoder.pass(new ErrorClass('foo'), { error: 'foo' })], +}))() From f16494e7deb68d1a15edac7a10d1a16f3566633a Mon Sep 17 00:00:00 2001 From: Jacob Alford Date: Wed, 8 Nov 2023 14:43:25 -0700 Subject: [PATCH 06/16] feat(int-schema): add IntSchema --- src/schemata/Int.ts | 70 +++++++++++++++++++++++++++++++++++++++------ tests/Int.test.ts | 43 ++++++++++++++++------------ 2 files changed, 87 insertions(+), 26 deletions(-) diff --git a/src/schemata/Int.ts b/src/schemata/Int.ts index 4ef70305..14049ea5 100644 --- a/src/schemata/Int.ts +++ b/src/schemata/Int.ts @@ -1,9 +1,18 @@ /** @since 1.0.0 */ +import { unsafeCoerce } from 'fp-ts/function' +import { type Branded } from 'schemata-ts/brand' import { type Integer, type MaxSafeInt, type MinSafeInt } from 'schemata-ts/integer' -import { make } from 'schemata-ts/internal/schema' -import { type Schema } from 'schemata-ts/Schema' +import { type Schema, SchemaImplementation } from 'schemata-ts/Schema' import { type NumberParams } from 'schemata-ts/schemables/primitives/definition' +type IntWithDefaults< + Min extends number | undefined, + Max extends number | undefined, +> = Integer< + Min extends undefined ? MinSafeInt : Min, + Max extends undefined ? MaxSafeInt : Max +> + /** * Integer branded newtype. Parameters: min, max are inclusive. * @@ -21,9 +30,54 @@ export const Int = < Max extends number | undefined = undefined, >( params?: NumberParams, -): Schema< - Integer< - Min extends undefined ? MinSafeInt : Min, - Max extends undefined ? MaxSafeInt : Max - > -> => make(s => s.int(params)) +): IntSchema => new IntSchema(params) + +/** + * The StringSchema transformer class, use instead `S.String` function to create a StringSchema + * + * @since 2.2.0 + * @category Transformations + */ +export class IntSchema< + Min extends number | undefined, + Max extends number | undefined, +> extends SchemaImplementation> { + constructor(private readonly params?: NumberParams) { + super(s => s.int(params)) + } + + /** + * Brands this string schema with a certain brand + * + * @since 2.2.0 + */ + public readonly brand: () => Schema, Brand>> = + () => unsafeCoerce(this) + + /** + * Sets the minimum required length of the string + * + * @since 2.2.0 + */ + public readonly min: ( + minLength: NewMin, + ) => IntSchema = min => new IntSchema({ ...this.params, min }) + + /** + * Sets the maximum required length of the string + * + * @since 2.2.0 + */ + public readonly max: ( + maxLength: NewMax, + ) => IntSchema = max => new IntSchema({ ...this.params, max }) + + /** + * Overrides the 'expected' field in TranscodeError > TypeMismatch + * + * @since 2.2.0 + * @default 'string' + */ + public readonly errorName: (errorName: string) => IntSchema = errorName => + new IntSchema({ ...this.params, errorName }) +} diff --git a/tests/Int.test.ts b/tests/Int.test.ts index 5705f428..b4ddb032 100644 --- a/tests/Int.test.ts +++ b/tests/Int.test.ts @@ -1,5 +1,6 @@ import * as S from 'schemata-ts' import * as JS from 'schemata-ts/JsonSchema' +import * as TC from 'schemata-ts/Transcoder' import { runStandardTestSuite } from '../test-utils/test-suite' @@ -39,7 +40,7 @@ runStandardTestSuite(S.Int(), _ => ({ typeString: 'Integer', }))() -runStandardTestSuite(S.Int({ min: 10 }), _ => ({ +runStandardTestSuite(S.Int().min(10), _ => ({ decoderTests: [ _.decoder.pass(10), _.decoder.pass(11), @@ -55,7 +56,7 @@ runStandardTestSuite(S.Int({ min: 10 }), _ => ({ typeString: 'Integer<10,>', }))() -runStandardTestSuite(S.Int({ max: 10 }), _ => ({ +runStandardTestSuite(S.Int().max(10), _ => ({ decoderTests: [ _.decoder.fail(11), _.decoder.fail(156e10), @@ -71,19 +72,25 @@ runStandardTestSuite(S.Int({ max: 10 }), _ => ({ typeString: 'Integer<,10>', }))() -runStandardTestSuite(S.Int({ min: 10, max: 20 }), _ => ({ - decoderTests: [ - _.decoder.pass(10), - _.decoder.pass(11), - _.decoder.pass(20), - _.decoder.fail(9), - _.decoder.fail(0), - _.decoder.fail(-1), - _.decoder.fail(21), - ], - encoderTests: [], - guardTests: [], - eqTests: [], - jsonSchema: JS.integer({ minimum: 10, maximum: 20 }), - typeString: 'Integer<10,20>', -}))() +runStandardTestSuite( + S.Int({ min: 10, max: 20 }).errorName('Foo').brand(), + _ => ({ + decoderTests: [ + _.decoder.pass(10), + _.decoder.pass(11), + _.decoder.pass(20), + _.decoder.fail(9), + _.decoder.fail(0), + _.decoder.fail(-1), + _.decoder.fail(21), + ], + encoderTests: [], + guardTests: [], + eqTests: [], + jsonSchema: JS.integer({ minimum: 10, maximum: 20 }), + typeString: 'Integer<10,20>', + }), + { + makeDecodeError: _ => TC.transcodeErrors(TC.typeMismatch('Foo', _)), + }, +)() From 3b11c556cc50d51325477236c52dd73ac9fa6b40 Mon Sep 17 00:00:00 2001 From: Jacob Alford Date: Wed, 8 Nov 2023 14:43:44 -0700 Subject: [PATCH 07/16] feat(float-schema): add FloatSchema --- docs/schemata/Float.md | 87 ++++++++++++++++++++++++++++++++++-------- docs/schemata/Int.md | 81 ++++++++++++++++++++++++++++++++++----- src/schemata/Float.ts | 70 +++++++++++++++++++++++++++++---- tests/Float.test.ts | 51 ++++++++++++++----------- 4 files changed, 233 insertions(+), 56 deletions(-) diff --git a/docs/schemata/Float.md b/docs/schemata/Float.md index f45680fd..fdf44491 100644 --- a/docs/schemata/Float.md +++ b/docs/schemata/Float.md @@ -14,6 +14,12 @@ Added in v1.0.0 - [Number](#number) - [Float](#float) +- [Transformations](#transformations) + - [FloatSchema (class)](#floatschema-class) + - [brand (property)](#brand-property) + - [min (property)](#min-property) + - [max (property)](#max-property) + - [errorName (property)](#errorname-property) --- @@ -34,22 +40,71 @@ Represents floating point numbers: ```ts export declare const Float: ( params?: NumberParams | undefined -) => Schema< - Opaque< - number, - FloatBrand< - Min extends undefined ? -1.7976931348623157e308 : Min, - Max extends undefined ? 1.7976931348623157e308 : Max - > - >, - Opaque< - number, - FloatBrand< - Min extends undefined ? -1.7976931348623157e308 : Min, - Max extends undefined ? 1.7976931348623157e308 : Max - > - > -> +) => FloatSchema ``` Added in v1.0.0 + +# Transformations + +## FloatSchema (class) + +The StringSchema transformer class, use instead `S.String` function to create a StringSchema + +**Signature** + +```ts +export declare class FloatSchema { + constructor(private readonly params?: NumberParams) +} +``` + +Added in v2.2.0 + +### brand (property) + +Brands this string schema with a certain brand + +**Signature** + +```ts +readonly brand: () => Schema>, Brand>, Opaque>, Brand>> +``` + +Added in v2.2.0 + +### min (property) + +Sets the minimum required length of the string + +**Signature** + +```ts +readonly min: (minLength: NewMin) => FloatSchema +``` + +Added in v2.2.0 + +### max (property) + +Sets the maximum required length of the string + +**Signature** + +```ts +readonly max: (maxLength: NewMax) => FloatSchema +``` + +Added in v2.2.0 + +### errorName (property) + +Overrides the 'expected' field in TranscodeError > TypeMismatch + +**Signature** + +```ts +readonly errorName: (errorName: string) => FloatSchema +``` + +Added in v2.2.0 diff --git a/docs/schemata/Int.md b/docs/schemata/Int.md index 1dd3a48f..2c258c64 100644 --- a/docs/schemata/Int.md +++ b/docs/schemata/Int.md @@ -14,6 +14,12 @@ Added in v1.0.0 - [Number](#number) - [Int](#int) +- [Transformations](#transformations) + - [IntSchema (class)](#intschema-class) + - [brand (property)](#brand-property) + - [min (property)](#min-property) + - [max (property)](#max-property) + - [errorName (property)](#errorname-property) --- @@ -34,16 +40,71 @@ Represents integers: ```ts export declare const Int: ( params?: NumberParams | undefined -) => Schema< - Opaque< - number, - IntBrand - >, - Opaque< - number, - IntBrand - > -> +) => IntSchema ``` Added in v1.0.0 + +# Transformations + +## IntSchema (class) + +The StringSchema transformer class, use instead `S.String` function to create a StringSchema + +**Signature** + +```ts +export declare class IntSchema { + constructor(private readonly params?: NumberParams) +} +``` + +Added in v2.2.0 + +### brand (property) + +Brands this string schema with a certain brand + +**Signature** + +```ts +readonly brand: () => Schema>, Brand>, Opaque>, Brand>> +``` + +Added in v2.2.0 + +### min (property) + +Sets the minimum required length of the string + +**Signature** + +```ts +readonly min: (minLength: NewMin) => IntSchema +``` + +Added in v2.2.0 + +### max (property) + +Sets the maximum required length of the string + +**Signature** + +```ts +readonly max: (maxLength: NewMax) => IntSchema +``` + +Added in v2.2.0 + +### errorName (property) + +Overrides the 'expected' field in TranscodeError > TypeMismatch + +**Signature** + +```ts +readonly errorName: (errorName: string) => IntSchema +``` + +Added in v2.2.0 diff --git a/src/schemata/Float.ts b/src/schemata/Float.ts index 291668d2..dd0618a6 100644 --- a/src/schemata/Float.ts +++ b/src/schemata/Float.ts @@ -1,13 +1,22 @@ /** @since 1.0.0 */ +import { unsafeCoerce } from 'fp-ts/function' +import { type Branded } from 'schemata-ts/brand' import { type Float as Floating, type MaxNegativeFloat, type MaxPositiveFloat, } from 'schemata-ts/float' -import { make } from 'schemata-ts/internal/schema' -import { type Schema } from 'schemata-ts/Schema' +import { type Schema, SchemaImplementation } from 'schemata-ts/Schema' import { type NumberParams } from 'schemata-ts/schemables/primitives/definition' +type FloatWithDefault< + Min extends number | undefined, + Max extends number | undefined, +> = Floating< + Min extends undefined ? MaxNegativeFloat : Min, + Max extends undefined ? MaxPositiveFloat : Max +> + /** * Floating point branded newtype. Parameters: min, max are inclusive. * @@ -25,9 +34,54 @@ export const Float = < Max extends number | undefined = undefined, >( params?: NumberParams, -): Schema< - Floating< - Min extends undefined ? MaxNegativeFloat : Min, - Max extends undefined ? MaxPositiveFloat : Max - > -> => make(s => s.float(params)) +): FloatSchema => new FloatSchema(params) + +/** + * The StringSchema transformer class, use instead `S.String` function to create a StringSchema + * + * @since 2.2.0 + * @category Transformations + */ +export class FloatSchema< + Min extends number | undefined, + Max extends number | undefined, +> extends SchemaImplementation> { + constructor(private readonly params?: NumberParams) { + super(s => s.float(params)) + } + + /** + * Brands this string schema with a certain brand + * + * @since 2.2.0 + */ + public readonly brand: () => Schema, Brand>> = + () => unsafeCoerce(this) + + /** + * Sets the minimum required length of the string + * + * @since 2.2.0 + */ + public readonly min: ( + minLength: NewMin, + ) => FloatSchema = min => new FloatSchema({ ...this.params, min }) + + /** + * Sets the maximum required length of the string + * + * @since 2.2.0 + */ + public readonly max: ( + maxLength: NewMax, + ) => FloatSchema = max => new FloatSchema({ ...this.params, max }) + + /** + * Overrides the 'expected' field in TranscodeError > TypeMismatch + * + * @since 2.2.0 + * @default 'string' + */ + public readonly errorName: (errorName: string) => FloatSchema = errorName => + new FloatSchema({ ...this.params, errorName }) +} diff --git a/tests/Float.test.ts b/tests/Float.test.ts index 4a062e36..722bb415 100644 --- a/tests/Float.test.ts +++ b/tests/Float.test.ts @@ -1,5 +1,6 @@ import * as S from 'schemata-ts' import * as JS from 'schemata-ts/JsonSchema' +import * as TC from 'schemata-ts/Transcoder' import { runStandardTestSuite } from '../test-utils/test-suite' @@ -38,7 +39,7 @@ runStandardTestSuite(S.Float(), _ => ({ typeString: 'Float', }))() -runStandardTestSuite(S.Float({ min: 10 }), _ => ({ +runStandardTestSuite(S.Float().min(10), _ => ({ decoderTests: [ _.decoder.pass(10), _.decoder.pass(11), @@ -54,7 +55,7 @@ runStandardTestSuite(S.Float({ min: 10 }), _ => ({ typeString: 'Float<10,>', }))() -runStandardTestSuite(S.Float({ max: 10 }), _ => ({ +runStandardTestSuite(S.Float().max(10), _ => ({ decoderTests: [ _.decoder.fail(11), _.decoder.fail(156e10), @@ -70,23 +71,29 @@ runStandardTestSuite(S.Float({ max: 10 }), _ => ({ typeString: 'Float<,10>', }))() -runStandardTestSuite(S.Float({ min: 10, max: 20 }), _ => ({ - decoderTests: [ - _.decoder.pass(10), - _.decoder.pass(11), - _.decoder.pass(20), - _.decoder.pass(19), - _.decoder.pass(10.1), - _.decoder.pass(19.9), - _.decoder.fail(9), - _.decoder.fail(0), - _.decoder.fail(-1), - _.decoder.fail(21), - _.decoder.fail(156e10), - ], - encoderTests: [], - guardTests: [], - eqTests: [], - jsonSchema: JS.number({ minimum: 10, maximum: 20 }), - typeString: 'Float<10,20>', -}))() +runStandardTestSuite( + S.Float({ min: 10, max: 20 }).errorName('Foo').brand(), + _ => ({ + decoderTests: [ + _.decoder.pass(10), + _.decoder.pass(11), + _.decoder.pass(20), + _.decoder.pass(19), + _.decoder.pass(10.1), + _.decoder.pass(19.9), + _.decoder.fail(9), + _.decoder.fail(0), + _.decoder.fail(-1), + _.decoder.fail(21), + _.decoder.fail(156e10), + ], + encoderTests: [], + guardTests: [], + eqTests: [], + jsonSchema: JS.number({ minimum: 10, maximum: 20 }), + typeString: 'Float<10,20>', + }), + { + makeDecodeError: _ => TC.transcodeErrors(TC.typeMismatch('Foo', _)), + }, +)() From 2ddeb679ee1568d3c351e9c951512a9f5f883cc8 Mon Sep 17 00:00:00 2001 From: Jacob Alford Date: Wed, 8 Nov 2023 14:50:26 -0700 Subject: [PATCH 08/16] feat(Int,Float): Fix copy pasta --- docs/TranscodeError.md | 2 +- docs/Transcoder.md | 2 +- docs/TranscoderPar.md | 2 +- docs/TypeString.md | 2 +- docs/schemata/Class.md | 2 +- docs/schemata/CreditCard.md | 2 +- docs/schemata/Date.md | 2 +- docs/schemata/DateFromInt.md | 2 +- docs/schemata/DateFromIsoString.md | 2 +- docs/schemata/DateFromString.md | 2 +- docs/schemata/DateFromUnixTime.md | 2 +- docs/schemata/Either.md | 2 +- docs/schemata/EmailAddress.md | 2 +- docs/schemata/EthereumAddress.md | 2 +- docs/schemata/Float.md | 10 +++++----- docs/schemata/FloatFromString.md | 2 +- docs/schemata/HexColor.md | 2 +- docs/schemata/Hexadecimal.md | 2 +- docs/schemata/HslColor.md | 2 +- docs/schemata/Imap.md | 2 +- docs/schemata/Int.md | 10 +++++----- docs/schemata/IntFromString.md | 2 +- docs/schemata/Intersect.md | 2 +- docs/schemata/Jwt.md | 2 +- docs/schemata/LatLong.md | 2 +- docs/schemata/Lazy.md | 2 +- docs/schemata/Literal.md | 2 +- docs/schemata/MapFromEntries.md | 2 +- docs/schemata/Natural.md | 2 +- docs/schemata/NegativeFloat.md | 2 +- docs/schemata/NegativeInt.md | 2 +- docs/schemata/Newtype.md | 2 +- docs/schemata/NonEmptyArray.md | 2 +- docs/schemata/NonEmptyString.md | 2 +- docs/schemata/NonNegativeFloat.md | 2 +- docs/schemata/NonPositiveFloat.md | 2 +- docs/schemata/NonPositiveInt.md | 2 +- docs/schemata/Nullable.md | 2 +- docs/schemata/Number.md | 2 +- docs/schemata/Option.md | 2 +- docs/schemata/OptionFromNullable.md | 2 +- docs/schemata/Optional.md | 2 +- docs/schemata/Parse.md | 2 +- docs/schemata/ParseBase64Json.md | 2 +- docs/schemata/ParseEncodedJson.md | 2 +- docs/schemata/ParseJsonString.md | 2 +- docs/schemata/Partial.md | 2 +- docs/schemata/Pattern.md | 2 +- docs/schemata/PositiveFloat.md | 2 +- docs/schemata/PositiveInt.md | 2 +- docs/schemata/RGB.md | 2 +- docs/schemata/Readonly.md | 2 +- docs/schemata/Record.md | 2 +- docs/schemata/Refine.md | 2 +- docs/schemata/SetFromArray.md | 2 +- docs/schemata/Strict.md | 2 +- docs/schemata/String.md | 2 +- docs/schemata/Struct.md | 2 +- docs/schemata/Tuple.md | 2 +- docs/schemata/UUID.md | 2 +- docs/schemata/Union.md | 2 +- docs/schemata/Unit.md | 2 +- docs/schemata/Unknown.md | 2 +- docs/schemata/UnknownArray.md | 2 +- docs/schemata/UnknownRecord.md | 2 +- docs/schemata/index.md | 30 ++++++++++++++--------------- src/schemata/Float.ts | 8 ++++---- src/schemata/Int.ts | 8 ++++---- 68 files changed, 96 insertions(+), 96 deletions(-) diff --git a/docs/TranscodeError.md b/docs/TranscodeError.md index 9d2ec301..17eaa94c 100644 --- a/docs/TranscodeError.md +++ b/docs/TranscodeError.md @@ -1,6 +1,6 @@ --- title: TranscodeError.ts -nav_order: 88 +nav_order: 89 permalink: /transcode-error/ --- diff --git a/docs/Transcoder.md b/docs/Transcoder.md index bf129f43..8c49d0c9 100644 --- a/docs/Transcoder.md +++ b/docs/Transcoder.md @@ -1,6 +1,6 @@ --- title: Transcoder.ts -nav_order: 89 +nav_order: 90 permalink: /transcoder/ --- diff --git a/docs/TranscoderPar.md b/docs/TranscoderPar.md index c4b11a1d..0ee46bc9 100644 --- a/docs/TranscoderPar.md +++ b/docs/TranscoderPar.md @@ -1,6 +1,6 @@ --- title: TranscoderPar.ts -nav_order: 90 +nav_order: 91 permalink: /transcoder-par/ --- diff --git a/docs/TypeString.md b/docs/TypeString.md index 383f97f1..6fa55db2 100644 --- a/docs/TypeString.md +++ b/docs/TypeString.md @@ -1,6 +1,6 @@ --- title: TypeString.ts -nav_order: 91 +nav_order: 92 permalink: /type-string/ --- diff --git a/docs/schemata/Class.md b/docs/schemata/Class.md index 57b57bb7..52688204 100644 --- a/docs/schemata/Class.md +++ b/docs/schemata/Class.md @@ -1,6 +1,6 @@ --- title: Class -nav_order: 26 +nav_order: 27 parent: schemata --- diff --git a/docs/schemata/CreditCard.md b/docs/schemata/CreditCard.md index 37d3bc27..9b25c816 100644 --- a/docs/schemata/CreditCard.md +++ b/docs/schemata/CreditCard.md @@ -1,6 +1,6 @@ --- title: CreditCard -nav_order: 27 +nav_order: 28 parent: schemata --- diff --git a/docs/schemata/Date.md b/docs/schemata/Date.md index ff13e054..11c64c19 100644 --- a/docs/schemata/Date.md +++ b/docs/schemata/Date.md @@ -1,6 +1,6 @@ --- title: Date -nav_order: 28 +nav_order: 29 parent: schemata --- diff --git a/docs/schemata/DateFromInt.md b/docs/schemata/DateFromInt.md index 03a5cd81..36ab467b 100644 --- a/docs/schemata/DateFromInt.md +++ b/docs/schemata/DateFromInt.md @@ -1,6 +1,6 @@ --- title: DateFromInt -nav_order: 29 +nav_order: 30 parent: schemata --- diff --git a/docs/schemata/DateFromIsoString.md b/docs/schemata/DateFromIsoString.md index 5c27cd47..d64ebbd9 100644 --- a/docs/schemata/DateFromIsoString.md +++ b/docs/schemata/DateFromIsoString.md @@ -1,6 +1,6 @@ --- title: DateFromIsoString -nav_order: 30 +nav_order: 31 parent: schemata --- diff --git a/docs/schemata/DateFromString.md b/docs/schemata/DateFromString.md index c3d6efde..df4e46e9 100644 --- a/docs/schemata/DateFromString.md +++ b/docs/schemata/DateFromString.md @@ -1,6 +1,6 @@ --- title: DateFromString -nav_order: 31 +nav_order: 32 parent: schemata --- diff --git a/docs/schemata/DateFromUnixTime.md b/docs/schemata/DateFromUnixTime.md index 37bc311b..cc6bc3d4 100644 --- a/docs/schemata/DateFromUnixTime.md +++ b/docs/schemata/DateFromUnixTime.md @@ -1,6 +1,6 @@ --- title: DateFromUnixTime -nav_order: 32 +nav_order: 33 parent: schemata --- diff --git a/docs/schemata/Either.md b/docs/schemata/Either.md index 16c94b4a..13a04e5c 100644 --- a/docs/schemata/Either.md +++ b/docs/schemata/Either.md @@ -1,6 +1,6 @@ --- title: Either -nav_order: 33 +nav_order: 34 parent: schemata --- diff --git a/docs/schemata/EmailAddress.md b/docs/schemata/EmailAddress.md index 33b4cff4..fe6c835a 100644 --- a/docs/schemata/EmailAddress.md +++ b/docs/schemata/EmailAddress.md @@ -1,6 +1,6 @@ --- title: EmailAddress -nav_order: 34 +nav_order: 35 parent: schemata --- diff --git a/docs/schemata/EthereumAddress.md b/docs/schemata/EthereumAddress.md index 1916d681..386b53c1 100644 --- a/docs/schemata/EthereumAddress.md +++ b/docs/schemata/EthereumAddress.md @@ -1,6 +1,6 @@ --- title: EthereumAddress -nav_order: 35 +nav_order: 36 parent: schemata --- diff --git a/docs/schemata/Float.md b/docs/schemata/Float.md index fdf44491..0128e3d8 100644 --- a/docs/schemata/Float.md +++ b/docs/schemata/Float.md @@ -1,6 +1,6 @@ --- title: Float -nav_order: 36 +nav_order: 37 parent: schemata --- @@ -49,7 +49,7 @@ Added in v1.0.0 ## FloatSchema (class) -The StringSchema transformer class, use instead `S.String` function to create a StringSchema +The FloatSchema transformer class, use instead `S.Float` function to create a FloatSchema **Signature** @@ -63,7 +63,7 @@ Added in v2.2.0 ### brand (property) -Brands this string schema with a certain brand +Brands this FloatSchema with a certain brand **Signature** @@ -75,7 +75,7 @@ Added in v2.2.0 ### min (property) -Sets the minimum required length of the string +Sets the minimum value of the FloatSchema **Signature** @@ -87,7 +87,7 @@ Added in v2.2.0 ### max (property) -Sets the maximum required length of the string +Sets the maximum value of the FloatSchema **Signature** diff --git a/docs/schemata/FloatFromString.md b/docs/schemata/FloatFromString.md index 1cf4bc7c..c89cc2ba 100644 --- a/docs/schemata/FloatFromString.md +++ b/docs/schemata/FloatFromString.md @@ -1,6 +1,6 @@ --- title: FloatFromString -nav_order: 37 +nav_order: 38 parent: schemata --- diff --git a/docs/schemata/HexColor.md b/docs/schemata/HexColor.md index 26acfaa0..294c4bc7 100644 --- a/docs/schemata/HexColor.md +++ b/docs/schemata/HexColor.md @@ -1,6 +1,6 @@ --- title: HexColor -nav_order: 39 +nav_order: 40 parent: schemata --- diff --git a/docs/schemata/Hexadecimal.md b/docs/schemata/Hexadecimal.md index f8e46200..25206ce3 100644 --- a/docs/schemata/Hexadecimal.md +++ b/docs/schemata/Hexadecimal.md @@ -1,6 +1,6 @@ --- title: Hexadecimal -nav_order: 38 +nav_order: 39 parent: schemata --- diff --git a/docs/schemata/HslColor.md b/docs/schemata/HslColor.md index 85660653..d0da5eee 100644 --- a/docs/schemata/HslColor.md +++ b/docs/schemata/HslColor.md @@ -1,6 +1,6 @@ --- title: HslColor -nav_order: 40 +nav_order: 41 parent: schemata --- diff --git a/docs/schemata/Imap.md b/docs/schemata/Imap.md index c8d365ab..ba773029 100644 --- a/docs/schemata/Imap.md +++ b/docs/schemata/Imap.md @@ -1,6 +1,6 @@ --- title: Imap -nav_order: 41 +nav_order: 42 parent: schemata --- diff --git a/docs/schemata/Int.md b/docs/schemata/Int.md index 2c258c64..63a74508 100644 --- a/docs/schemata/Int.md +++ b/docs/schemata/Int.md @@ -1,6 +1,6 @@ --- title: Int -nav_order: 43 +nav_order: 44 parent: schemata --- @@ -49,7 +49,7 @@ Added in v1.0.0 ## IntSchema (class) -The StringSchema transformer class, use instead `S.String` function to create a StringSchema +The IntSchema transformer class, use instead `S.Int` function to create an IntSchema **Signature** @@ -63,7 +63,7 @@ Added in v2.2.0 ### brand (property) -Brands this string schema with a certain brand +Brands this Int schema with a certain brand **Signature** @@ -75,7 +75,7 @@ Added in v2.2.0 ### min (property) -Sets the minimum required length of the string +Sets the minimum value of the IntSchema **Signature** @@ -87,7 +87,7 @@ Added in v2.2.0 ### max (property) -Sets the maximum required length of the string +Sets the maximum value of the IntSchema **Signature** diff --git a/docs/schemata/IntFromString.md b/docs/schemata/IntFromString.md index 03df8b13..5f972580 100644 --- a/docs/schemata/IntFromString.md +++ b/docs/schemata/IntFromString.md @@ -1,6 +1,6 @@ --- title: IntFromString -nav_order: 45 +nav_order: 46 parent: schemata --- diff --git a/docs/schemata/Intersect.md b/docs/schemata/Intersect.md index 6b32a05d..ed2f4319 100644 --- a/docs/schemata/Intersect.md +++ b/docs/schemata/Intersect.md @@ -1,6 +1,6 @@ --- title: Intersect -nav_order: 44 +nav_order: 45 parent: schemata --- diff --git a/docs/schemata/Jwt.md b/docs/schemata/Jwt.md index cc845b29..cb839310 100644 --- a/docs/schemata/Jwt.md +++ b/docs/schemata/Jwt.md @@ -1,6 +1,6 @@ --- title: Jwt -nav_order: 46 +nav_order: 47 parent: schemata --- diff --git a/docs/schemata/LatLong.md b/docs/schemata/LatLong.md index 6c4385d0..7ab946bd 100644 --- a/docs/schemata/LatLong.md +++ b/docs/schemata/LatLong.md @@ -1,6 +1,6 @@ --- title: LatLong -nav_order: 47 +nav_order: 48 parent: schemata --- diff --git a/docs/schemata/Lazy.md b/docs/schemata/Lazy.md index 847d4c11..fd155c24 100644 --- a/docs/schemata/Lazy.md +++ b/docs/schemata/Lazy.md @@ -1,6 +1,6 @@ --- title: Lazy -nav_order: 48 +nav_order: 49 parent: schemata --- diff --git a/docs/schemata/Literal.md b/docs/schemata/Literal.md index ba7cce2d..d1cfdecf 100644 --- a/docs/schemata/Literal.md +++ b/docs/schemata/Literal.md @@ -1,6 +1,6 @@ --- title: Literal -nav_order: 49 +nav_order: 50 parent: schemata --- diff --git a/docs/schemata/MapFromEntries.md b/docs/schemata/MapFromEntries.md index 414f285e..753840e4 100644 --- a/docs/schemata/MapFromEntries.md +++ b/docs/schemata/MapFromEntries.md @@ -1,6 +1,6 @@ --- title: MapFromEntries -nav_order: 50 +nav_order: 51 parent: schemata --- diff --git a/docs/schemata/Natural.md b/docs/schemata/Natural.md index 1e70a1ca..f683e4ea 100644 --- a/docs/schemata/Natural.md +++ b/docs/schemata/Natural.md @@ -1,6 +1,6 @@ --- title: Natural -nav_order: 51 +nav_order: 52 parent: schemata --- diff --git a/docs/schemata/NegativeFloat.md b/docs/schemata/NegativeFloat.md index 9022d577..7325accf 100644 --- a/docs/schemata/NegativeFloat.md +++ b/docs/schemata/NegativeFloat.md @@ -1,6 +1,6 @@ --- title: NegativeFloat -nav_order: 52 +nav_order: 53 parent: schemata --- diff --git a/docs/schemata/NegativeInt.md b/docs/schemata/NegativeInt.md index ebb04b91..b222a886 100644 --- a/docs/schemata/NegativeInt.md +++ b/docs/schemata/NegativeInt.md @@ -1,6 +1,6 @@ --- title: NegativeInt -nav_order: 53 +nav_order: 54 parent: schemata --- diff --git a/docs/schemata/Newtype.md b/docs/schemata/Newtype.md index a25e77c4..a012fcef 100644 --- a/docs/schemata/Newtype.md +++ b/docs/schemata/Newtype.md @@ -1,6 +1,6 @@ --- title: Newtype -nav_order: 54 +nav_order: 55 parent: schemata --- diff --git a/docs/schemata/NonEmptyArray.md b/docs/schemata/NonEmptyArray.md index da70d140..db005757 100644 --- a/docs/schemata/NonEmptyArray.md +++ b/docs/schemata/NonEmptyArray.md @@ -1,6 +1,6 @@ --- title: NonEmptyArray -nav_order: 55 +nav_order: 56 parent: schemata --- diff --git a/docs/schemata/NonEmptyString.md b/docs/schemata/NonEmptyString.md index 5661f86f..1b8f51b8 100644 --- a/docs/schemata/NonEmptyString.md +++ b/docs/schemata/NonEmptyString.md @@ -1,6 +1,6 @@ --- title: NonEmptyString -nav_order: 56 +nav_order: 57 parent: schemata --- diff --git a/docs/schemata/NonNegativeFloat.md b/docs/schemata/NonNegativeFloat.md index 574b635c..bfc3f8d9 100644 --- a/docs/schemata/NonNegativeFloat.md +++ b/docs/schemata/NonNegativeFloat.md @@ -1,6 +1,6 @@ --- title: NonNegativeFloat -nav_order: 57 +nav_order: 58 parent: schemata --- diff --git a/docs/schemata/NonPositiveFloat.md b/docs/schemata/NonPositiveFloat.md index ce1a1004..99fee91c 100644 --- a/docs/schemata/NonPositiveFloat.md +++ b/docs/schemata/NonPositiveFloat.md @@ -1,6 +1,6 @@ --- title: NonPositiveFloat -nav_order: 58 +nav_order: 59 parent: schemata --- diff --git a/docs/schemata/NonPositiveInt.md b/docs/schemata/NonPositiveInt.md index e40f030c..bd8e06f7 100644 --- a/docs/schemata/NonPositiveInt.md +++ b/docs/schemata/NonPositiveInt.md @@ -1,6 +1,6 @@ --- title: NonPositiveInt -nav_order: 59 +nav_order: 60 parent: schemata --- diff --git a/docs/schemata/Nullable.md b/docs/schemata/Nullable.md index c64f30b5..589e6808 100644 --- a/docs/schemata/Nullable.md +++ b/docs/schemata/Nullable.md @@ -1,6 +1,6 @@ --- title: Nullable -nav_order: 60 +nav_order: 61 parent: schemata --- diff --git a/docs/schemata/Number.md b/docs/schemata/Number.md index 328ce62a..b3dfa8f8 100644 --- a/docs/schemata/Number.md +++ b/docs/schemata/Number.md @@ -1,6 +1,6 @@ --- title: Number -nav_order: 61 +nav_order: 62 parent: schemata --- diff --git a/docs/schemata/Option.md b/docs/schemata/Option.md index 0447a985..51439a8b 100644 --- a/docs/schemata/Option.md +++ b/docs/schemata/Option.md @@ -1,6 +1,6 @@ --- title: Option -nav_order: 62 +nav_order: 63 parent: schemata --- diff --git a/docs/schemata/OptionFromNullable.md b/docs/schemata/OptionFromNullable.md index fd820106..ff9d50c1 100644 --- a/docs/schemata/OptionFromNullable.md +++ b/docs/schemata/OptionFromNullable.md @@ -1,6 +1,6 @@ --- title: OptionFromNullable -nav_order: 64 +nav_order: 65 parent: schemata --- diff --git a/docs/schemata/Optional.md b/docs/schemata/Optional.md index a53b6b2d..4554c6a8 100644 --- a/docs/schemata/Optional.md +++ b/docs/schemata/Optional.md @@ -1,6 +1,6 @@ --- title: Optional -nav_order: 63 +nav_order: 64 parent: schemata --- diff --git a/docs/schemata/Parse.md b/docs/schemata/Parse.md index 5fd6ed22..b66c4a5d 100644 --- a/docs/schemata/Parse.md +++ b/docs/schemata/Parse.md @@ -1,6 +1,6 @@ --- title: Parse -nav_order: 65 +nav_order: 66 parent: schemata --- diff --git a/docs/schemata/ParseBase64Json.md b/docs/schemata/ParseBase64Json.md index 1edffbca..9571cfb6 100644 --- a/docs/schemata/ParseBase64Json.md +++ b/docs/schemata/ParseBase64Json.md @@ -1,6 +1,6 @@ --- title: ParseBase64Json -nav_order: 66 +nav_order: 67 parent: schemata --- diff --git a/docs/schemata/ParseEncodedJson.md b/docs/schemata/ParseEncodedJson.md index 3d3ac6ad..4503982a 100644 --- a/docs/schemata/ParseEncodedJson.md +++ b/docs/schemata/ParseEncodedJson.md @@ -1,6 +1,6 @@ --- title: ParseEncodedJson -nav_order: 67 +nav_order: 68 parent: schemata --- diff --git a/docs/schemata/ParseJsonString.md b/docs/schemata/ParseJsonString.md index 90df8a42..b2130566 100644 --- a/docs/schemata/ParseJsonString.md +++ b/docs/schemata/ParseJsonString.md @@ -1,6 +1,6 @@ --- title: ParseJsonString -nav_order: 68 +nav_order: 69 parent: schemata --- diff --git a/docs/schemata/Partial.md b/docs/schemata/Partial.md index 55684b3f..3a19083c 100644 --- a/docs/schemata/Partial.md +++ b/docs/schemata/Partial.md @@ -1,6 +1,6 @@ --- title: Partial -nav_order: 69 +nav_order: 70 parent: schemata --- diff --git a/docs/schemata/Pattern.md b/docs/schemata/Pattern.md index 4d14bb82..1c2bbad5 100644 --- a/docs/schemata/Pattern.md +++ b/docs/schemata/Pattern.md @@ -1,6 +1,6 @@ --- title: Pattern -nav_order: 70 +nav_order: 71 parent: schemata --- diff --git a/docs/schemata/PositiveFloat.md b/docs/schemata/PositiveFloat.md index ef59bce3..a0dab945 100644 --- a/docs/schemata/PositiveFloat.md +++ b/docs/schemata/PositiveFloat.md @@ -1,6 +1,6 @@ --- title: PositiveFloat -nav_order: 71 +nav_order: 72 parent: schemata --- diff --git a/docs/schemata/PositiveInt.md b/docs/schemata/PositiveInt.md index c054d47a..169891b1 100644 --- a/docs/schemata/PositiveInt.md +++ b/docs/schemata/PositiveInt.md @@ -1,6 +1,6 @@ --- title: PositiveInt -nav_order: 72 +nav_order: 73 parent: schemata --- diff --git a/docs/schemata/RGB.md b/docs/schemata/RGB.md index 99c640ec..133c9977 100644 --- a/docs/schemata/RGB.md +++ b/docs/schemata/RGB.md @@ -1,6 +1,6 @@ --- title: RGB -nav_order: 76 +nav_order: 77 parent: schemata --- diff --git a/docs/schemata/Readonly.md b/docs/schemata/Readonly.md index 3657b5ba..dab7fca5 100644 --- a/docs/schemata/Readonly.md +++ b/docs/schemata/Readonly.md @@ -1,6 +1,6 @@ --- title: Readonly -nav_order: 73 +nav_order: 74 parent: schemata --- diff --git a/docs/schemata/Record.md b/docs/schemata/Record.md index 3b49d7f3..91daaa10 100644 --- a/docs/schemata/Record.md +++ b/docs/schemata/Record.md @@ -1,6 +1,6 @@ --- title: Record -nav_order: 74 +nav_order: 75 parent: schemata --- diff --git a/docs/schemata/Refine.md b/docs/schemata/Refine.md index ae27a75c..cdcd89dd 100644 --- a/docs/schemata/Refine.md +++ b/docs/schemata/Refine.md @@ -1,6 +1,6 @@ --- title: Refine -nav_order: 75 +nav_order: 76 parent: schemata --- diff --git a/docs/schemata/SetFromArray.md b/docs/schemata/SetFromArray.md index f6de3325..f574153b 100644 --- a/docs/schemata/SetFromArray.md +++ b/docs/schemata/SetFromArray.md @@ -1,6 +1,6 @@ --- title: SetFromArray -nav_order: 77 +nav_order: 78 parent: schemata --- diff --git a/docs/schemata/Strict.md b/docs/schemata/Strict.md index 99338c99..aaa9d1fb 100644 --- a/docs/schemata/Strict.md +++ b/docs/schemata/Strict.md @@ -1,6 +1,6 @@ --- title: Strict -nav_order: 78 +nav_order: 79 parent: schemata --- diff --git a/docs/schemata/String.md b/docs/schemata/String.md index cae84938..f0bebe26 100644 --- a/docs/schemata/String.md +++ b/docs/schemata/String.md @@ -1,6 +1,6 @@ --- title: String -nav_order: 79 +nav_order: 80 parent: schemata --- diff --git a/docs/schemata/Struct.md b/docs/schemata/Struct.md index ac6381c2..f34467eb 100644 --- a/docs/schemata/Struct.md +++ b/docs/schemata/Struct.md @@ -1,6 +1,6 @@ --- title: Struct -nav_order: 80 +nav_order: 81 parent: schemata --- diff --git a/docs/schemata/Tuple.md b/docs/schemata/Tuple.md index d9224b44..76990e88 100644 --- a/docs/schemata/Tuple.md +++ b/docs/schemata/Tuple.md @@ -1,6 +1,6 @@ --- title: Tuple -nav_order: 81 +nav_order: 82 parent: schemata --- diff --git a/docs/schemata/UUID.md b/docs/schemata/UUID.md index 6b163195..eeb1d59f 100644 --- a/docs/schemata/UUID.md +++ b/docs/schemata/UUID.md @@ -1,6 +1,6 @@ --- title: UUID -nav_order: 87 +nav_order: 88 parent: schemata --- diff --git a/docs/schemata/Union.md b/docs/schemata/Union.md index bd477498..e37c4c80 100644 --- a/docs/schemata/Union.md +++ b/docs/schemata/Union.md @@ -1,6 +1,6 @@ --- title: Union -nav_order: 82 +nav_order: 83 parent: schemata --- diff --git a/docs/schemata/Unit.md b/docs/schemata/Unit.md index 86bc79db..12408e7e 100644 --- a/docs/schemata/Unit.md +++ b/docs/schemata/Unit.md @@ -1,6 +1,6 @@ --- title: Unit -nav_order: 83 +nav_order: 84 parent: schemata --- diff --git a/docs/schemata/Unknown.md b/docs/schemata/Unknown.md index 08708662..c41c159b 100644 --- a/docs/schemata/Unknown.md +++ b/docs/schemata/Unknown.md @@ -1,6 +1,6 @@ --- title: Unknown -nav_order: 84 +nav_order: 85 parent: schemata --- diff --git a/docs/schemata/UnknownArray.md b/docs/schemata/UnknownArray.md index 08b6b78c..0696050c 100644 --- a/docs/schemata/UnknownArray.md +++ b/docs/schemata/UnknownArray.md @@ -1,6 +1,6 @@ --- title: UnknownArray -nav_order: 85 +nav_order: 86 parent: schemata --- diff --git a/docs/schemata/UnknownRecord.md b/docs/schemata/UnknownRecord.md index e47e283a..3f9e1641 100644 --- a/docs/schemata/UnknownRecord.md +++ b/docs/schemata/UnknownRecord.md @@ -1,6 +1,6 @@ --- title: UnknownRecord -nav_order: 86 +nav_order: 87 parent: schemata --- diff --git a/docs/schemata/index.md b/docs/schemata/index.md index e73ec054..15a0f561 100644 --- a/docs/schemata/index.md +++ b/docs/schemata/index.md @@ -83,23 +83,23 @@ has_children: true ### String (17) -* Ascii ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Ascii.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Ascii.ts)) (e.g: `l4~1`, `)|z~}`, `O4Z@`) -* Base64 ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Base64.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Base64.ts)) (e.g: `eQ+++05/dp/+9j+3dl+6aw+/zU5/O6d/+6e9lQv8`, `+n///Yv+bx0=`, `9/S/AW+2/e3Zfmx/eBEexHEe5x5+f+BTt1p=`) -* Base64Url ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Base64Url.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Base64Url.ts)) (e.g: `e__9-I`, `3_-a_-_X`, `_T-7--_-5`) -* BitcoinAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/BitcoinAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/BitcoinAddress.ts)) (e.g: `3kYASqPstWdVZA65uoVuAEFMg4TvAUekJXXNHRS`, `bc1f1y0a3ada9cc5a04z1523qa5abeezw92x`, `bc1xe0u2z02awy802i2o1d64c321ra3`) +* Ascii ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Ascii.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Ascii.ts)) (e.g: `DxN%`, `p!mq@`, `~|{{l`) +* Base64 ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Base64.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Base64.ts)) (e.g: `s+E+Z42Xxk/+3/U+li//p96f+l/o`, `u345++//B+711SN6/9ok7++B`, `LgPP/K/g5HfjR+/7+74Gl/2a/qhxp/0mQr==`) +* Base64Url ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Base64Url.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Base64Url.ts)) (e.g: `D---xB-`, `-o1_-z-`, `--_8_Z_d__`) +* BitcoinAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/BitcoinAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/BitcoinAddress.ts)) (e.g: `1QPZ2zALkNmKLAfA9kGLNm9A7X1GGnPn2Qn`, `24LoFGBK3zvQnVdz4JNpCALi4FoWTxtZG8XZxKf`, `bc19h9casw3o260lva263766cep6492hrz9xm2t`) * CamelCaseString ([docs](https://jacob-alford.github.io/schemata-ts/schemata/CamelCaseString.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/CamelCaseString.ts)) (e.g: `Camel_case-string` → `camelCaseString`) -* CreditCard ([docs](https://jacob-alford.github.io/schemata-ts/schemata/CreditCard.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/CreditCard.ts)) (e.g: `8179596818132214`, `3932220044003541706`, `62292072866283597`) -* EmailAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/EmailAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/EmailAddress.ts)) (e.g: `d?|#|_b?.*/.&}@[50.9.0.9]`, `NtI|/.~*-|.={?&'.%+?L*.?$&.=*Q*.&^_!_}&~.}/~}?/_+?'.^*E%|@[26.31.22.62]`, `"￸㶸"@o-.-l-q9.h0-g6QOk..-PVMUK-1-W.6TyUi--S.dwI`) -* EthereumAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/EthereumAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/EthereumAddress.ts)) (e.g: `0x61F4eC9Db99dfA89faAf1bDecFBEaAbDBa7cC4C7`, `0x9CEdea92deBBfdB13851Dd2a2ce6dFF1379ED3F3`, `0x1AEaDfdCACcC202628F6DE9aC19d80505DB3AE4a`) -* HexColor ([docs](https://jacob-alford.github.io/schemata-ts/schemata/HexColor.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/HexColor.ts)) (e.g: `Ac928fd2`, `#3Bfb33`, `#a7CAF29D`) -* Hexadecimal ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Hexadecimal.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Hexadecimal.ts)) (e.g: `d1efc4`, `FCf0B9EB`, `Bb827A`) -* HslColor ([docs](https://jacob-alford.github.io/schemata-ts/schemata/HslColor.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/HslColor.ts)) (e.g: `hsla(-.5317678028e+13965811099turn+51e55475989152%0000000000.037%/39%)`, `hsla(-.2,000100e-5%,+000000000.21998890675%,6715839.158922788)`, `hsl(-0037517617+0000100%0.01%)`) -* Jwt ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Jwt.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Jwt.ts)) (e.g: `..-_lJH_`, `0i8--.eXwxk--_7`, `1_F.VdxTXKlCU`) -* LatLong ([docs](https://jacob-alford.github.io/schemata-ts/schemata/LatLong.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/LatLong.ts)) (e.g: `-2.49281137,92`, `-90.0000,180.000000000`, `90,-120`) -* NonEmptyString ([docs](https://jacob-alford.github.io/schemata-ts/schemata/NonEmptyString.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/NonEmptyString.ts)) (e.g: `0kVIVeCc`, `B.1Av}wn`, `y7namenamepr`) -* RGB ([docs](https://jacob-alford.github.io/schemata-ts/schemata/RGB.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/RGB.ts)) (e.g: `rgb(8,195,252)`, `rgba(100%,3%,100%,1)`, `rgba(100%,99%,99%,0.0367943763)`) +* CreditCard ([docs](https://jacob-alford.github.io/schemata-ts/schemata/CreditCard.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/CreditCard.ts)) (e.g: `6529020340876286962`, `378389006333372`, `62835962063734984`) +* EmailAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/EmailAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/EmailAddress.ts)) (e.g: `~&%{+!+*&*.%/=-|+%?}.{-C}o'$z@Mpp3--52.68qx.u6.4Q.nIYH`, `'{/-*{'H^%!.?|}/!'&|.~7!}}/-|+&.8$-&+.r+~?B?=.!$_9_O%*'}?@[87.9.730.63]`, `"࢒￰乃귞᮶"@[91.1.34.410]`) +* EthereumAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/EthereumAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/EthereumAddress.ts)) (e.g: `0xDdE30CF0BDAFf6e92DFb7CFcdfa5Cf2eAF2e6a36`, `0x9F0DCC602AC889beCfBaDF0E08CeA61C3cCC0e7A`, `0x1fB624A1Eb2bA9ab41BA5Ecee8Cb1f0fC00fbCfD`) +* HexColor ([docs](https://jacob-alford.github.io/schemata-ts/schemata/HexColor.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/HexColor.ts)) (e.g: `#0Bf1a2`, `c9DbAacC`, `#cF9eABaF`) +* Hexadecimal ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Hexadecimal.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Hexadecimal.ts)) (e.g: `0XdebB0BA95cFB`, `EA13bcEC8`, `0H2aFC3F1Db1`) +* HslColor ([docs](https://jacob-alford.github.io/schemata-ts/schemata/HslColor.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/HslColor.ts)) (e.g: `hsl(+583turn,+00000000000e963%,00000100e-70%)`, `hsla(.1603641113+000100.000000000000%00093e65523%)`, `hsl(.17e-2342589grad+0000000.8621%0000000000.2e758385%)`) +* Jwt ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Jwt.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Jwt.ts)) (e.g: `--_4___.__`, `____-kHMn-._`, `_2_y281.Y-_-9`) +* LatLong ([docs](https://jacob-alford.github.io/schemata-ts/schemata/LatLong.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/LatLong.ts)) (e.g: `90.000000,180`, `90.00000000,180`, `(90,+99)`) +* NonEmptyString ([docs](https://jacob-alford.github.io/schemata-ts/schemata/NonEmptyString.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/NonEmptyString.ts)) (e.g: `otoD+lleGACeqtri`, `toString`, `piuxku`) +* RGB ([docs](https://jacob-alford.github.io/schemata-ts/schemata/RGB.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/RGB.ts)) (e.g: `rgb(69,240,252)`, `rgba(237,252,250,.26)`, `rgb(225,251,98)`) * String ([docs](https://jacob-alford.github.io/schemata-ts/schemata/String.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/String.ts)) -* UUID ([docs](https://jacob-alford.github.io/schemata-ts/schemata/UUID.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/UUID.ts)) (e.g: `bB98f8ca-ccfd-ed3B-9fB4-b1aeA8009DeC`, `eAbEdEC6-bc5F-eCcB-021f-3FB1c20aCFdB`, `acEEC83c-1F17-dBCb-abfE-3DD1C8Cf8dEB`) +* UUID ([docs](https://jacob-alford.github.io/schemata-ts/schemata/UUID.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/UUID.ts)) (e.g: `d1b69A90-f2e0-BC61-bD7a-BFeF3d9Ecc8A`, `cb18bBec-Bed7-1BFa-0CcB-DCB330efE7DA`, `CbFd7ddf-FEaf-D0Ba-9b21-abBcEeC1fA5b`) ### Unit (1) diff --git a/src/schemata/Float.ts b/src/schemata/Float.ts index dd0618a6..380ac2fd 100644 --- a/src/schemata/Float.ts +++ b/src/schemata/Float.ts @@ -37,7 +37,7 @@ export const Float = < ): FloatSchema => new FloatSchema(params) /** - * The StringSchema transformer class, use instead `S.String` function to create a StringSchema + * The FloatSchema transformer class, use instead `S.Float` function to create a FloatSchema * * @since 2.2.0 * @category Transformations @@ -51,7 +51,7 @@ export class FloatSchema< } /** - * Brands this string schema with a certain brand + * Brands this FloatSchema with a certain brand * * @since 2.2.0 */ @@ -59,7 +59,7 @@ export class FloatSchema< () => unsafeCoerce(this) /** - * Sets the minimum required length of the string + * Sets the minimum value of the FloatSchema * * @since 2.2.0 */ @@ -68,7 +68,7 @@ export class FloatSchema< ) => FloatSchema = min => new FloatSchema({ ...this.params, min }) /** - * Sets the maximum required length of the string + * Sets the maximum value of the FloatSchema * * @since 2.2.0 */ diff --git a/src/schemata/Int.ts b/src/schemata/Int.ts index 14049ea5..97ac2b26 100644 --- a/src/schemata/Int.ts +++ b/src/schemata/Int.ts @@ -33,7 +33,7 @@ export const Int = < ): IntSchema => new IntSchema(params) /** - * The StringSchema transformer class, use instead `S.String` function to create a StringSchema + * The IntSchema transformer class, use instead `S.Int` function to create an IntSchema * * @since 2.2.0 * @category Transformations @@ -47,7 +47,7 @@ export class IntSchema< } /** - * Brands this string schema with a certain brand + * Brands this Int schema with a certain brand * * @since 2.2.0 */ @@ -55,7 +55,7 @@ export class IntSchema< () => unsafeCoerce(this) /** - * Sets the minimum required length of the string + * Sets the minimum value of the IntSchema * * @since 2.2.0 */ @@ -64,7 +64,7 @@ export class IntSchema< ) => IntSchema = min => new IntSchema({ ...this.params, min }) /** - * Sets the maximum required length of the string + * Sets the maximum value of the IntSchema * * @since 2.2.0 */ From 07c33d09b4dbd4615d9eeae6e30482a0ea52451b Mon Sep 17 00:00:00 2001 From: Jacob Alford Date: Wed, 8 Nov 2023 14:49:03 -0700 Subject: [PATCH 09/16] feat(StructSchema): make definition public --- docs/schemata/Struct.md | 2 +- src/schemata/Struct.ts | 27 +++++++++++++++------------ 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/docs/schemata/Struct.md b/docs/schemata/Struct.md index f34467eb..b78f595f 100644 --- a/docs/schemata/Struct.md +++ b/docs/schemata/Struct.md @@ -62,7 +62,7 @@ Use `Struct({})` schema combinator instead ```ts export declare class StructSchema { - constructor(private readonly props: T, private readonly indexSignature?: ExtraProps) + constructor(public readonly definition: T, private readonly indexSignature?: ExtraProps) } ``` diff --git a/src/schemata/Struct.ts b/src/schemata/Struct.ts index e9fd34d9..49124fb2 100644 --- a/src/schemata/Struct.ts +++ b/src/schemata/Struct.ts @@ -75,17 +75,17 @@ export class StructSchema implements Schema, Output> { constructor( - private readonly props: T, + public readonly definition: T, private readonly indexSignature?: ExtraProps, ) { super((_: Schemable) => { const struct: Record> = {} const structName: Record> = {} - for (const key in props) { - if (!hasOwn(props, key)) continue + for (const key in definition) { + if (!hasOwn(definition, key)) continue // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const schema = props[key]! + const schema = definition[key]! const schemable: SchemableKind = schema.runSchema(_) const guard = deriveGuard(schema) const information = deriveInformation(schema) @@ -136,7 +136,7 @@ export class StructSchema ): StructSchema>, Ix> => new StructSchema( pipe( - this.props, + this.definition, RR.filterWithIndex(k => keys.includes(k as K)), _ => unsafeCoerce(_), ), @@ -155,7 +155,7 @@ export class StructSchema ): StructSchema>, Ix> => new StructSchema( pipe( - this.props, + this.definition, RR.filterWithIndex(k => !keys.includes(k as K)), _ => unsafeCoerce(_), ), @@ -174,7 +174,7 @@ export class StructSchema Simplify>> > => unsafeCoerce( - new StructSchema(pipe(this.props, RR.map(Optional)), this.indexSignature), + new StructSchema(pipe(this.definition, RR.map(Optional)), this.indexSignature), ) /** @@ -190,7 +190,10 @@ export class StructSchema Simplify> > => unsafeCoerce( - new StructSchema(pipe(this.props, RR.map(OptionFromOptional)), this.indexSignature), + new StructSchema( + pipe(this.definition, RR.map(OptionFromOptional)), + this.indexSignature, + ), ) /** @@ -203,7 +206,7 @@ export class StructSchema public readonly readonly = (): Schema< Simplify>>, Simplify>> - > => Readonly(new StructSchema(this.props, this.indexSignature)) + > => Readonly(new StructSchema(this.definition, this.indexSignature)) /** * Sets a Struct Schema's index signature to be strict @@ -213,7 +216,7 @@ export class StructSchema * @since 2.1.0 */ public readonly strict = (): StructSchema => - new StructSchema(this.props, 'error') + new StructSchema(this.definition, 'error') /** * Adds an index signature to a Struct Schema. @@ -224,7 +227,7 @@ export class StructSchema */ public readonly addIndexSignature = >( indexSignature: Ix2, - ): StructSchema => new StructSchema(this.props, indexSignature) + ): StructSchema => new StructSchema(this.definition, indexSignature) /** * Extends a Struct Schema with additional properties. Keys specified in `props` will @@ -253,7 +256,7 @@ export class StructSchema that: StructSchema, ): StructSchema, Ix> => new StructSchema( - { ...this.props, ...that.props } as Spread, + { ...this.definition, ...that.definition } as Spread, this.indexSignature, ) } From 002020c282cbc1a34a238df5052bbbe0d7fb2450 Mon Sep 17 00:00:00 2001 From: Jacob Alford Date: Mon, 16 Oct 2023 17:16:25 -0600 Subject: [PATCH 10/16] feat(string): add StringSchema schema transformer --- docs/schemata/String.md | 72 +++++++++++++++++++++++++++++++++- src/schemata/NonEmptyString.ts | 7 ++-- src/schemata/String.ts | 53 +++++++++++++++++++++++-- tests/String.test.ts | 29 ++++++++++++++ 4 files changed, 152 insertions(+), 9 deletions(-) diff --git a/docs/schemata/String.md b/docs/schemata/String.md index f0bebe26..377d957d 100644 --- a/docs/schemata/String.md +++ b/docs/schemata/String.md @@ -14,6 +14,12 @@ Added in v1.0.0 - [String](#string) - [String](#string-1) +- [Transformations](#transformations) + - [StringSchema (class)](#stringschema-class) + - [brand (property)](#brand-property) + - [minLength (property)](#minlength-property) + - [maxLength (property)](#maxlength-property) + - [errorName (property)](#errorname-property) --- @@ -26,7 +32,71 @@ Represents string inputs / outputs **Signature** ```ts -export declare const String: (params?: StringParams | undefined) => Schema +export declare const String: (params?: StringParams | undefined) => StringSchema ``` Added in v1.0.0 + +# Transformations + +## StringSchema (class) + +The StringSchema transformer class, use instead `S.String` function to create a StringSchema + +**Signature** + +```ts +export declare class StringSchema { + constructor(private readonly params?: StringParams) +} +``` + +Added in v2.2.0 + +### brand (property) + +Brands this string schema with a certain brand + +**Signature** + +```ts +readonly brand: () => Schema, Opaque> +``` + +Added in v2.2.0 + +### minLength (property) + +Sets the minimum required length of the string + +**Signature** + +```ts +readonly minLength: (minLength: number) => StringSchema +``` + +Added in v2.2.0 + +### maxLength (property) + +Sets the maximum required length of the string + +**Signature** + +```ts +readonly maxLength: (maxLength: number) => StringSchema +``` + +Added in v2.2.0 + +### errorName (property) + +Overrides the 'expected' field in TranscodeError > TypeMismatch + +**Signature** + +```ts +readonly errorName: (errorName: string) => StringSchema +``` + +Added in v2.2.0 diff --git a/src/schemata/NonEmptyString.ts b/src/schemata/NonEmptyString.ts index fd132b38..70e9462f 100644 --- a/src/schemata/NonEmptyString.ts +++ b/src/schemata/NonEmptyString.ts @@ -1,7 +1,6 @@ /** @since 1.0.0 */ import { type Branded } from 'schemata-ts/brand' import { type Schema } from 'schemata-ts/Schema' -import { Brand } from 'schemata-ts/schemata/Brand' import { String } from 'schemata-ts/schemata/String' interface NonEmptyStringBrand { @@ -22,6 +21,6 @@ export type NonEmptyString = Branded * @since 1.0.0 * @category String */ -export const NonEmptyString: Schema = Brand()( - String({ minLength: 1 }), -) +export const NonEmptyString: Schema = String({ + minLength: 1, +}).brand() diff --git a/src/schemata/String.ts b/src/schemata/String.ts index a535065d..f59a9d7e 100644 --- a/src/schemata/String.ts +++ b/src/schemata/String.ts @@ -1,6 +1,7 @@ /** @since 1.0.0 */ -import { make } from 'schemata-ts/internal/schema' -import { type Schema } from 'schemata-ts/Schema' +import { unsafeCoerce } from 'fp-ts/function' +import { type Branded } from 'schemata-ts/brand' +import { type Schema, SchemaImplementation } from 'schemata-ts/Schema' import { type StringParams } from 'schemata-ts/schemables/primitives/definition' /** @@ -9,5 +10,49 @@ import { type StringParams } from 'schemata-ts/schemables/primitives/definition' * @since 1.0.0 * @category String */ -export const String = (params?: StringParams): Schema => - make(s => s.string(params)) +export const String = (params?: StringParams): StringSchema => new StringSchema(params) + +/** + * The StringSchema transformer class, use instead `S.String` function to create a StringSchema + * + * @since 2.2.0 + * @category Transformations + */ +export class StringSchema extends SchemaImplementation { + constructor(private readonly params?: StringParams) { + super(s => s.string(params)) + } + + /** + * Brands this string schema with a certain brand + * + * @since 2.2.0 + */ + public readonly brand: () => Schema> = () => + unsafeCoerce(this) + + /** + * Sets the minimum required length of the string + * + * @since 2.2.0 + */ + public readonly minLength: (minLength: number) => StringSchema = minLength => + new StringSchema({ ...this.params, minLength }) + + /** + * Sets the maximum required length of the string + * + * @since 2.2.0 + */ + public readonly maxLength: (maxLength: number) => StringSchema = maxLength => + new StringSchema({ ...this.params, maxLength }) + + /** + * Overrides the 'expected' field in TranscodeError > TypeMismatch + * + * @since 2.2.0 + * @default 'string' + */ + public readonly errorName: (errorName: string) => StringSchema = errorName => + new StringSchema({ ...this.params, errorName }) +} diff --git a/tests/String.test.ts b/tests/String.test.ts index cb763376..60765608 100644 --- a/tests/String.test.ts +++ b/tests/String.test.ts @@ -1,5 +1,8 @@ +import { expectTypeOf } from 'expect-type' import * as S from 'schemata-ts' +import { type Branded } from 'schemata-ts/brand' import * as JS from 'schemata-ts/JsonSchema' +import * as TC from 'schemata-ts/Transcoder' import { runStandardTestSuite } from '../test-utils/test-suite' @@ -65,3 +68,29 @@ runStandardTestSuite(S.String({ minLength: 10, maxLength: 20 }), _ => ({ jsonSchema: JS.string({ minLength: 10, maxLength: 20 }), typeString: 'string<10,20>', }))() + +interface TestBrand_ { + readonly Brand: unique symbol +} + +const TestTBase = S.String().minLength(1).maxLength(5).errorName('TestT') + +test('string-transformations', () => { + expectTypeOf(TestTBase).toMatchTypeOf>() +}) + +const TestT = TestTBase.brand() + +test('.brand()', () => { + expectTypeOf(TestT).toEqualTypeOf< + S.Schema, Branded> + >() +}) + +runStandardTestSuite(TestT, _ => ({ + decoderTests: [ + _.decoder.pass('abcd'), + _.decoder.fail('', () => TC.transcodeErrors(TC.typeMismatch('TestT', ''))), + _.decoder.fail('abcdef', _ => TC.transcodeErrors(TC.typeMismatch('TestT', _))), + ], +}))() From d08386ed0aaf937a2c1d70b429a942820d948249 Mon Sep 17 00:00:00 2001 From: Jacob Alford Date: Wed, 11 Oct 2023 15:12:50 -0600 Subject: [PATCH 11/16] feat(TupleSchema): add TupleSchema fluent transformer --- docs/schemata/Tuple.md | 48 ++++++++++++++++++++++++-- src/schemata/Tuple.ts | 76 ++++++++++++++++++++++++++++++------------ tests/Tuple.test.ts | 38 +++++++++++++++++---- 3 files changed, 132 insertions(+), 30 deletions(-) diff --git a/docs/schemata/Tuple.md b/docs/schemata/Tuple.md index 76990e88..73b44304 100644 --- a/docs/schemata/Tuple.md +++ b/docs/schemata/Tuple.md @@ -14,6 +14,10 @@ Added in v1.4.0 - [Combinators](#combinators) - [Tuple](#tuple) +- [Transformations](#transformations) + - [TupleSchema (class)](#tupleschema-class) + - [append (property)](#append-property) + - [prepend (property)](#prepend-property) --- @@ -26,9 +30,47 @@ A schema for n-tuples **Signature** ```ts -export declare const Tuple: []>( - ...items: T -) => Schema<{ readonly [K in keyof T]: InputOf }, { readonly [K in keyof T]: TypeOf }> +export declare const Tuple: []>(...items: T) => TupleSchema ``` Added in v1.0.0 + +# Transformations + +## TupleSchema (class) + +The TupleSchema transformer class, use instead `Tuple` function + +**Signature** + +```ts +export declare class TupleSchema { + constructor(private readonly items: T) +} +``` + +Added in v2.2.0 + +### append (property) + +Appends items to the end of the tuple + +**Signature** + +```ts +readonly append: []>(...items: U) => TupleSchema +``` + +Added in v2.2.0 + +### prepend (property) + +Prepends items to the beginning of the tuple + +**Signature** + +```ts +readonly prepend: []>(...items: U) => TupleSchema +``` + +Added in v2.2.0 diff --git a/src/schemata/Tuple.ts b/src/schemata/Tuple.ts index 41ce12c7..c20d1fa1 100644 --- a/src/schemata/Tuple.ts +++ b/src/schemata/Tuple.ts @@ -1,9 +1,13 @@ /** @since 1.4.0 */ -import { pipe, unsafeCoerce } from 'fp-ts/function' -import * as RA from 'fp-ts/ReadonlyArray' import { deriveTypeString } from 'schemata-ts/derivations/type-string-schemable' -import { make } from 'schemata-ts/internal/schema' -import { type InputOf, type OutputOf, type Schema } from 'schemata-ts/Schema' +import { type SchemableKind, type SchemableLambda } from 'schemata-ts/internal/schemable' +import { + type InputOf, + type OutputOf, + type Schema, + SchemaImplementation, +} from 'schemata-ts/Schema' +import { type Schemable } from 'schemata-ts/Schemable' import { ArrayTypeString } from 'schemata-ts/schemables/array/instances/type-string' /** @@ -14,22 +18,52 @@ import { ArrayTypeString } from 'schemata-ts/schemables/array/instances/type-str */ export const Tuple = >>( ...items: T -): Schema< - { - readonly [K in keyof T]: InputOf - }, - { - readonly [K in keyof T]: OutputOf +): TupleSchema => new TupleSchema(items) + +type Input>> = { + readonly [K in keyof T]: InputOf +} + +type Output>> = { + readonly [K in keyof T]: OutputOf +} + +/** + * The TupleSchema transformer class, use instead `Tuple` function + * + * @since 2.2.0 + * @category Transformations + */ +export class TupleSchema< + T extends ReadonlyArray>, +> extends SchemaImplementation, Output> { + constructor(private readonly items: T) { + const name = ArrayTypeString.tuple('', ...items.map(deriveTypeString))[0] + super( + (s: Schemable) => + s.tuple(name, ...items.map(schema => schema.runSchema(s))) as SchemableKind< + S, + Input, + Output + >, + ) } -> => { - const name = ArrayTypeString.tuple('', ...items.map(deriveTypeString))[0] - return unsafeCoerce( - make(S => - pipe( - items, - RA.map(schema => schema.runSchema(S)), - schemable => S.tuple(name, ...schemable), - ), - ), - ) + + /** + * Appends items to the end of the tuple + * + * @since 2.2.0 + */ + public readonly append = >>( + ...items: U + ): TupleSchema => new TupleSchema([...this.items, ...items]) + + /** + * Prepends items to the beginning of the tuple + * + * @since 2.2.0 + */ + public readonly prepend = >>( + ...items: U + ): TupleSchema => new TupleSchema([...items, ...this.items]) } diff --git a/tests/Tuple.test.ts b/tests/Tuple.test.ts index 87c4d741..072a9dc7 100644 --- a/tests/Tuple.test.ts +++ b/tests/Tuple.test.ts @@ -1,16 +1,42 @@ +import { expectTypeOf } from 'expect-type' import * as S from 'schemata-ts' +import { type Integer } from 'schemata-ts/integer' import * as JS from 'schemata-ts/JsonSchema' +import * as TC from 'schemata-ts/Transcoder' import { runStandardTestSuite } from '../test-utils/test-suite' -runStandardTestSuite(S.Tuple(S.String(), S.Natural), () => ({ - jsonSchema: JS.tuple(JS.string(), JS.integer({ minimum: 0 })), +const SchemaBase = S.Tuple(S.String(), S.Natural) + +const Schema = SchemaBase.prepend(S.Boolean).append(S.String()) + +test('Tuple Types', () => { + expectTypeOf(Schema).toMatchTypeOf< + S.Schema, string]> + >() +}) + +runStandardTestSuite(Schema, _ => ({ + decoderTests: [ + _.decoder.pass([true, 'foo', 1, 'bar']), + _.decoder.fail(['a', 1], () => + TC.transcodeErrors( + TC.typeMismatch('[boolean, string, Integer<0,>, string]', ['a', 1]), + ), + ), + ], + jsonSchema: JS.tuple( + JS.booleanSchema, + JS.string(), + JS.integer({ minimum: 0 }), + JS.string(), + ), jsonSchema2020: { type: 'array', - prefixItems: [JS.string(), JS.integer({ minimum: 0 })], + prefixItems: [JS.booleanSchema, JS.string(), JS.integer({ minimum: 0 }), JS.string()], items: false, - maxItems: 2, - minItems: 2, + maxItems: 4, + minItems: 4, }, - typeString: '[string, Integer<0,>]', + typeString: '[boolean, string, Integer<0,>, string]', }))() From 0625779a20d6de9194a777b1df41ac283955e5ac Mon Sep 17 00:00:00 2001 From: Jacob Alford Date: Tue, 24 Oct 2023 16:31:27 -0600 Subject: [PATCH 12/16] feat(Parse): make Parse preserve branded type refinement --- docs/schemata/FloatFromString.md | 8 ++--- docs/schemata/IntFromString.md | 8 ++--- docs/schemata/Parse.md | 8 ++--- docs/schemata/ParseFloat.md | 54 +++++++++++++++++++++++++++++ docs/schemata/ParseInt.md | 48 +++++++++++++++++++++++++ docs/schemata/index.md | 4 ++- src/schemables/parser/definition.ts | 6 ++-- src/schemata/Parse.ts | 8 ++--- 8 files changed, 124 insertions(+), 20 deletions(-) create mode 100644 docs/schemata/ParseFloat.md create mode 100644 docs/schemata/ParseInt.md diff --git a/docs/schemata/FloatFromString.md b/docs/schemata/FloatFromString.md index c89cc2ba..c96da01a 100644 --- a/docs/schemata/FloatFromString.md +++ b/docs/schemata/FloatFromString.md @@ -13,7 +13,7 @@ Added in v1.0.0

Table of contents

- [Conversion](#conversion) - - [FloatFromString](#floatfromstring) + - [~~FloatFromString~~](#floatfromstring) - [utils](#utils) - [FloatString (type alias)](#floatstring-type-alias) @@ -21,7 +21,7 @@ Added in v1.0.0 # Conversion -## FloatFromString +## ~~FloatFromString~~ Floating point branded newtype from strings. Parameters: min, max are inclusive. @@ -35,7 +35,7 @@ Represents string floating point numbers: ```ts export declare const FloatFromString: Schema< - Opaque, + Opaque>, Opaque> > ``` @@ -51,7 +51,7 @@ A string that can safely be parsed to a floating point number. **Signature** ```ts -export type FloatString = Branded +export type FloatString = Branded> ``` Added in v2.0.0 diff --git a/docs/schemata/IntFromString.md b/docs/schemata/IntFromString.md index 5f972580..8029a3af 100644 --- a/docs/schemata/IntFromString.md +++ b/docs/schemata/IntFromString.md @@ -13,7 +13,7 @@ Added in v1.0.0

Table of contents

- [Conversion](#conversion) - - [IntFromString](#intfromstring) + - [~~IntFromString~~](#intfromstring) - [Pattern](#pattern) - [intFromString](#intfromstring) - [utils](#utils) @@ -23,7 +23,7 @@ Added in v1.0.0 # Conversion -## IntFromString +## ~~IntFromString~~ Integer branded newtype from string. Parameters: min, max are inclusive. @@ -43,7 +43,7 @@ Represents string-integers: ```ts export declare const IntFromString: Schema< - Opaque, + Opaque>, Opaque> > ``` @@ -71,7 +71,7 @@ A string that can safely be parsed to a floating point number. **Signature** ```ts -export type IntString = Branded +export type IntString = Branded> ``` Added in v2.0.0 diff --git a/docs/schemata/Parse.md b/docs/schemata/Parse.md index b66c4a5d..27458d01 100644 --- a/docs/schemata/Parse.md +++ b/docs/schemata/Parse.md @@ -28,12 +28,12 @@ A schema for pre-parsing/printing a string **Signature** ```ts -export declare const Parse: ( - name: string, +export declare const Parse: ( + inputName: string, parse: (raw: string) => Either, - print: (a: I) => Either, + print: (a: I) => Either, options?: ParserOptions | undefined -) => (inner: Schema) => Schema +) => (inner: Schema) => Schema ``` Added in v2.0.0 diff --git a/docs/schemata/ParseFloat.md b/docs/schemata/ParseFloat.md new file mode 100644 index 00000000..e9bfe6d1 --- /dev/null +++ b/docs/schemata/ParseFloat.md @@ -0,0 +1,54 @@ +--- +title: ParseFloat +nav_order: 67 +parent: schemata +--- + +## ParseFloat overview + +Added in v2.2.0 + +--- + +

Table of contents

+ +- [Printer Parsers](#printer-parsers) + - [ParseFloat](#parsefloat) + +--- + +# Printer Parsers + +## ParseFloat + +Parses a string into an float. A slightly more performant variant of the now deprecated +`S.FloatFromString` with the additional ability to specify `min` / `max` bounds. + +**Signature** + +```ts +export declare const ParseFloat: < + Min extends number | undefined = undefined, + Max extends number | undefined = undefined +>( + params?: NumberParams | undefined +) => Schema< + Opaque< + string, + { + readonly FloatString: unique symbol + readonly Min: Min extends undefined ? -1.7976931348623157e308 : Min + readonly Max: Max extends undefined ? 1.7976931348623157e308 : Max + } + >, + Opaque< + number, + FloatBrand< + Min extends undefined ? -1.7976931348623157e308 : Min, + Max extends undefined ? 1.7976931348623157e308 : Max + > + > +> +``` + +Added in v2.2.0 diff --git a/docs/schemata/ParseInt.md b/docs/schemata/ParseInt.md new file mode 100644 index 00000000..b5dac03d --- /dev/null +++ b/docs/schemata/ParseInt.md @@ -0,0 +1,48 @@ +--- +title: ParseInt +nav_order: 68 +parent: schemata +--- + +## ParseInt overview + +Added in v2.2.0 + +--- + +

Table of contents

+ +- [Printer Parsers](#printer-parsers) + - [ParseInt](#parseint) + +--- + +# Printer Parsers + +## ParseInt + +Parses a string into an integer. A slightly more performant variant of the now +deprecated `S.IntFromString` with the additional ability to specify `min` / `max` bounds. + +**Signature** + +```ts +export declare const ParseInt: ( + params?: NumberParams | undefined +) => Schema< + Opaque< + string, + { + readonly IntString: unique symbol + readonly min: Min extends undefined ? -9007199254740991 : Min + readonly max: Max extends undefined ? 9007199254740991 : Max + } + >, + Opaque< + number, + IntBrand + > +> +``` + +Added in v2.2.0 diff --git a/docs/schemata/index.md b/docs/schemata/index.md index 15a0f561..622dc62e 100644 --- a/docs/schemata/index.md +++ b/docs/schemata/index.md @@ -75,10 +75,12 @@ has_children: true * PositiveFloat ([docs](https://jacob-alford.github.io/schemata-ts/schemata/PositiveFloat.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/PositiveFloat.ts)) * PositiveInt ([docs](https://jacob-alford.github.io/schemata-ts/schemata/PositiveInt.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/PositiveInt.ts)) -### Printer Parsers (3) +### Printer Parsers (5) * ParseBase64Json ([docs](https://jacob-alford.github.io/schemata-ts/schemata/ParseBase64Json.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/ParseBase64Json.ts)) * ParseEncodedJson ([docs](https://jacob-alford.github.io/schemata-ts/schemata/ParseEncodedJson.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/ParseEncodedJson.ts)) +* ParseFloat ([docs](https://jacob-alford.github.io/schemata-ts/schemata/ParseFloat.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/ParseFloat.ts)) +* ParseInt ([docs](https://jacob-alford.github.io/schemata-ts/schemata/ParseInt.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/ParseInt.ts)) * ParseJsonString ([docs](https://jacob-alford.github.io/schemata-ts/schemata/ParseJsonString.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/ParseJsonString.ts)) ### String (17) diff --git a/src/schemables/parser/definition.ts b/src/schemables/parser/definition.ts index ad0355b9..18383aec 100644 --- a/src/schemables/parser/definition.ts +++ b/src/schemables/parser/definition.ts @@ -6,12 +6,12 @@ declare const jsonString: unique symbol export type JsonString = Branded export interface WithParser { - readonly parse: ( + readonly parse: ( name: string, parse: (encoded: string) => E.Either, - print: (a: I) => E.Either, + print: (a: I) => E.Either, contentEncoding?: string, contentMediaType?: string, format?: string, - ) =>
(inner: SchemableKind) => SchemableKind + ) => (inner: SchemableKind) => SchemableKind } diff --git a/src/schemata/Parse.ts b/src/schemata/Parse.ts index 37d44b79..aaef42f1 100644 --- a/src/schemata/Parse.ts +++ b/src/schemata/Parse.ts @@ -16,12 +16,12 @@ export type ParserOptions = { * @since 2.0.0 * @category Combinators */ -export const Parse: ( - name: string, +export const Parse: ( + inputName: string, parse: (raw: string) => Either, - print: (a: I) => Either, + print: (a: I) => Either, options?: ParserOptions, -) => (inner: Schema) => Schema = +) => (inner: Schema) => Schema = (name, parse, print, options = {}) => inner => make(_ => From de956e44ada511582f91c11a3dfb6c5c1a787b32 Mon Sep 17 00:00:00 2001 From: Jacob Alford Date: Tue, 24 Oct 2023 16:34:28 -0600 Subject: [PATCH 13/16] feat(ParseInt): add ParseInt schema --- src/schemata/IntFromString.ts | 14 +++++-- src/schemata/ParseInt.ts | 73 +++++++++++++++++++++++++++++++++ src/schemata/index.ts | 1 + tests/ParseInt.test.ts | 76 +++++++++++++++++++++++++++++++++++ 4 files changed, 160 insertions(+), 4 deletions(-) create mode 100644 src/schemata/ParseInt.ts create mode 100644 tests/ParseInt.test.ts diff --git a/src/schemata/IntFromString.ts b/src/schemata/IntFromString.ts index 1d2b2b45..f9ee270b 100644 --- a/src/schemata/IntFromString.ts +++ b/src/schemata/IntFromString.ts @@ -2,7 +2,7 @@ import { pipe } from 'fp-ts/function' import * as k from 'kuvio' import { type Branded } from 'schemata-ts/brand' -import { type Integer } from 'schemata-ts/integer' +import { type Integer, type MaxSafeInt, type MinSafeInt } from 'schemata-ts/integer' import { type Schema } from 'schemata-ts/Schema' import { PrimitivesGuard } from 'schemata-ts/schemables/primitives/instances/guard' import { PrimitivesTypeString } from 'schemata-ts/schemables/primitives/instances/type-string' @@ -10,8 +10,10 @@ import { Brand } from 'schemata-ts/schemata/Brand' import { Imap } from 'schemata-ts/schemata/Imap' import { Pattern } from 'schemata-ts/schemata/Pattern' -type IntStringBrand = { +type IntStringBrand = { readonly IntString: unique symbol + readonly min: Min + readonly max: Max } /** @@ -19,7 +21,10 @@ type IntStringBrand = { * * @since 2.0.0 */ -export type IntString = Branded +export type IntString = Branded< + string, + IntStringBrand +> /** * @since 1.0.0 @@ -84,12 +89,13 @@ export const intFromString: k.Pattern = k.oneOf( * { z | z ∈ ℤ, z >= -2 ** 53 + 1, z <= 2 ** 53 - 1 } * ``` * + * @deprecated Use `ParseInt` instead. * @since 1.0.0 * @category Conversion */ export const IntFromString: Schema = pipe( Pattern(intFromString, ['IntString', PrimitivesTypeString.int()[1]]), - Brand(), + Brand>(), Imap( PrimitivesGuard.int(), s => Number(s) as Integer, diff --git a/src/schemata/ParseInt.ts b/src/schemata/ParseInt.ts new file mode 100644 index 00000000..a1fe06e9 --- /dev/null +++ b/src/schemata/ParseInt.ts @@ -0,0 +1,73 @@ +/** @since 2.2.0 */ +import * as E from 'fp-ts/Either' +import { flow, pipe } from 'fp-ts/function' +import * as Str from 'fp-ts/string' +import { type Integer, type MaxSafeInt, type MinSafeInt } from 'schemata-ts/integer' +import { type Schema } from 'schemata-ts/Schema' +import { type NumberParams } from 'schemata-ts/schemables/primitives/definition' +import { getNumberBoundsInt, isInt } from 'schemata-ts/schemables/primitives/utils' +import { Int } from 'schemata-ts/schemata/Int' +import { type IntString } from 'schemata-ts/schemata/IntFromString' +import { Parse } from 'schemata-ts/schemata/Parse' + +/** + * Parses a string into an integer. A slightly more performant variant of the now + * deprecated `S.IntFromString` with the additional ability to specify `min` / `max` bounds. + * + * @since 2.2.0 + * @category Printer Parsers + */ +export const ParseInt = < + Min extends number | undefined = undefined, + Max extends number | undefined = undefined, +>( + params?: NumberParams, +): Schema< + IntString< + Min extends undefined ? MinSafeInt : Min, + Max extends undefined ? MaxSafeInt : Max + >, + Integer< + Min extends undefined ? MinSafeInt : Min, + Max extends undefined ? MaxSafeInt : Max + > +> => + pipe( + Int(params), + Parse< + Integer< + Min extends undefined ? MinSafeInt : Min, + Max extends undefined ? MaxSafeInt : Max + >, + IntString< + Min extends undefined ? MinSafeInt : Min, + Max extends undefined ? MaxSafeInt : Max + > + >( + `IntString${getNumberBoundsInt(params)}`, + flow( + Str.trim, + E.fromPredicate( + s => s.length > 0, + () => 'Expected a non-empty integer string', + ), + E.map(Number), + E.filterOrElse( + isInt(params), + n => + `Expected an integer between ${params?.min ?? Number.MIN_SAFE_INTEGER} and ${ + params?.max ?? Number.MAX_SAFE_INTEGER + }, but got ${n}`, + ), + ), + flow( + String, + _ => + _ as IntString< + Min extends undefined ? MinSafeInt : Min, + Max extends undefined ? MaxSafeInt : Max + >, + E.right, + ), + ), + ) diff --git a/src/schemata/index.ts b/src/schemata/index.ts index 546e7f0e..dd816313 100644 --- a/src/schemata/index.ts +++ b/src/schemata/index.ts @@ -62,6 +62,7 @@ export * from 'schemata-ts/schemata/OptionFromNullable' export * from 'schemata-ts/schemata/Parse' export * from 'schemata-ts/schemata/ParseBase64Json' export * from 'schemata-ts/schemata/ParseEncodedJson' +export * from 'schemata-ts/schemata/ParseInt' export * from 'schemata-ts/schemata/ParseJsonString' export * from 'schemata-ts/schemata/Partial' export * from 'schemata-ts/schemata/Pattern' diff --git a/tests/ParseInt.test.ts b/tests/ParseInt.test.ts new file mode 100644 index 00000000..38b7dde2 --- /dev/null +++ b/tests/ParseInt.test.ts @@ -0,0 +1,76 @@ +import { expectTypeOf } from 'expect-type' +import * as S from 'schemata-ts' +import { type Integer, type MaxSafeInt, type MinSafeInt } from 'schemata-ts/integer' +import { type IntString } from 'schemata-ts/schemata/IntFromString' +import * as TC from 'schemata-ts/Transcoder' + +import { runStandardTestSuite } from '../test-utils/test-suite' + +const valid = [ + '0', + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + '10', + '1e+1', + '1e1', + '-1', + '11', + '1.1e1', +] +const invalid = ['1.1', '1e-1', '1.1e-1', '', ' ', 'a', '1a', 'a1'] + +const Unbounded = S.ParseInt() + +runStandardTestSuite(Unbounded, _ => ({ + decoderTests: [ + ...valid.map(v => _.decoder.pass(v, Number(v))), + ...invalid.map(v => + _.decoder.fail(v, () => + TC.transcodeErrors(TC.serializationError('IntString', expect.any(String), v)), + ), + ), + ], + encoderTests: [ + _.encoder.pass(_.c(0), _.c('0')), + _.encoder.pass(_.c(Number.MIN_SAFE_INTEGER), _.c('-9007199254740991')), + _.encoder.pass(_.c(Number.MAX_SAFE_INTEGER), _.c('9007199254740991')), + ], +}))() + +test('Unbounded types', () => { + expectTypeOf(Unbounded).toEqualTypeOf< + S.Schema, Integer> + >() +}) + +const Bounded = S.ParseInt({ min: 0, max: 10 }) + +test('Bounded types', () => { + expectTypeOf(Bounded).toEqualTypeOf, Integer<0, 10>>>() +}) + +runStandardTestSuite(Bounded, _ => ({ + decoderTests: [ + _.decoder.fail('-1', () => + TC.transcodeErrors( + TC.serializationError('IntString<0,10>', expect.any(String), '-1'), + ), + ), + _.decoder.pass('0', 0), + + _.decoder.pass('1', 1), + _.decoder.fail('11', () => + TC.transcodeErrors( + TC.serializationError('IntString<0,10>', expect.any(String), '11'), + ), + ), + ], + encoderTests: [_.encoder.pass(_.c(0), _.c('0')), _.encoder.pass(_.c(10), _.c('10'))], +}))() From 7f4f93a4a02745e0265986f70f55771e44a024cd Mon Sep 17 00:00:00 2001 From: Jacob Alford Date: Tue, 24 Oct 2023 16:34:42 -0600 Subject: [PATCH 14/16] feat(ParseFloat): add ParseFloat schema --- src/schemata/FloatFromString.ts | 18 +++++-- src/schemata/ParseFloat.ts | 77 +++++++++++++++++++++++++++++ src/schemata/index.ts | 1 + tests/ParseFloat.test.ts | 86 +++++++++++++++++++++++++++++++++ 4 files changed, 178 insertions(+), 4 deletions(-) create mode 100644 src/schemata/ParseFloat.ts create mode 100644 tests/ParseFloat.test.ts diff --git a/src/schemata/FloatFromString.ts b/src/schemata/FloatFromString.ts index ca967ada..daa8d445 100644 --- a/src/schemata/FloatFromString.ts +++ b/src/schemata/FloatFromString.ts @@ -2,7 +2,11 @@ import { pipe } from 'fp-ts/function' import * as k from 'kuvio' import { type Branded } from 'schemata-ts/brand' -import { type Float } from 'schemata-ts/float' +import { + type Float, + type MaxNegativeFloat, + type MaxPositiveFloat, +} from 'schemata-ts/float' import { type Schema } from 'schemata-ts/Schema' import { PrimitivesGuard } from 'schemata-ts/schemables/primitives/instances/guard' import { Brand } from 'schemata-ts/schemata/Brand' @@ -10,8 +14,10 @@ import { Imap } from 'schemata-ts/schemata/Imap' import { Pattern } from 'schemata-ts/schemata/Pattern' import { Refine } from 'schemata-ts/schemata/Refine' -type FloatStringBrand = { +type FloatStringBrand = { readonly FloatString: unique symbol + readonly Min: Min + readonly Max: Max } /** @@ -19,7 +25,10 @@ type FloatStringBrand = { * * @since 2.0.0 */ -export type FloatString = Branded +export type FloatString = Branded< + string, + FloatStringBrand +> /** * Negative floats with at least one digit before the decimal point. @@ -133,6 +142,7 @@ const floatFromString: k.Pattern = pipe( * { f | f ∈ ℝ, f >= -Number.MAX_VALUE, f <= Number.MAX_VALUE } * ``` * + * @deprecated Use `ParseFloat` instead. * @since 1.0.0 * @category Conversion */ @@ -142,7 +152,7 @@ export const FloatFromString: Schema = pipe( (s): s is string => PrimitivesGuard.float().is(Number(s)) && s.trim() !== '', 'Float', ), - Brand(), + Brand>(), Imap( PrimitivesGuard.float(), s => Number(s) as Float, diff --git a/src/schemata/ParseFloat.ts b/src/schemata/ParseFloat.ts new file mode 100644 index 00000000..bd4b2dee --- /dev/null +++ b/src/schemata/ParseFloat.ts @@ -0,0 +1,77 @@ +/** @since 2.2.0 */ +import * as E from 'fp-ts/Either' +import { flow, pipe } from 'fp-ts/function' +import * as Str from 'fp-ts/string' +import { + type Float as Floating, + type MaxNegativeFloat, + type MaxPositiveFloat, +} from 'schemata-ts/float' +import { type Schema } from 'schemata-ts/Schema' +import { type NumberParams } from 'schemata-ts/schemables/primitives/definition' +import { getNumberBoundsInt, isFloat } from 'schemata-ts/schemables/primitives/utils' +import { Float } from 'schemata-ts/schemata/Float' +import { type FloatString } from 'schemata-ts/schemata/FloatFromString' +import { Parse } from 'schemata-ts/schemata/Parse' + +/** + * Parses a string into an float. A slightly more performant variant of the now deprecated + * `S.FloatFromString` with the additional ability to specify `min` / `max` bounds. + * + * @since 2.2.0 + * @category Printer Parsers + */ +export const ParseFloat = < + Min extends number | undefined = undefined, + Max extends number | undefined = undefined, +>( + params?: NumberParams, +): Schema< + FloatString< + Min extends undefined ? MaxNegativeFloat : Min, + Max extends undefined ? MaxPositiveFloat : Max + >, + Floating< + Min extends undefined ? MaxNegativeFloat : Min, + Max extends undefined ? MaxPositiveFloat : Max + > +> => + pipe( + Float(params), + Parse< + Floating< + Min extends undefined ? MaxNegativeFloat : Min, + Max extends undefined ? MaxPositiveFloat : Max + >, + FloatString< + Min extends undefined ? MaxNegativeFloat : Min, + Max extends undefined ? MaxPositiveFloat : Max + > + >( + `FloatString${getNumberBoundsInt(params)}`, + flow( + Str.trim, + E.fromPredicate( + s => s.length > 0, + () => 'Expected a non-empty float string', + ), + E.map(Number), + E.filterOrElse( + isFloat(params), + n => + `Expected a floating point number between ${ + params?.min ?? Number.MIN_SAFE_INTEGER + } and ${params?.max ?? Number.MAX_SAFE_INTEGER}, but got ${n}`, + ), + ), + flow( + String, + _ => + _ as FloatString< + Min extends undefined ? MaxNegativeFloat : Min, + Max extends undefined ? MaxPositiveFloat : Max + >, + E.right, + ), + ), + ) diff --git a/src/schemata/index.ts b/src/schemata/index.ts index dd816313..bcc1b843 100644 --- a/src/schemata/index.ts +++ b/src/schemata/index.ts @@ -62,6 +62,7 @@ export * from 'schemata-ts/schemata/OptionFromNullable' export * from 'schemata-ts/schemata/Parse' export * from 'schemata-ts/schemata/ParseBase64Json' export * from 'schemata-ts/schemata/ParseEncodedJson' +export * from 'schemata-ts/schemata/ParseFloat' export * from 'schemata-ts/schemata/ParseInt' export * from 'schemata-ts/schemata/ParseJsonString' export * from 'schemata-ts/schemata/Partial' diff --git a/tests/ParseFloat.test.ts b/tests/ParseFloat.test.ts new file mode 100644 index 00000000..c8a5003f --- /dev/null +++ b/tests/ParseFloat.test.ts @@ -0,0 +1,86 @@ +import { expectTypeOf } from 'expect-type' +import * as S from 'schemata-ts' +import { + type Float as Floating, + type MaxNegativeFloat, + type MaxPositiveFloat, +} from 'schemata-ts/float' +import { type FloatString } from 'schemata-ts/schemata/FloatFromString' +import * as TC from 'schemata-ts/Transcoder' + +import { runStandardTestSuite } from '../test-utils/test-suite' + +const valid = [ + '0', + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + '10', + '1e+1', + '1e1', + '-1', + '11', + '1.1e1', + '1.1', + '1e-1', + '1.1e-1', +] +const invalid = ['', ' ', 'a', '1a', 'a1'] + +const Unbounded = S.ParseFloat() + +runStandardTestSuite(Unbounded, _ => ({ + decoderTests: [ + ...valid.map(v => _.decoder.pass(v, Number(v))), + ...invalid.map(v => + _.decoder.fail(v, () => + TC.transcodeErrors(TC.serializationError('FloatString', expect.any(String), v)), + ), + ), + ], + encoderTests: [ + _.encoder.pass(_.c(0), _.c('0')), + _.encoder.pass(_.c(Number.MIN_VALUE), _.c(String(Number.MIN_VALUE))), + _.encoder.pass(_.c(Number.MAX_VALUE), _.c(String(Number.MAX_VALUE))), + ], +}))() + +test('Unbounded types', () => { + expectTypeOf(Unbounded).toEqualTypeOf< + S.Schema< + FloatString, + Floating + > + >() +}) + +const Bounded = S.ParseFloat({ min: 0, max: 10 }) + +test('Bounded types', () => { + expectTypeOf(Bounded).toEqualTypeOf, Floating<0, 10>>>() +}) + +runStandardTestSuite(Bounded, _ => ({ + decoderTests: [ + _.decoder.fail('-1', () => + TC.transcodeErrors( + TC.serializationError('FloatString<0,10>', expect.any(String), '-1'), + ), + ), + _.decoder.pass('0', 0), + + _.decoder.pass('1', 1), + _.decoder.fail('11', () => + TC.transcodeErrors( + TC.serializationError('FloatString<0,10>', expect.any(String), '11'), + ), + ), + ], + encoderTests: [_.encoder.pass(_.c(0), _.c('0')), _.encoder.pass(_.c(10), _.c('10'))], +}))() From c23c044ae4220f8feea9425a0db2870124e44138 Mon Sep 17 00:00:00 2001 From: Jacob Alford Date: Wed, 8 Nov 2023 17:23:43 -0700 Subject: [PATCH 15/16] feat(docs): add new transformations to README --- README.md | 34 +++++++++++++++++++------------- docs/TranscodeError.md | 2 +- docs/Transcoder.md | 2 +- docs/TranscoderPar.md | 2 +- docs/TypeString.md | 2 +- docs/index.md | 34 +++++++++++++++++++------------- docs/schemata/Intersect.md | 4 ++-- docs/schemata/ParseFloat.md | 2 +- docs/schemata/ParseInt.md | 2 +- docs/schemata/ParseJsonString.md | 2 +- docs/schemata/Partial.md | 2 +- docs/schemata/Pattern.md | 2 +- docs/schemata/PositiveFloat.md | 2 +- docs/schemata/PositiveInt.md | 2 +- docs/schemata/RGB.md | 2 +- docs/schemata/Readonly.md | 2 +- docs/schemata/Record.md | 2 +- docs/schemata/Refine.md | 2 +- docs/schemata/SetFromArray.md | 2 +- docs/schemata/Strict.md | 2 +- docs/schemata/String.md | 2 +- docs/schemata/Struct.md | 2 +- docs/schemata/Tuple.md | 2 +- docs/schemata/UUID.md | 2 +- docs/schemata/Union.md | 2 +- docs/schemata/Unit.md | 2 +- docs/schemata/Unknown.md | 2 +- docs/schemata/UnknownArray.md | 2 +- docs/schemata/UnknownRecord.md | 2 +- docs/schemata/index.md | 30 ++++++++++++++-------------- package.json | 2 +- src/schemata/Intersect.ts | 1 - 32 files changed, 84 insertions(+), 73 deletions(-) diff --git a/README.md b/README.md index 27180588..e631d48c 100644 --- a/README.md +++ b/README.md @@ -123,20 +123,26 @@ export const PersonSchema = S.Struct({ ## Schema Transformations -There are two types of schema transformations in `schemata-ts`: ['combinators'](#schema) which are functions that take schemas as parameters and return new schemas, and 'transformers' which are specific to a particular schema. Starting with version 2.1 it is possible to adjust the declaration of a schema _after_ it's declared. The possibilities here are endless. Schemata-ts currently supports the following transformations: - -- `StructSchema`: A struct specific schema transformer which permits the following methods: - - `omit`: Omit one or many properties from a struct schema - - `pick`: Pick one or many properties from a struct schema - - `extend`: Extend a struct schema with additional properties - - `intersect`: Extend a struct schema with additional properties from another struct schema - - `partial`: Make both input and output properties of a struct schema optional - - `partialOption`: Make both input properties optional, and map output properties to the fp-ts `Option` type - - `strict`: Raise an `UnexpectedValue` transcode error when encountering unspecified properties - - `addIndexSignature`: Add an index signature to a struct schema, effectively providing a schema for all properties not explicitly defined - - `readonly`: Mark all properties of a struct schema readonly - -And others are soon to come, for instance `Array` and `String` with `nonEmpty`; `Tuple` with `prepend` and `append`; and `Union` with `extend`. +There are three ways to transform a schema in `schemata-ts`: ['combinators'](#schema) which are functions that take schemas as parameters and return new schemas, 'transformers' which are specific to particular schemata, and `Imap` which applies an invariant transformation to the underlying data-type. + +### Invariant Transformations + +Aside from `Guard`, all data-types derivable from schemas are invariant functors. This means that supplying mapping functions `to` and `from` to `Imap` adjusts the `Output` of that particular data type. Because `Guard` is not invariant, you must supply the resulting `Guard` to the invariant map. The combinator version of this is `Imap`. In version `3.0` (coming late 2023/early 2024) it will be possible to `.imap()` any schema. + +### Schema Transformers + +Schema transformers are classes which extend `SchemaImplementation`, and allow adjustment to the underlying schema parameters after it has been declared in an immutable fashion. This is useful for type-specific methods like `pick` or `omit` for `Struct`. + +Here are the current transformers and available methods, + +- Struct: `pick`, `omit`, `partial`, `partialOption`, `readonly`, `strict`, `addIndexSignature`, `extend`, `intersect` +- Array: `minLength`, `maxLength`, `nonEmpty` +- String: `brand`, `minLength`, `maxLength`, `errorName` +- Int: `brand`, `min`, `max`, `errorName` +- Float: `brand`, `min`, `max`, `errorName` +- Tuple: `append`, `prepend` + +... with more to come! ### Transformation Example diff --git a/docs/TranscodeError.md b/docs/TranscodeError.md index 17eaa94c..299dc815 100644 --- a/docs/TranscodeError.md +++ b/docs/TranscodeError.md @@ -1,6 +1,6 @@ --- title: TranscodeError.ts -nav_order: 89 +nav_order: 91 permalink: /transcode-error/ --- diff --git a/docs/Transcoder.md b/docs/Transcoder.md index 8c49d0c9..19e96a1f 100644 --- a/docs/Transcoder.md +++ b/docs/Transcoder.md @@ -1,6 +1,6 @@ --- title: Transcoder.ts -nav_order: 90 +nav_order: 92 permalink: /transcoder/ --- diff --git a/docs/TranscoderPar.md b/docs/TranscoderPar.md index 0ee46bc9..1a38e9c0 100644 --- a/docs/TranscoderPar.md +++ b/docs/TranscoderPar.md @@ -1,6 +1,6 @@ --- title: TranscoderPar.ts -nav_order: 91 +nav_order: 93 permalink: /transcoder-par/ --- diff --git a/docs/TypeString.md b/docs/TypeString.md index 6fa55db2..88846f0c 100644 --- a/docs/TypeString.md +++ b/docs/TypeString.md @@ -1,6 +1,6 @@ --- title: TypeString.ts -nav_order: 92 +nav_order: 94 permalink: /type-string/ --- diff --git a/docs/index.md b/docs/index.md index 66eb43bf..2d91720a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -130,20 +130,26 @@ export const PersonSchema = S.Struct({ ## Schema Transformations -There are two types of schema transformations in `schemata-ts`: ['combinators'](#schema) which are functions that take schemas as parameters and return new schemas, and 'transformers' which are specific to a particular schema. Starting with version 2.1 it is possible to adjust the declaration of a schema _after_ it's declared. The possibilities here are endless. Schemata-ts currently supports the following transformations: - -- `StructSchema`: A struct specific schema transformer which permits the following methods: - - `omit`: Omit one or many properties from a struct schema - - `pick`: Pick one or many properties from a struct schema - - `extend`: Extend a struct schema with additional properties - - `intersect`: Extend a struct schema with additional properties from another struct schema - - `partial`: Make both input and output properties of a struct schema optional - - `partialOption`: Make both input properties optional, and map output properties to the fp-ts `Option` type - - `strict`: Raise an `UnexpectedValue` transcode error when encountering unspecified properties - - `addIndexSignature`: Add an index signature to a struct schema, effectively providing a schema for all properties not explicitly defined - - `readonly`: Mark all properties of a struct schema readonly - -And others are soon to come, for instance `Array` and `String` with `nonEmpty`; `Tuple` with `prepend` and `append`; and `Union` with `extend`. +There are three ways to transform a schema in `schemata-ts`: ['combinators'](#schema) which are functions that take schemas as parameters and return new schemas, 'transformers' which are specific to a particular schema, and `Imap` which applies an invariant transformation to the underlying data-type. + +### Invariant Transformations + +All data-types derivable from schemas are invariant functors, aside from `Guard`. This means that if you supply mapping functions `to`, and `from` the new type, you will adjust the `Output` type of that particular data type. Because `Guard` is not invariant, you must supply the resulting `Guard` to the invariant map. The combinator version of this is `Imap`. In version `3.0` which is coming in late 2023/early 2024 it will be possible to `.imap` a schema. + +### Schema Transformers + +Schema transformers are classes which extend `SchemaImplementation`, and allow adjustment to the underlying schema parameters after it has been declared in an immutable fashion. This is useful for type-specific methods like `pick` or `omit` for `Struct`. + +Here are the current transformers and available methods: + +- `StructSchema`: `pick`, `omit`, `partial`, `partialOption`, `readonly`, `strict`, `addIndexSignature`, `extend`, `intersect` +- `ArraySchema`: `minLength`, `maxLength`, `nonEmpty` +- `StringSchema`: `brand`, `minLength`, `maxLength`, `errorName` +- `IntSchema`: `brand`, `min`, `max`, `errorName` +- `FloatSchema`: `brand`, `min`, `max`, `errorName` +- `TupleSchema`: `append`, `prepend` + +... and more to come! ### Transformation Example diff --git a/docs/schemata/Intersect.md b/docs/schemata/Intersect.md index ed2f4319..cc5b48fd 100644 --- a/docs/schemata/Intersect.md +++ b/docs/schemata/Intersect.md @@ -13,13 +13,13 @@ Added in v1.0.0

Table of contents

- [Combinators](#combinators) - - [~~Intersect~~](#intersect) + - [Intersect](#intersect) --- # Combinators -## ~~Intersect~~ +## Intersect An intersection of two struct-derived types. diff --git a/docs/schemata/ParseFloat.md b/docs/schemata/ParseFloat.md index e9bfe6d1..2f7ed088 100644 --- a/docs/schemata/ParseFloat.md +++ b/docs/schemata/ParseFloat.md @@ -1,6 +1,6 @@ --- title: ParseFloat -nav_order: 67 +nav_order: 69 parent: schemata --- diff --git a/docs/schemata/ParseInt.md b/docs/schemata/ParseInt.md index b5dac03d..3d9c6352 100644 --- a/docs/schemata/ParseInt.md +++ b/docs/schemata/ParseInt.md @@ -1,6 +1,6 @@ --- title: ParseInt -nav_order: 68 +nav_order: 70 parent: schemata --- diff --git a/docs/schemata/ParseJsonString.md b/docs/schemata/ParseJsonString.md index b2130566..dd89db0d 100644 --- a/docs/schemata/ParseJsonString.md +++ b/docs/schemata/ParseJsonString.md @@ -1,6 +1,6 @@ --- title: ParseJsonString -nav_order: 69 +nav_order: 71 parent: schemata --- diff --git a/docs/schemata/Partial.md b/docs/schemata/Partial.md index 3a19083c..569c3ba1 100644 --- a/docs/schemata/Partial.md +++ b/docs/schemata/Partial.md @@ -1,6 +1,6 @@ --- title: Partial -nav_order: 70 +nav_order: 72 parent: schemata --- diff --git a/docs/schemata/Pattern.md b/docs/schemata/Pattern.md index 1c2bbad5..e691fdc1 100644 --- a/docs/schemata/Pattern.md +++ b/docs/schemata/Pattern.md @@ -1,6 +1,6 @@ --- title: Pattern -nav_order: 71 +nav_order: 73 parent: schemata --- diff --git a/docs/schemata/PositiveFloat.md b/docs/schemata/PositiveFloat.md index a0dab945..b4164983 100644 --- a/docs/schemata/PositiveFloat.md +++ b/docs/schemata/PositiveFloat.md @@ -1,6 +1,6 @@ --- title: PositiveFloat -nav_order: 72 +nav_order: 74 parent: schemata --- diff --git a/docs/schemata/PositiveInt.md b/docs/schemata/PositiveInt.md index 169891b1..f24b7f89 100644 --- a/docs/schemata/PositiveInt.md +++ b/docs/schemata/PositiveInt.md @@ -1,6 +1,6 @@ --- title: PositiveInt -nav_order: 73 +nav_order: 75 parent: schemata --- diff --git a/docs/schemata/RGB.md b/docs/schemata/RGB.md index 133c9977..62eb24c1 100644 --- a/docs/schemata/RGB.md +++ b/docs/schemata/RGB.md @@ -1,6 +1,6 @@ --- title: RGB -nav_order: 77 +nav_order: 79 parent: schemata --- diff --git a/docs/schemata/Readonly.md b/docs/schemata/Readonly.md index dab7fca5..9e0db8ab 100644 --- a/docs/schemata/Readonly.md +++ b/docs/schemata/Readonly.md @@ -1,6 +1,6 @@ --- title: Readonly -nav_order: 74 +nav_order: 76 parent: schemata --- diff --git a/docs/schemata/Record.md b/docs/schemata/Record.md index 91daaa10..808e28ca 100644 --- a/docs/schemata/Record.md +++ b/docs/schemata/Record.md @@ -1,6 +1,6 @@ --- title: Record -nav_order: 75 +nav_order: 77 parent: schemata --- diff --git a/docs/schemata/Refine.md b/docs/schemata/Refine.md index cdcd89dd..bbb8715c 100644 --- a/docs/schemata/Refine.md +++ b/docs/schemata/Refine.md @@ -1,6 +1,6 @@ --- title: Refine -nav_order: 76 +nav_order: 78 parent: schemata --- diff --git a/docs/schemata/SetFromArray.md b/docs/schemata/SetFromArray.md index f574153b..a4871f14 100644 --- a/docs/schemata/SetFromArray.md +++ b/docs/schemata/SetFromArray.md @@ -1,6 +1,6 @@ --- title: SetFromArray -nav_order: 78 +nav_order: 80 parent: schemata --- diff --git a/docs/schemata/Strict.md b/docs/schemata/Strict.md index aaa9d1fb..2401b567 100644 --- a/docs/schemata/Strict.md +++ b/docs/schemata/Strict.md @@ -1,6 +1,6 @@ --- title: Strict -nav_order: 79 +nav_order: 81 parent: schemata --- diff --git a/docs/schemata/String.md b/docs/schemata/String.md index 377d957d..1a94e14f 100644 --- a/docs/schemata/String.md +++ b/docs/schemata/String.md @@ -1,6 +1,6 @@ --- title: String -nav_order: 80 +nav_order: 82 parent: schemata --- diff --git a/docs/schemata/Struct.md b/docs/schemata/Struct.md index b78f595f..1e303be2 100644 --- a/docs/schemata/Struct.md +++ b/docs/schemata/Struct.md @@ -1,6 +1,6 @@ --- title: Struct -nav_order: 81 +nav_order: 83 parent: schemata --- diff --git a/docs/schemata/Tuple.md b/docs/schemata/Tuple.md index 73b44304..4768d0c9 100644 --- a/docs/schemata/Tuple.md +++ b/docs/schemata/Tuple.md @@ -1,6 +1,6 @@ --- title: Tuple -nav_order: 82 +nav_order: 84 parent: schemata --- diff --git a/docs/schemata/UUID.md b/docs/schemata/UUID.md index eeb1d59f..b66ebca3 100644 --- a/docs/schemata/UUID.md +++ b/docs/schemata/UUID.md @@ -1,6 +1,6 @@ --- title: UUID -nav_order: 88 +nav_order: 90 parent: schemata --- diff --git a/docs/schemata/Union.md b/docs/schemata/Union.md index e37c4c80..3af67816 100644 --- a/docs/schemata/Union.md +++ b/docs/schemata/Union.md @@ -1,6 +1,6 @@ --- title: Union -nav_order: 83 +nav_order: 85 parent: schemata --- diff --git a/docs/schemata/Unit.md b/docs/schemata/Unit.md index 12408e7e..cdc7919a 100644 --- a/docs/schemata/Unit.md +++ b/docs/schemata/Unit.md @@ -1,6 +1,6 @@ --- title: Unit -nav_order: 84 +nav_order: 86 parent: schemata --- diff --git a/docs/schemata/Unknown.md b/docs/schemata/Unknown.md index c41c159b..5b79324a 100644 --- a/docs/schemata/Unknown.md +++ b/docs/schemata/Unknown.md @@ -1,6 +1,6 @@ --- title: Unknown -nav_order: 85 +nav_order: 87 parent: schemata --- diff --git a/docs/schemata/UnknownArray.md b/docs/schemata/UnknownArray.md index 0696050c..09615068 100644 --- a/docs/schemata/UnknownArray.md +++ b/docs/schemata/UnknownArray.md @@ -1,6 +1,6 @@ --- title: UnknownArray -nav_order: 86 +nav_order: 88 parent: schemata --- diff --git a/docs/schemata/UnknownRecord.md b/docs/schemata/UnknownRecord.md index 3f9e1641..1462bceb 100644 --- a/docs/schemata/UnknownRecord.md +++ b/docs/schemata/UnknownRecord.md @@ -1,6 +1,6 @@ --- title: UnknownRecord -nav_order: 87 +nav_order: 89 parent: schemata --- diff --git a/docs/schemata/index.md b/docs/schemata/index.md index 622dc62e..b98e313e 100644 --- a/docs/schemata/index.md +++ b/docs/schemata/index.md @@ -85,23 +85,23 @@ has_children: true ### String (17) -* Ascii ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Ascii.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Ascii.ts)) (e.g: `DxN%`, `p!mq@`, `~|{{l`) -* Base64 ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Base64.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Base64.ts)) (e.g: `s+E+Z42Xxk/+3/U+li//p96f+l/o`, `u345++//B+711SN6/9ok7++B`, `LgPP/K/g5HfjR+/7+74Gl/2a/qhxp/0mQr==`) -* Base64Url ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Base64Url.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Base64Url.ts)) (e.g: `D---xB-`, `-o1_-z-`, `--_8_Z_d__`) -* BitcoinAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/BitcoinAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/BitcoinAddress.ts)) (e.g: `1QPZ2zALkNmKLAfA9kGLNm9A7X1GGnPn2Qn`, `24LoFGBK3zvQnVdz4JNpCALi4FoWTxtZG8XZxKf`, `bc19h9casw3o260lva263766cep6492hrz9xm2t`) +* Ascii ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Ascii.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Ascii.ts)) (e.g: `:&3Mi]J9`, `>#evxtA}`, `bW|V`) +* Base64 ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Base64.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Base64.ts)) (e.g: `AlN/g/5++o+8//+AWV+B7f5a`, `A//HSD+xW+==`, `+a+9OE5L`) +* Base64Url ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Base64Url.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Base64Url.ts)) (e.g: `47QBIX__`, `-O__D1`, `_G7_-8`) +* BitcoinAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/BitcoinAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/BitcoinAddress.ts)) (e.g: `bc1acs0y8wunv88bcxpwi02y1bwcux799dly8264td`, `2CaKCMnhRSPMY9qzvLFDn8xD8ok23`, `bc1awz0e1lpa6v2827g6bnxy99re2`) * CamelCaseString ([docs](https://jacob-alford.github.io/schemata-ts/schemata/CamelCaseString.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/CamelCaseString.ts)) (e.g: `Camel_case-string` → `camelCaseString`) -* CreditCard ([docs](https://jacob-alford.github.io/schemata-ts/schemata/CreditCard.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/CreditCard.ts)) (e.g: `6529020340876286962`, `378389006333372`, `62835962063734984`) -* EmailAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/EmailAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/EmailAddress.ts)) (e.g: `~&%{+!+*&*.%/=-|+%?}.{-C}o'$z@Mpp3--52.68qx.u6.4Q.nIYH`, `'{/-*{'H^%!.?|}/!'&|.~7!}}/-|+&.8$-&+.r+~?B?=.!$_9_O%*'}?@[87.9.730.63]`, `"࢒￰乃귞᮶"@[91.1.34.410]`) -* EthereumAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/EthereumAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/EthereumAddress.ts)) (e.g: `0xDdE30CF0BDAFf6e92DFb7CFcdfa5Cf2eAF2e6a36`, `0x9F0DCC602AC889beCfBaDF0E08CeA61C3cCC0e7A`, `0x1fB624A1Eb2bA9ab41BA5Ecee8Cb1f0fC00fbCfD`) -* HexColor ([docs](https://jacob-alford.github.io/schemata-ts/schemata/HexColor.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/HexColor.ts)) (e.g: `#0Bf1a2`, `c9DbAacC`, `#cF9eABaF`) -* Hexadecimal ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Hexadecimal.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Hexadecimal.ts)) (e.g: `0XdebB0BA95cFB`, `EA13bcEC8`, `0H2aFC3F1Db1`) -* HslColor ([docs](https://jacob-alford.github.io/schemata-ts/schemata/HslColor.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/HslColor.ts)) (e.g: `hsl(+583turn,+00000000000e963%,00000100e-70%)`, `hsla(.1603641113+000100.000000000000%00093e65523%)`, `hsl(.17e-2342589grad+0000000.8621%0000000000.2e758385%)`) -* Jwt ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Jwt.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Jwt.ts)) (e.g: `--_4___.__`, `____-kHMn-._`, `_2_y281.Y-_-9`) -* LatLong ([docs](https://jacob-alford.github.io/schemata-ts/schemata/LatLong.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/LatLong.ts)) (e.g: `90.000000,180`, `90.00000000,180`, `(90,+99)`) -* NonEmptyString ([docs](https://jacob-alford.github.io/schemata-ts/schemata/NonEmptyString.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/NonEmptyString.ts)) (e.g: `otoD+lleGACeqtri`, `toString`, `piuxku`) -* RGB ([docs](https://jacob-alford.github.io/schemata-ts/schemata/RGB.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/RGB.ts)) (e.g: `rgb(69,240,252)`, `rgba(237,252,250,.26)`, `rgb(225,251,98)`) +* CreditCard ([docs](https://jacob-alford.github.io/schemata-ts/schemata/CreditCard.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/CreditCard.ts)) (e.g: `3528587942168942`, `6286620799069453971`, `62873192077181039`) +* EmailAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/EmailAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/EmailAddress.ts)) (e.g: `..$'E@[2.047.28.734]`, `"뜽쓸輽寉ꠂ䑁⸱꽠ẻ奅鿌�"@L83-BB.QM05C1j.a-.--W2e.XwvnHvmgC`, `=A!%&.~^~%}?^~~=/.?Lq*%|%@[94.1.73.7]`) +* EthereumAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/EthereumAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/EthereumAddress.ts)) (e.g: `0x9EfbBb7ee173F6AcBBACc12b175B6CC9EbF26fd1`, `0xDAe59bA61CeddB33C99e3AEcFA3A0Be0dD62Ce9d`, `0xAa300c1eaf1A8e00ECfdC4BdEBEa8ADcDbBF170C`) +* HexColor ([docs](https://jacob-alford.github.io/schemata-ts/schemata/HexColor.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/HexColor.ts)) (e.g: `aaEADc`, `#03e9af`, `EdC9AE`) +* Hexadecimal ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Hexadecimal.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Hexadecimal.ts)) (e.g: `0h0cDbbfFB6`, `0h4fFEcf118C`, `FD0ecDf1eAcA`) +* HslColor ([docs](https://jacob-alford.github.io/schemata-ts/schemata/HslColor.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/HslColor.ts)) (e.g: `hsla(.09204772e+2912726610,00000000090e-849471712912%,.02752%)`, `hsla(3551856+0000000000100e241%000000000092%/295378%)`, `hsl(+700.654%+00.461675%/4466051.55%)`) +* Jwt ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Jwt.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Jwt.ts)) (e.g: `_.ZAf_-Y_-.-T9eY`, `--.__5.c`, `A._-u_b.-Ebj7t-e--`) +* LatLong ([docs](https://jacob-alford.github.io/schemata-ts/schemata/LatLong.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/LatLong.ts)) (e.g: `(-90,180)`, `(2.2544,-180)`, `(90,+180)`) +* NonEmptyString ([docs](https://jacob-alford.github.io/schemata-ts/schemata/NonEmptyString.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/NonEmptyString.ts)) (e.g: `7lengt==`, `pPZL1RdP`, `b1d90d`) +* RGB ([docs](https://jacob-alford.github.io/schemata-ts/schemata/RGB.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/RGB.ts)) (e.g: `rgba(100%,100%,100%,.1)`, `rgba(100%,70%,100%,0.08)`, `rgba(94%,99%,100%,1.0)`) * String ([docs](https://jacob-alford.github.io/schemata-ts/schemata/String.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/String.ts)) -* UUID ([docs](https://jacob-alford.github.io/schemata-ts/schemata/UUID.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/UUID.ts)) (e.g: `d1b69A90-f2e0-BC61-bD7a-BFeF3d9Ecc8A`, `cb18bBec-Bed7-1BFa-0CcB-DCB330efE7DA`, `CbFd7ddf-FEaf-D0Ba-9b21-abBcEeC1fA5b`) +* UUID ([docs](https://jacob-alford.github.io/schemata-ts/schemata/UUID.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/UUID.ts)) (e.g: `2cc0CE8D-6A8d-Cf39-00E2-bBCdc9032AFe`, `13b20Eee-eE98-D0DF-4Adf-A62AFeBfEA9B`, `3Bf72fDc-BAAc-d4DF-E4F0-0E072fbce5f8`) ### Unit (1) diff --git a/package.json b/package.json index e4bbfa49..9f4cc3e7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "schemata-ts", - "version": "2.1.1", + "version": "2.2.0", "description": "An all-inclusive schema engine featuring schemata inspired by io-ts and validators.js. Written for TypeScript with fp-ts", "homepage": "https://jacob-alford.github.io/schemata-ts/", "repository": { diff --git a/src/schemata/Intersect.ts b/src/schemata/Intersect.ts index 8c99bddb..a5fd642e 100644 --- a/src/schemata/Intersect.ts +++ b/src/schemata/Intersect.ts @@ -5,7 +5,6 @@ import { type Schema } from 'schemata-ts/Schema' /** * An intersection of two struct-derived types. * - * @deprecated Use `Struct({}).intersect()` instead. * @since 1.0.0 * @category Combinators */ From d4fc11e2ef8a2415556c8a0b839e453586fd5be0 Mon Sep 17 00:00:00 2001 From: Jacob Alford Date: Wed, 8 Nov 2023 17:37:32 -0700 Subject: [PATCH 16/16] chore: generate docs --- docs/index.md | 20 ++++++++++---------- docs/schemata/index.md | 30 +++++++++++++++--------------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/docs/index.md b/docs/index.md index 2d91720a..8d861ace 100644 --- a/docs/index.md +++ b/docs/index.md @@ -130,26 +130,26 @@ export const PersonSchema = S.Struct({ ## Schema Transformations -There are three ways to transform a schema in `schemata-ts`: ['combinators'](#schema) which are functions that take schemas as parameters and return new schemas, 'transformers' which are specific to a particular schema, and `Imap` which applies an invariant transformation to the underlying data-type. +There are three ways to transform a schema in `schemata-ts`: ['combinators'](#schema) which are functions that take schemas as parameters and return new schemas, 'transformers' which are specific to particular schemata, and `Imap` which applies an invariant transformation to the underlying data-type. ### Invariant Transformations -All data-types derivable from schemas are invariant functors, aside from `Guard`. This means that if you supply mapping functions `to`, and `from` the new type, you will adjust the `Output` type of that particular data type. Because `Guard` is not invariant, you must supply the resulting `Guard` to the invariant map. The combinator version of this is `Imap`. In version `3.0` which is coming in late 2023/early 2024 it will be possible to `.imap` a schema. +Aside from `Guard`, all data-types derivable from schemas are invariant functors. This means that supplying mapping functions `to` and `from` to `Imap` adjusts the `Output` of that particular data type. Because `Guard` is not invariant, you must supply the resulting `Guard` to the invariant map. The combinator version of this is `Imap`. In version `3.0` (coming late 2023/early 2024) it will be possible to `.imap()` any schema. ### Schema Transformers Schema transformers are classes which extend `SchemaImplementation`, and allow adjustment to the underlying schema parameters after it has been declared in an immutable fashion. This is useful for type-specific methods like `pick` or `omit` for `Struct`. -Here are the current transformers and available methods: +Here are the current transformers and available methods, -- `StructSchema`: `pick`, `omit`, `partial`, `partialOption`, `readonly`, `strict`, `addIndexSignature`, `extend`, `intersect` -- `ArraySchema`: `minLength`, `maxLength`, `nonEmpty` -- `StringSchema`: `brand`, `minLength`, `maxLength`, `errorName` -- `IntSchema`: `brand`, `min`, `max`, `errorName` -- `FloatSchema`: `brand`, `min`, `max`, `errorName` -- `TupleSchema`: `append`, `prepend` +- Struct: `pick`, `omit`, `partial`, `partialOption`, `readonly`, `strict`, `addIndexSignature`, `extend`, `intersect` +- Array: `minLength`, `maxLength`, `nonEmpty` +- String: `brand`, `minLength`, `maxLength`, `errorName` +- Int: `brand`, `min`, `max`, `errorName` +- Float: `brand`, `min`, `max`, `errorName` +- Tuple: `append`, `prepend` -... and more to come! +... with more to come! ### Transformation Example diff --git a/docs/schemata/index.md b/docs/schemata/index.md index b98e313e..1e1737b3 100644 --- a/docs/schemata/index.md +++ b/docs/schemata/index.md @@ -85,23 +85,23 @@ has_children: true ### String (17) -* Ascii ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Ascii.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Ascii.ts)) (e.g: `:&3Mi]J9`, `>#evxtA}`, `bW|V`) -* Base64 ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Base64.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Base64.ts)) (e.g: `AlN/g/5++o+8//+AWV+B7f5a`, `A//HSD+xW+==`, `+a+9OE5L`) -* Base64Url ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Base64Url.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Base64Url.ts)) (e.g: `47QBIX__`, `-O__D1`, `_G7_-8`) -* BitcoinAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/BitcoinAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/BitcoinAddress.ts)) (e.g: `bc1acs0y8wunv88bcxpwi02y1bwcux799dly8264td`, `2CaKCMnhRSPMY9qzvLFDn8xD8ok23`, `bc1awz0e1lpa6v2827g6bnxy99re2`) +* Ascii ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Ascii.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Ascii.ts)) (e.g: `{b;~$D`, `U;o>x2,o`, `sM9n,`) +* Base64 ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Base64.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Base64.ts)) (e.g: `3/+03/MTc4I++h+7973////5/m+F/vi/+/jSuw==`, `Fve2+i04/+/5`, `+++/1714w/++7/Lv`) +* Base64Url ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Base64Url.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Base64Url.ts)) (e.g: `Y_ww-6D_`, `s_r_Xy0_sj`, `-AC--y--`) +* BitcoinAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/BitcoinAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/BitcoinAddress.ts)) (e.g: `bc1c2dsca37vzb3a312xe47h6n3d2z`, `bc1exbc71d4lb8a88ncyecmb1b857l63dyn`, `2iAUJK4ERBid1CPN6zvQeKQSmGFGd`) * CamelCaseString ([docs](https://jacob-alford.github.io/schemata-ts/schemata/CamelCaseString.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/CamelCaseString.ts)) (e.g: `Camel_case-string` → `camelCaseString`) -* CreditCard ([docs](https://jacob-alford.github.io/schemata-ts/schemata/CreditCard.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/CreditCard.ts)) (e.g: `3528587942168942`, `6286620799069453971`, `62873192077181039`) -* EmailAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/EmailAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/EmailAddress.ts)) (e.g: `..$'E@[2.047.28.734]`, `"뜽쓸輽寉ꠂ䑁⸱꽠ẻ奅鿌�"@L83-BB.QM05C1j.a-.--W2e.XwvnHvmgC`, `=A!%&.~^~%}?^~~=/.?Lq*%|%@[94.1.73.7]`) -* EthereumAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/EthereumAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/EthereumAddress.ts)) (e.g: `0x9EfbBb7ee173F6AcBBACc12b175B6CC9EbF26fd1`, `0xDAe59bA61CeddB33C99e3AEcFA3A0Be0dD62Ce9d`, `0xAa300c1eaf1A8e00ECfdC4BdEBEa8ADcDbBF170C`) -* HexColor ([docs](https://jacob-alford.github.io/schemata-ts/schemata/HexColor.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/HexColor.ts)) (e.g: `aaEADc`, `#03e9af`, `EdC9AE`) -* Hexadecimal ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Hexadecimal.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Hexadecimal.ts)) (e.g: `0h0cDbbfFB6`, `0h4fFEcf118C`, `FD0ecDf1eAcA`) -* HslColor ([docs](https://jacob-alford.github.io/schemata-ts/schemata/HslColor.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/HslColor.ts)) (e.g: `hsla(.09204772e+2912726610,00000000090e-849471712912%,.02752%)`, `hsla(3551856+0000000000100e241%000000000092%/295378%)`, `hsl(+700.654%+00.461675%/4466051.55%)`) -* Jwt ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Jwt.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Jwt.ts)) (e.g: `_.ZAf_-Y_-.-T9eY`, `--.__5.c`, `A._-u_b.-Ebj7t-e--`) -* LatLong ([docs](https://jacob-alford.github.io/schemata-ts/schemata/LatLong.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/LatLong.ts)) (e.g: `(-90,180)`, `(2.2544,-180)`, `(90,+180)`) -* NonEmptyString ([docs](https://jacob-alford.github.io/schemata-ts/schemata/NonEmptyString.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/NonEmptyString.ts)) (e.g: `7lengt==`, `pPZL1RdP`, `b1d90d`) -* RGB ([docs](https://jacob-alford.github.io/schemata-ts/schemata/RGB.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/RGB.ts)) (e.g: `rgba(100%,100%,100%,.1)`, `rgba(100%,70%,100%,0.08)`, `rgba(94%,99%,100%,1.0)`) +* CreditCard ([docs](https://jacob-alford.github.io/schemata-ts/schemata/CreditCard.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/CreditCard.ts)) (e.g: `2293037513430698`, `8289225972708943`, `35290351306910219`) +* EmailAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/EmailAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/EmailAddress.ts)) (e.g: `"ࠠ䐵濶柃釕"@.-7.K-ha.-a.yesJOqw--m.Jl0-vgp-yz.qbU`, `"伌卉똰傴釋핑￷"@[976.69.06.091]`, `|@-CH7.OdUhVavBrw`) +* EthereumAddress ([docs](https://jacob-alford.github.io/schemata-ts/schemata/EthereumAddress.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/EthereumAddress.ts)) (e.g: `0xa6CbfBfDaB3bfcbB3abCCfBAeFDeD1bb6205fd9C`, `0x00ef0c969FB6fdAb4c1FC6Efcd2dB1ebDf9baeFc`, `0xCAf3BFFdFc3Fe1DDcAcBDa6f7eaAC9EaD9EBA31e`) +* HexColor ([docs](https://jacob-alford.github.io/schemata-ts/schemata/HexColor.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/HexColor.ts)) (e.g: `C0DEcd`, `dC1f45Da`, `7D91CB`) +* Hexadecimal ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Hexadecimal.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Hexadecimal.ts)) (e.g: `0H3CF0ad`, `B5D8aAfDb`, `2B6ceB`) +* HslColor ([docs](https://jacob-alford.github.io/schemata-ts/schemata/HslColor.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/HslColor.ts)) (e.g: `hsl(662021862513,0000000000.480837%,+000000000100e5%)`, `hsl(98819.9887136e9448688279,000000.0351%,+0100%)`, `hsl(+.5turn+000.4938336%+.5616749%/118716048%)`) +* Jwt ([docs](https://jacob-alford.github.io/schemata-ts/schemata/Jwt.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/Jwt.ts)) (e.g: `33B.8-`, `3l4d.pKS-_k_.-`, `4hP--_.DCW_`) +* LatLong ([docs](https://jacob-alford.github.io/schemata-ts/schemata/LatLong.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/LatLong.ts)) (e.g: `(0,+129)`, `(83.7478188474,-93)`, `90,180.0000`) +* NonEmptyString ([docs](https://jacob-alford.github.io/schemata-ts/schemata/NonEmptyString.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/NonEmptyString.ts)) (e.g: `(%!C0`, `alueEallvalueOf=`, `182967`) +* RGB ([docs](https://jacob-alford.github.io/schemata-ts/schemata/RGB.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/RGB.ts)) (e.g: `rgba(100%,22%,100%,0.184678)`, `rgb(2,209,103)`, `rgba(48%,100%,100%,.26)`) * String ([docs](https://jacob-alford.github.io/schemata-ts/schemata/String.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/String.ts)) -* UUID ([docs](https://jacob-alford.github.io/schemata-ts/schemata/UUID.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/UUID.ts)) (e.g: `2cc0CE8D-6A8d-Cf39-00E2-bBCdc9032AFe`, `13b20Eee-eE98-D0DF-4Adf-A62AFeBfEA9B`, `3Bf72fDc-BAAc-d4DF-E4F0-0E072fbce5f8`) +* UUID ([docs](https://jacob-alford.github.io/schemata-ts/schemata/UUID.html)) ([source](https://github.com/jacob-alford/schemata-ts/tree/main/src/schemata/UUID.ts)) (e.g: `fE9accDB-eeED-d4e0-7EaA-Cda1F0A6b1Ab`, `1F52a15b-FDDa-D3bf-AC0B-Eb89c1cBbaCf`, `82E435EE-be8B-6BCF-5BfE-deB9BE062B8A`) ### Unit (1)