@effect/schema
Advanced tools
Comparing version 0.4.0 to 0.5.0
{ | ||
"name": "@effect/schema", | ||
"version": "0.4.0", | ||
"version": "0.5.0", | ||
"license": "MIT", | ||
@@ -5,0 +5,0 @@ "repository": { |
103
README.md
@@ -21,5 +21,10 @@ <h3 align="center"> | ||
`@effect/schema` allows you to define a `Schema` that describes the structure and data types of a piece of data, and then use that `Schema` to perform various operations such as **parsing** from `unknown`, **decoding**, **encoding**, **verifying** that a value conforms to a given `Schema`. | ||
`@effect/schema` allows you to define a `Schema<I, A>` that describes the structure and data types of a piece of data, and then use that `Schema` to perform various operations such as: | ||
`@effect/schema` also provides a number of other features, including the ability to derive various artifacts such as `Arbitrary`s, `JSONSchema`s, and `Pretty`s from a `Schema`, as well as the ability to customize the library through the use of custom artifact compilers and custom `Schema` combinators. | ||
- parsing from `unknown` | ||
- decoding from `I` to `A` | ||
- encoding from `A` to `I` | ||
- verifying that a value conforms to a given `Schema` | ||
- generating fast-check arbitraries | ||
- pretty printing | ||
@@ -126,3 +131,3 @@ If you're eager to learn how to define your first schema, jump straight to the [**Basic usage**](https://github.com/effect-ts/schema#basic-usage) section! | ||
const result1 = parsePerson(input); | ||
if (S.isSuccess(result1)) { | ||
if (E.isRight(result1)) { | ||
console.log(result1.right); // { name: "Alice", age: 30 } | ||
@@ -133,3 +138,16 @@ } | ||
if (E.isLeft(result2)) { | ||
console.log(result2.left); // [PR.type(..., null)] | ||
console.log(result2.left); | ||
/* | ||
{ | ||
_tag: 'ParseError', | ||
errors: [ | ||
{ | ||
_tag: 'Type', | ||
expected: [Object], | ||
actual: null, | ||
message: [Object] | ||
} | ||
] | ||
} | ||
*/ | ||
} | ||
@@ -153,4 +171,4 @@ ``` | ||
Parsing failed: | ||
error(s) found | ||
└─ key "name" | ||
Error: error(s) found | ||
└─ ["name"] | ||
└─ is missing | ||
@@ -188,6 +206,3 @@ */ | ||
/* | ||
{ | ||
_tag: 'Right', | ||
right: { name: 'Bob', age: 40 } | ||
} | ||
{ _tag: 'Right', right: { name: 'Bob', age: 40 } } | ||
*/ | ||
@@ -224,21 +239,10 @@ ``` | ||
_tag: 'Left', | ||
left: [ | ||
{ | ||
_tag: 'Key', | ||
key: 'age', | ||
errors: [ | ||
{ _tag: 'Type', expected: ..., actual: 'abc' }, | ||
[length]: 1 | ||
] | ||
}, | ||
{ | ||
_tag: 'Key', | ||
key: 'email', | ||
errors: [ | ||
{ _tag: 'Unexpected', actual: 'bob@example.com' }, | ||
[length]: 1 | ||
] | ||
}, | ||
[length]: 2 | ||
] | ||
left: { | ||
_tag: 'ParseError', | ||
errors: [ | ||
{ _tag: 'Key', key: 'email', errors: [ [Object], [length]: 1 ] }, | ||
{ _tag: 'Key', key: 'age', errors: [ [Object], [length]: 1 ] }, | ||
[length]: 2 | ||
] | ||
} | ||
} | ||
@@ -254,3 +258,3 @@ */ | ||
import * as S from "@effect/schema/Schema"; | ||
import { pipe } from "@effect/data/Function"; | ||
import * as E from "@effect/data/Either"; | ||
@@ -266,3 +270,3 @@ // Age is a schema that can parse a string to a number and encode a number to a string | ||
const encoded = S.encodeEither(Person)({ name: "Alice", age: 30 }); | ||
if (S.isSuccess(encoded)) { | ||
if (E.isRight(encoded)) { | ||
console.log(encoded.right); // { name: "Alice", age: "30" } | ||
@@ -291,3 +295,3 @@ } | ||
console.error("Parsing failed:"); | ||
console.error(formatErrors(result.left)); | ||
console.error(formatErrors(result.left.errors)); | ||
} | ||
@@ -297,3 +301,3 @@ /* | ||
error(s) found | ||
└─ key "name" | ||
└─ ["name"] | ||
└─ is missing | ||
@@ -334,3 +338,3 @@ */ | ||
// const assertsPerson: (input: unknown) => asserts input is Person | ||
const assertsPerson: S.ToAsserts<typeof Person> = P.asserts(Person); | ||
const assertsPerson: S.ToAsserts<typeof Person> = S.asserts(Person); | ||
@@ -346,3 +350,3 @@ try { | ||
Error: error(s) found | ||
└─ key "age" | ||
└─ ["age"] | ||
└─ Expected number, actual "30" | ||
@@ -360,2 +364,3 @@ */ | ||
```ts | ||
import { pipe } from "@effect/data/Function"; | ||
import * as S from "@effect/schema/Schema"; | ||
@@ -367,14 +372,23 @@ import * as A from "@effect/schema/Arbitrary"; | ||
name: S.string, | ||
age: S.number, | ||
age: pipe(S.string, S.numberFromString, S.int()) | ||
}); | ||
const PersonArbitrary = A.arbitrary(Person)(fc); | ||
// Arbitrary for the To type | ||
const PersonArbitraryTo = A.to(Person)(fc); | ||
console.log(fc.sample(PersonArbitrary, 2)); | ||
console.log(fc.sample(PersonArbitraryTo, 2)); | ||
/* | ||
[ | ||
{ name: '!U?z/X', age: -2.5223372357846707e-44 }, | ||
{ name: 'valukeypro', age: -1.401298464324817e-45 } | ||
{ name: 'WJh;`Jz', age: 3.4028216409684243e+38 }, | ||
{ name: 'x&~', age: 139480325657985020 } | ||
] | ||
*/ | ||
// Arbitrary for the From type | ||
const PersonArbitraryFrom = A.from(Person)(fc); | ||
console.log(fc.sample(PersonArbitraryFrom, 2)); | ||
/* | ||
[ { name: 'Q}"H@aT', age: ']P$8w' }, { name: '|', age: '"' } ] | ||
*/ | ||
``` | ||
@@ -998,3 +1012,3 @@ | ||
**transform** | ||
### transform | ||
@@ -1030,5 +1044,5 @@ ```ts | ||
The `transformEither` combinator works in a similar way, but allows the transformation function to return a `ParseResult` object, which can either be a success or a failure. | ||
### transformResult | ||
Here's an example of the `transformEither` combinator which converts a `string` into a `boolean`: | ||
The `transformResult` combinator works in a similar way, but allows the transformation function to return a `ParseResult` object, which can either be a success or a failure. | ||
@@ -1050,4 +1064,3 @@ ```ts | ||
// use the transformEither combinator to convert the string schema into the boolean schema | ||
const transformedSchema: S.Schema<string, boolean> = S.transformEither(S.string, S.boolean, decode, encode); | ||
const transformedSchema: S.Schema<string, boolean> = S.transformEffect(S.string, S.boolean, decode, encode); | ||
``` | ||
@@ -1054,0 +1067,0 @@ |
@@ -8,3 +8,2 @@ /** | ||
import type { Either } from "@effect/data/Either"; | ||
import * as E from "@effect/data/Either"; | ||
import type { Option } from "@effect/data/Option"; | ||
@@ -15,3 +14,2 @@ import type { Predicate, Refinement } from "@effect/data/Predicate"; | ||
import type { ParseResult } from "@effect/schema/ParseResult"; | ||
import * as PR from "@effect/schema/ParseResult"; | ||
/** | ||
@@ -389,3 +387,3 @@ * @category model | ||
*/ | ||
export declare const transformEffect: { | ||
export declare const transformResult: { | ||
<I2, A2, A1>(to: Schema<I2, A2>, decode: (a1: A1, options?: ParseOptions) => ParseResult<I2>, encode: (i2: I2, options?: ParseOptions) => ParseResult<A1>): <I1>(self: Schema<I1, A1>) => Schema<I1, A2>; | ||
@@ -396,13 +394,2 @@ <I1, A1, I2, A2>(from: Schema<I1, A1>, to: Schema<I2, A2>, decode: (a1: A1, options?: ParseOptions) => ParseResult<I2>, encode: (i2: I2, options?: ParseOptions) => ParseResult<A1>): Schema<I1, A2>; | ||
Create a new `Schema` by transforming the input and output of an existing `Schema` | ||
using the provided decoding functions. | ||
@category combinators | ||
@since 1.0.0 | ||
*/ | ||
export declare const transformEither: { | ||
<I2, A2, A1>(to: Schema<I2, A2>, decode: (a1: A1, options?: ParseOptions) => E.Either<PR.ParseError, I2>, encode: (i2: I2, options?: ParseOptions) => E.Either<PR.ParseError, A1>): <I1>(self: Schema<I1, A1>) => Schema<I1, A2>; | ||
<I1, A1, I2, A2>(from: Schema<I1, A1>, to: Schema<I2, A2>, decode: (a1: A1, options?: ParseOptions) => E.Either<PR.ParseError, I2>, encode: (i2: I2, options?: ParseOptions) => E.Either<PR.ParseError, A1>): Schema<I1, A2>; | ||
}; | ||
/** | ||
Create a new `Schema` by transforming the input and output of an existing `Schema` | ||
using the provided mapping functions. | ||
@@ -409,0 +396,0 @@ |
@@ -134,3 +134,3 @@ "use strict"; | ||
}); | ||
exports.unknown = exports.uniqueSymbol = exports.union = exports.undefined = exports.tuple = exports.trimmed = exports.trim = exports.transformEither = exports.transformEffect = exports.transform = exports.to = exports.title = exports.templateLiteral = exports.symbol = exports.struct = exports.string = exports.startsWith = exports.reverse = exports.rest = exports.record = exports.readonlySetFromSelf = exports.readonlySet = exports.readonlyMapFromSelf = exports.readonlyMap = exports.positiveBigint = exports.positive = exports.pick = exports.pattern = exports.partial = void 0; | ||
exports.unknown = exports.uniqueSymbol = exports.union = exports.undefined = exports.tuple = exports.trimmed = exports.trim = exports.transformResult = exports.transform = exports.to = exports.title = exports.templateLiteral = exports.symbol = exports.struct = exports.string = exports.startsWith = exports.reverse = exports.rest = exports.record = exports.readonlySetFromSelf = exports.readonlySet = exports.readonlyMapFromSelf = exports.readonlyMap = exports.positiveBigint = exports.positive = exports.pick = exports.pattern = exports.partial = void 0; | ||
Object.defineProperty(exports, "validate", { | ||
@@ -564,14 +564,5 @@ enumerable: true, | ||
*/ | ||
const transformEffect = /*#__PURE__*/(0, _Function.dual)(4, (from, to, decode, encode) => make(AST.createTransform(from.ast, to.ast, decode, encode))); | ||
const transformResult = /*#__PURE__*/(0, _Function.dual)(4, (from, to, decode, encode) => make(AST.createTransform(from.ast, to.ast, decode, encode))); | ||
/** | ||
Create a new `Schema` by transforming the input and output of an existing `Schema` | ||
using the provided decoding functions. | ||
@category combinators | ||
@since 1.0.0 | ||
*/ | ||
exports.transformEffect = transformEffect; | ||
const transformEither = /*#__PURE__*/(0, _Function.dual)(4, (from, to, decode, encode) => make(AST.createTransform(from.ast, to.ast, decode, encode))); | ||
/** | ||
Create a new `Schema` by transforming the input and output of an existing `Schema` | ||
using the provided mapping functions. | ||
@@ -582,4 +573,4 @@ | ||
*/ | ||
exports.transformEither = transformEither; | ||
const transform = /*#__PURE__*/(0, _Function.dual)(4, (from, to, decode, encode) => transformEither(from, to, a => E.right(decode(a)), b => E.right(encode(b)))); | ||
exports.transformResult = transformResult; | ||
const transform = /*#__PURE__*/(0, _Function.dual)(4, (from, to, decode, encode) => transformResult(from, to, a => E.right(decode(a)), b => E.right(encode(b)))); | ||
/** | ||
@@ -994,3 +985,3 @@ * Attaches a property signature with the specified key and value to the schema. | ||
exports.date = date; | ||
const dateFromString = /*#__PURE__*/transformEffect(string, date, s => { | ||
const dateFromString = /*#__PURE__*/transformResult(string, date, s => { | ||
const n = Date.parse(s); | ||
@@ -1287,3 +1278,3 @@ return isNaN(n) ? PR.failure(PR.type(dateFromString.ast, s)) : PR.success(new Date(n)); | ||
const numberFromString = self => { | ||
const schema = transformEffect(self, number, s => { | ||
const schema = transformResult(self, number, s => { | ||
if (s === "NaN") { | ||
@@ -1290,0 +1281,0 @@ return PR.success(NaN); |
@@ -765,3 +765,3 @@ /** | ||
*/ | ||
export const transformEffect: { | ||
export const transformResult: { | ||
<I2, A2, A1>( | ||
@@ -787,43 +787,2 @@ to: Schema<I2, A2>, | ||
Create a new `Schema` by transforming the input and output of an existing `Schema` | ||
using the provided decoding functions. | ||
@category combinators | ||
@since 1.0.0 | ||
*/ | ||
export const transformEither: { | ||
<I2, A2, A1>( | ||
to: Schema<I2, A2>, | ||
decode: ( | ||
a1: A1, | ||
options?: ParseOptions | ||
) => E.Either<PR.ParseError, I2>, | ||
encode: ( | ||
i2: I2, | ||
options?: ParseOptions | ||
) => E.Either<PR.ParseError, A1> | ||
): <I1>(self: Schema<I1, A1>) => Schema<I1, A2> | ||
<I1, A1, I2, A2>( | ||
from: Schema<I1, A1>, | ||
to: Schema<I2, A2>, | ||
decode: ( | ||
a1: A1, | ||
options?: ParseOptions | ||
) => E.Either<PR.ParseError, I2>, | ||
encode: ( | ||
i2: I2, | ||
options?: ParseOptions | ||
) => E.Either<PR.ParseError, A1> | ||
): Schema<I1, A2> | ||
} = dual(4, <I1, A1, I2, A2>( | ||
from: Schema<I1, A1>, | ||
to: Schema<I2, A2>, | ||
decode: ( | ||
a1: A1, | ||
options?: ParseOptions | ||
) => E.Either<PR.ParseError, I2>, | ||
encode: (i2: I2, options?: ParseOptions) => E.Either<PR.ParseError, A1> | ||
): Schema<I1, A2> => make(AST.createTransform(from.ast, to.ast, decode, encode))) | ||
/** | ||
Create a new `Schema` by transforming the input and output of an existing `Schema` | ||
using the provided mapping functions. | ||
@@ -854,3 +813,3 @@ | ||
): Schema<I1, A2> => | ||
transformEither(from, to, (a) => E.right(decode(a)), (b) => E.right(encode(b))) | ||
transformResult(from, to, (a) => E.right(decode(a)), (b) => E.right(encode(b))) | ||
) | ||
@@ -1423,3 +1382,3 @@ | ||
*/ | ||
export const dateFromString: Schema<string, Date> = transformEffect( | ||
export const dateFromString: Schema<string, Date> = transformResult( | ||
string, | ||
@@ -1863,3 +1822,3 @@ date, | ||
export const numberFromString = <I>(self: Schema<I, string>): Schema<I, number> => { | ||
const schema: Schema<I, number> = transformEffect( | ||
const schema: Schema<I, number> = transformResult( | ||
self, | ||
@@ -1866,0 +1825,0 @@ number, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1460
828383
15868