Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@effect/schema

Package Overview
Dependencies
Maintainers
3
Versions
335
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@effect/schema - npm Package Compare versions

Comparing version 0.2.1 to 0.3.0

8

Arbitrary.js

@@ -13,2 +13,3 @@ "use strict";

var I = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/schema/internal/common"));
var _ParseResult = /*#__PURE__*/require("@effect/schema/ParseResult");
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }

@@ -186,10 +187,9 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

case "Refinement":
case "Transform":
{
const from = go(ast.from);
return (0, _Function.pipe)(getHook(ast), O.match(() => fc => from(fc).filter(a => E.isRight(ast.decode(a))), handler => handler(from)));
const to = go(ast.to);
return (0, _Function.pipe)(getHook(ast), O.match(() => fc => to(fc).filter(a => E.isRight((0, _ParseResult.eitherSync)(ast.decode(a)))), handler => handler(to)));
}
case "Transform":
return go(ast.to);
}
});
//# sourceMappingURL=Arbitrary.js.map

@@ -112,2 +112,12 @@ /**

*/
export interface HasTransformation {
readonly hasTransformation: boolean;
}
/**
* @since 1.0.0
*/
export declare const hasTransformation: (ast: AST) => boolean;
/**
* @since 1.0.0
*/
export declare const getAnnotation: <A>(key: PropertyKey) => (annotated: Annotated) => Option<A>;

@@ -118,3 +128,3 @@ /**

*/
export interface Declaration extends Annotated {
export interface Declaration extends Annotated, HasTransformation {
readonly _tag: "Declaration";

@@ -212,2 +222,7 @@ readonly typeParameters: ReadonlyArray<AST>;

/**
* @category guards
* @since 1.0.0
*/
export declare const isNeverKeyword: (ast: AST) => ast is NeverKeyword;
/**
* @category model

@@ -397,3 +412,3 @@ * @since 1.0.0

*/
export interface Tuple extends Annotated {
export interface Tuple extends Annotated, HasTransformation {
readonly _tag: "Tuple";

@@ -431,3 +446,3 @@ readonly elements: ReadonlyArray<Element>;

export interface IndexSignature {
readonly parameter: StringKeyword | SymbolKeyword | TemplateLiteral | Refinement;
readonly parameter: AST;
readonly type: AST;

@@ -439,3 +454,3 @@ readonly isReadonly: boolean;

*/
export declare const createIndexSignature: (parameter: StringKeyword | SymbolKeyword | TemplateLiteral | Refinement, type: AST, isReadonly: boolean) => IndexSignature;
export declare const createIndexSignature: (parameter: AST, type: AST, isReadonly: boolean) => IndexSignature;
/**

@@ -445,3 +460,3 @@ * @category model

*/
export interface TypeLiteral extends Annotated {
export interface TypeLiteral extends Annotated, HasTransformation {
readonly _tag: "TypeLiteral";

@@ -465,3 +480,3 @@ readonly propertySignatures: ReadonlyArray<PropertySignature>;

*/
export interface Union extends Annotated {
export interface Union extends Annotated, HasTransformation {
readonly _tag: "Union";

@@ -484,3 +499,3 @@ readonly types: readonly [AST, AST, ...Array<AST>];

*/
export interface Lazy extends Annotated {
export interface Lazy extends Annotated, HasTransformation {
readonly _tag: "Lazy";

@@ -506,4 +521,5 @@ readonly f: () => AST;

readonly from: AST;
readonly to: AST;
readonly decode: (input: any, options?: ParseOptions) => ParseResult<any>;
readonly isReversed: boolean;
readonly encode: (input: any, options?: ParseOptions) => ParseResult<any>;
}

@@ -514,3 +530,3 @@ /**

*/
export declare const createRefinement: (from: AST, decode: (input: any, options?: ParseOptions) => ParseResult<any>, isReversed: boolean, annotations?: Annotated["annotations"]) => Refinement;
export declare const createRefinement: (from: AST, to: AST, decode: Refinement["decode"], encode: Refinement["encode"], annotations?: Annotated["annotations"]) => Refinement;
/**

@@ -539,3 +555,2 @@ * @category guards

readonly encode: (input: any, options?: ParseOptions) => ParseResult<any>;
readonly isReversed: boolean;
}

@@ -546,3 +561,3 @@ /**

*/
export declare const createTransform: (from: AST, to: AST, decode: Transform["decode"], encode: Transform["encode"], isReversed: boolean, annotations?: Annotated["annotations"]) => Transform;
export declare const createTransform: (from: AST, to: AST, decode: Transform["decode"], encode: Transform["encode"], annotations?: Annotated["annotations"]) => Transform;
/**

@@ -567,2 +582,3 @@ * @category guards

decode: (...typeParameters: ReadonlyArray<AST>) => (input: any, options?: ParseOptions) => ParseResult<any>;
hasTransformation: boolean;
} | {

@@ -672,2 +688,3 @@ annotations: {

isReadonly: boolean;
hasTransformation: boolean;
} | {

@@ -681,2 +698,3 @@ annotations: {

indexSignatures: ReadonlyArray<IndexSignature>;
hasTransformation: boolean;
} | {

@@ -689,2 +707,3 @@ annotations: {

types: readonly [AST, AST, ...Array<AST>];
hasTransformation: boolean;
} | {

@@ -697,2 +716,3 @@ annotations: {

f: () => AST;
hasTransformation: boolean;
} | {

@@ -705,4 +725,5 @@ annotations: {

from: AST;
to: AST;
decode: (input: any, options?: ParseOptions) => ParseResult<any>;
isReversed: boolean;
encode: (input: any, options?: ParseOptions) => ParseResult<any>;
} | {

@@ -718,3 +739,2 @@ annotations: {

encode: (input: any, options?: ParseOptions) => ParseResult<any>;
isReversed: boolean;
};

@@ -734,2 +754,3 @@ /**

decode: (...typeParameters: ReadonlyArray<AST>) => (input: any, options?: ParseOptions) => ParseResult<any>;
hasTransformation: boolean;
} | {

@@ -823,2 +844,3 @@ annotations: {

isReadonly: boolean;
hasTransformation: boolean;
} | {

@@ -831,2 +853,3 @@ annotations: {

indexSignatures: ReadonlyArray<IndexSignature>;
hasTransformation: boolean;
} | {

@@ -838,2 +861,3 @@ annotations: {

types: readonly [AST, AST, ...Array<AST>];
hasTransformation: boolean;
} | {

@@ -845,2 +869,3 @@ annotations: {

f: () => AST;
hasTransformation: boolean;
} | {

@@ -852,4 +877,5 @@ annotations: {

from: AST;
to: AST;
decode: (input: any, options?: ParseOptions) => ParseResult<any>;
isReversed: boolean;
encode: (input: any, options?: ParseOptions) => ParseResult<any>;
} | {

@@ -864,3 +890,2 @@ annotations: {

encode: (input: any, options?: ParseOptions) => ParseResult<any>;
isReversed: boolean;
};

@@ -867,0 +892,0 @@ /**

@@ -6,3 +6,3 @@ "use strict";

});
exports.voidKeyword = exports.unknownKeyword = exports.undefinedKeyword = exports.symbolKeyword = exports.stringKeyword = exports.sortByWeightDesc = exports.setAnnotation = exports.reverse = exports.pick = exports.partial = exports.omit = exports.objectKeyword = exports.numberKeyword = exports.neverKeyword = exports.mergeAnnotations = exports.keyof = exports.isUnknownKeyword = exports.isUniqueSymbol = exports.isUnion = exports.isTypeLiteral = exports.isTuple = exports.isTransform = exports.isTemplateLiteral = exports.isSymbolKeyword = exports.isStringKeyword = exports.isRefinement = exports.isNumberKeyword = exports.isLiteral = exports.isLazy = exports.isDeclaration = exports.isBooleanKeyword = exports.isBigIntKeyword = exports.isAnyKeyword = exports.getTo = exports.getFrom = exports.getCompiler = exports.getAnnotation = exports.createUniqueSymbol = exports.createUnion = exports.createTypeLiteral = exports.createTuple = exports.createTransform = exports.createTemplateLiteral = exports.createRefinement = exports.createRecord = exports.createPropertySignature = exports.createLiteral = exports.createLazy = exports.createIndexSignature = exports.createEnums = exports.createElement = exports.createDeclaration = exports.booleanKeyword = exports.bigIntKeyword = exports.appendRestElement = exports.appendElement = exports.anyKeyword = exports._getWeight = exports._getPropertySignatures = exports._getParameter = exports._getCardinality = exports.TypeAnnotationId = exports.TitleAnnotationId = exports.MessageAnnotationId = exports.JSONSchemaAnnotationId = exports.IdentifierAnnotationId = exports.ExamplesAnnotationId = exports.DocumentationAnnotationId = exports.DescriptionAnnotationId = exports.BrandAnnotationId = void 0;
exports.voidKeyword = exports.unknownKeyword = exports.undefinedKeyword = exports.symbolKeyword = exports.stringKeyword = exports.sortByWeightDesc = exports.setAnnotation = exports.reverse = exports.pick = exports.partial = exports.omit = exports.objectKeyword = exports.numberKeyword = exports.neverKeyword = exports.mergeAnnotations = exports.keyof = exports.isUnknownKeyword = exports.isUniqueSymbol = exports.isUnion = exports.isTypeLiteral = exports.isTuple = exports.isTransform = exports.isTemplateLiteral = exports.isSymbolKeyword = exports.isStringKeyword = exports.isRefinement = exports.isNumberKeyword = exports.isNeverKeyword = exports.isLiteral = exports.isLazy = exports.isDeclaration = exports.isBooleanKeyword = exports.isBigIntKeyword = exports.isAnyKeyword = exports.hasTransformation = exports.getTo = exports.getFrom = exports.getCompiler = exports.getAnnotation = exports.createUniqueSymbol = exports.createUnion = exports.createTypeLiteral = exports.createTuple = exports.createTransform = exports.createTemplateLiteral = exports.createRefinement = exports.createRecord = exports.createPropertySignature = exports.createLiteral = exports.createLazy = exports.createIndexSignature = exports.createEnums = exports.createElement = exports.createDeclaration = exports.booleanKeyword = exports.bigIntKeyword = exports.appendRestElement = exports.appendElement = exports.anyKeyword = exports._getWeight = exports._getPropertySignatures = exports._getParameterKeyof = exports._getCardinality = exports.TypeAnnotationId = exports.TitleAnnotationId = exports.MessageAnnotationId = exports.JSONSchemaAnnotationId = exports.IdentifierAnnotationId = exports.ExamplesAnnotationId = exports.DocumentationAnnotationId = exports.DescriptionAnnotationId = exports.BrandAnnotationId = void 0;
var _Function = /*#__PURE__*/require("@effect/data/Function");

@@ -78,2 +78,7 @@ var Number = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/data/Number"));

exports.DocumentationAnnotationId = DocumentationAnnotationId;
const hasTransformation = ast => isRefinement(ast) || isTransform(ast) || "hasTransformation" in ast && ast.hasTransformation;
/**
* @since 1.0.0
*/
exports.hasTransformation = hasTransformation;
const getAnnotation = key => annotated => Object.prototype.hasOwnProperty.call(annotated.annotations, key) ? O.some(annotated.annotations[key]) : O.none();

@@ -90,3 +95,4 @@ /**

decode,
annotations
annotations,
hasTransformation: hasTransformation(type) || typeParameters.some(hasTransformation)
});

@@ -165,6 +171,12 @@ /**

/**
* @category guards
* @since 1.0.0
*/
exports.neverKeyword = neverKeyword;
const isNeverKeyword = ast => ast._tag === "NeverKeyword";
/**
* @category constructors
* @since 1.0.0
*/
exports.neverKeyword = neverKeyword;
exports.isNeverKeyword = isNeverKeyword;
const unknownKeyword = {

@@ -340,3 +352,4 @@ _tag: "UnknownKeyword",

isReadonly,
annotations
annotations,
hasTransformation: elements.some(e => hasTransformation(e.type)) || O.isSome(rest) && rest.value.some(hasTransformation)
});

@@ -364,7 +377,12 @@ /**

exports.createPropertySignature = createPropertySignature;
const createIndexSignature = (parameter, type, isReadonly) => ({
parameter,
type,
isReadonly
});
const createIndexSignature = (parameter, type, isReadonly) => {
if (isNeverKeyword(_getParameterKeyof(parameter))) {
throw new Error("An index signature parameter type must be 'string', 'symbol', a template literal type or a refinement of the previous types");
}
return {
parameter,
type,
isReadonly
};
};
/**

@@ -379,3 +397,4 @@ * @category constructors

indexSignatures: sortByCardinalityAsc(indexSignatures),
annotations
annotations,
hasTransformation: propertySignatures.some(p => hasTransformation(p.type)) || indexSignatures.some(is => hasTransformation(is.type))
});

@@ -405,3 +424,4 @@ /**

types: sortByWeightDesc(types),
annotations
annotations,
hasTransformation: types.some(hasTransformation)
};

@@ -425,3 +445,4 @@ }

f,
annotations
annotations,
hasTransformation: true
});

@@ -439,7 +460,8 @@ /**

exports.isLazy = isLazy;
const createRefinement = (from, decode, isReversed, annotations = {}) => ({
const createRefinement = (from, to, decode, encode, annotations = {}) => ({
_tag: "Refinement",
from,
to,
decode,
isReversed,
encode,
annotations

@@ -458,9 +480,8 @@ });

exports.isRefinement = isRefinement;
const createTransform = (from, to, decode, encode, isReversed, annotations = {}) => ({
const createTransform = (from, to, decode, encode, annotations = {}) => ({
_tag: "Transform",
from,
to: getTo(to),
to,
decode,
encode,
isReversed,
annotations

@@ -614,3 +635,2 @@ });

case "Refinement":
return partial(ast.from);
case "Transform":

@@ -635,26 +655,28 @@ return partial(ast.to);

const getTo = ast => {
switch (ast._tag) {
case "Declaration":
return createDeclaration(ast.typeParameters.map(getTo), ast.type, ast.decode, ast.annotations);
case "Tuple":
return createTuple(ast.elements.map(e => ({
...e,
type: getTo(e.type)
})), O.map(ast.rest, RA.mapNonEmpty(getTo)), ast.isReadonly, ast.annotations);
case "TypeLiteral":
return createTypeLiteral(ast.propertySignatures.map(p => ({
...p,
type: getTo(p.type)
})), ast.indexSignatures.map(is => ({
...is,
type: getTo(is.type)
})), ast.annotations);
case "Union":
return createUnion(ast.types.map(getTo), ast.annotations);
case "Lazy":
return createLazy(() => getTo(ast.f()), ast.annotations);
case "Refinement":
return createRefinement(getTo(ast.from), ast.decode, false, ast.annotations);
case "Transform":
return getTo(ast.to);
if (hasTransformation(ast)) {
switch (ast._tag) {
case "Declaration":
return createDeclaration(ast.typeParameters.map(getTo), ast.type, ast.decode, ast.annotations);
case "Tuple":
return createTuple(ast.elements.map(e => ({
...e,
type: getTo(e.type)
})), O.map(ast.rest, RA.mapNonEmpty(getTo)), ast.isReadonly, ast.annotations);
case "TypeLiteral":
return createTypeLiteral(ast.propertySignatures.map(p => ({
...p,
type: getTo(p.type)
})), ast.indexSignatures.map(is => ({
...is,
type: getTo(is.type)
})), ast.annotations);
case "Union":
return createUnion(ast.types.map(getTo), ast.annotations);
case "Lazy":
return createLazy(() => getTo(ast.f()), ast.annotations);
case "Refinement":
return createRefinement(ast.to, ast.to, ast.decode, ast.decode, ast.annotations);
case "Transform":
return ast.to;
}
}

@@ -668,25 +690,27 @@ return ast;

const getFrom = ast => {
switch (ast._tag) {
case "Declaration":
return createDeclaration(ast.typeParameters.map(getFrom), ast.type, ast.decode, ast.annotations);
case "Tuple":
return createTuple(ast.elements.map(e => ({
...e,
type: getFrom(e.type)
})), O.map(ast.rest, RA.mapNonEmpty(getFrom)), ast.isReadonly, ast.annotations);
case "TypeLiteral":
return createTypeLiteral(ast.propertySignatures.map(p => ({
...p,
type: getFrom(p.type)
})), ast.indexSignatures.map(is => ({
...is,
type: getFrom(is.type)
})), ast.annotations);
case "Union":
return createUnion(ast.types.map(getFrom), ast.annotations);
case "Lazy":
return createLazy(() => getFrom(ast.f()), ast.annotations);
case "Refinement":
case "Transform":
return getFrom(ast.from);
if (hasTransformation(ast)) {
switch (ast._tag) {
case "Declaration":
return createDeclaration(ast.typeParameters.map(getFrom), ast.type, ast.decode, ast.annotations);
case "Tuple":
return createTuple(ast.elements.map(e => ({
...e,
type: getFrom(e.type)
})), O.map(ast.rest, RA.mapNonEmpty(getFrom)), ast.isReadonly, ast.annotations);
case "TypeLiteral":
return createTypeLiteral(ast.propertySignatures.map(p => ({
...p,
type: getFrom(p.type)
})), ast.indexSignatures.map(is => ({
...is,
type: getFrom(is.type)
})), ast.annotations);
case "Union":
return createUnion(ast.types.map(getFrom), ast.annotations);
case "Lazy":
return createLazy(() => getFrom(ast.f()), ast.annotations);
case "Refinement":
case "Transform":
return getFrom(ast.from);
}
}

@@ -700,26 +724,28 @@ return ast;

const reverse = ast => {
switch (ast._tag) {
case "Declaration":
return createDeclaration(ast.typeParameters.map(reverse), ast.type, ast.decode, ast.annotations);
case "Tuple":
return createTuple(ast.elements.map(e => ({
...e,
type: reverse(e.type)
})), O.map(ast.rest, RA.mapNonEmpty(reverse)), ast.isReadonly, ast.annotations);
case "TypeLiteral":
return createTypeLiteral(ast.propertySignatures.map(p => ({
...p,
type: reverse(p.type)
})), ast.indexSignatures.map(is => ({
...is,
type: reverse(is.type)
})), ast.annotations);
case "Union":
return createUnion(ast.types.map(reverse), ast.annotations);
case "Lazy":
return createLazy(() => reverse(ast.f()), ast.annotations);
case "Refinement":
return createRefinement(ast.from, ast.decode, !ast.isReversed, ast.annotations);
case "Transform":
return createTransform(reverse(ast.from), ast.to, ast.decode, ast.encode, !ast.isReversed);
if (hasTransformation(ast)) {
switch (ast._tag) {
case "Declaration":
return createDeclaration(ast.typeParameters.map(reverse), ast.type, ast.decode, ast.annotations);
case "Tuple":
return createTuple(ast.elements.map(e => ({
...e,
type: reverse(e.type)
})), O.map(ast.rest, RA.mapNonEmpty(reverse)), ast.isReadonly, ast.annotations);
case "TypeLiteral":
return createTypeLiteral(ast.propertySignatures.map(p => ({
...p,
type: reverse(p.type)
})), ast.indexSignatures.map(is => ({
...is,
type: reverse(is.type)
})), ast.annotations);
case "Union":
return createUnion(ast.types.map(reverse), ast.annotations);
case "Lazy":
return createLazy(() => reverse(ast.f()), ast.annotations);
case "Refinement":
return createRefinement(reverse(ast.to), reverse(ast.from), ast.encode, ast.decode, ast.annotations);
case "Transform":
return createTransform(reverse(ast.to), reverse(ast.from), ast.encode, ast.decode);
}
}

@@ -757,3 +783,2 @@ return ast;

case "Refinement":
return _getCardinality(ast.from);
case "Transform":

@@ -783,3 +808,2 @@ return _getCardinality(ast.to);

case "Refinement":
return _getWeight(ast.from);
case "Transform":

@@ -830,4 +854,14 @@ return _getWeight(ast.to);

/** @internal */
const _getParameter = x => isRefinement(x) ? _getParameter(x.from) : x;
exports._getParameter = _getParameter;
const _getParameterKeyof = ast => {
switch (ast._tag) {
case "StringKeyword":
case "SymbolKeyword":
case "TemplateLiteral":
return ast;
case "Refinement":
return _getParameterKeyof(ast.from);
}
return neverKeyword;
};
exports._getParameterKeyof = _getParameterKeyof;
const _keyof = ast => {

@@ -843,3 +877,3 @@ switch (ast._tag) {

case "TypeLiteral":
return ast.propertySignatures.map(p => typeof p.name === "symbol" ? createUniqueSymbol(p.name) : createLiteral(p.name)).concat(ast.indexSignatures.map(is => _getParameter(is.parameter)));
return ast.propertySignatures.map(p => typeof p.name === "symbol" ? createUniqueSymbol(p.name) : createLiteral(p.name)).concat(ast.indexSignatures.map(is => _getParameterKeyof(is.parameter)));
case "Union":

@@ -852,3 +886,2 @@ {

case "Refinement":
return _keyof(ast.from);
case "Transform":

@@ -885,3 +918,2 @@ return _keyof(ast.to);

case "Refinement":
return _getPropertySignatures(ast.from);
case "Transform":

@@ -888,0 +920,0 @@ return _getPropertySignatures(ast.to);

@@ -36,4 +36,6 @@ "use strict";

case "Refinement":
case "Transform":
return getKeysForIndexSignature(input, parameter.from);
}
return [];
};

@@ -40,0 +42,0 @@ // ---------------------------------------------

{
"name": "@effect/schema",
"version": "0.2.1",
"version": "0.3.0",
"license": "MIT",

@@ -10,4 +10,5 @@ "repository": {

"dependencies": {
"@effect/data": "~0.4.1",
"fast-check": "^3.7.0"
"@effect/data": "~0.5.0",
"@effect/io": "^0.10.0",
"fast-check": "^3.7.1"
},

@@ -14,0 +15,0 @@ "publishConfig": {

/**
* @since 1.0.0
*/
import * as O from "@effect/data/Option";
import * as E from "@effect/data/Either";
import type { Option } from "@effect/data/Option";
import type { ParseOptions } from "@effect/schema/AST";
import type { ParseResult } from "@effect/schema/ParseResult";
import * as PR from "@effect/schema/ParseResult";
import type { ParseResult } from "@effect/schema/ParseResult";
import type { Schema, To } from "@effect/schema/Schema";

@@ -14,3 +14,3 @@ /**

*/
export declare const decodeEither: <I, A>(schema: Schema<I, A>) => (input: unknown, options?: ParseOptions) => PR.ParseResult<A>;
export declare const parse: <_, A>(schema: Schema<_, A>) => (i: unknown, options?: ParseOptions) => A;
/**

@@ -20,3 +20,3 @@ * @category decoding

*/
export declare const decodeOption: <I, A>(schema: Schema<I, A>) => (input: unknown, options?: ParseOptions) => O.Option<A>;
export declare const parseOption: <_, A>(schema: Schema<_, A>) => (i: unknown, options?: ParseOptions) => Option<A>;
/**

@@ -26,12 +26,48 @@ * @category decoding

*/
export declare const decode: <I, A>(schema: Schema<I, A>) => (input: unknown, options?: ParseOptions) => A;
export declare const parseEither: <_, A>(schema: Schema<_, A>) => (i: unknown, options?: ParseOptions) => E.Either<PR.ParseError, A>;
/**
* @category decoding
* @since 1.0.0
*/
export declare const parsePromise: <_, A>(schema: Schema<_, A>) => (i: unknown, options?: ParseOptions) => Promise<A>;
/**
* @category decoding
* @since 1.0.0
*/
export declare const parseEffect: <_, A>(schema: Schema<_, A>) => (i: unknown, options?: ParseOptions) => ParseResult<A>;
/**
* @category decoding
* @since 1.0.0
*/
export declare const decode: <I, A>(schema: Schema<I, A>) => (i: I, options?: ParseOptions) => A;
/**
* @category decoding
* @since 1.0.0
*/
export declare const decodeOption: <I, A>(schema: Schema<I, A>) => (i: I, options?: ParseOptions) => Option<A>;
/**
* @category decoding
* @since 1.0.0
*/
export declare const decodeEither: <I, A>(schema: Schema<I, A>) => (i: I, options?: ParseOptions) => E.Either<PR.ParseError, A>;
/**
* @category decoding
* @since 1.0.0
*/
export declare const decodePromise: <I, A>(schema: Schema<I, A>) => (i: I, options?: ParseOptions) => Promise<A>;
/**
* @category decoding
* @since 1.0.0
*/
export declare const decodeEffect: <_, A>(schema: Schema<_, A>) => (i: unknown, options?: ParseOptions | undefined) => ParseResult<A>;
/**
* @category validation
* @since 1.0.0
*/
export declare const is: <I, A>(schema: Schema<I, A>) => (input: unknown, options?: ParseOptions) => input is A;
export declare const validate: <_, A>(schema: Schema<_, A>) => (a: unknown, options?: ParseOptions) => A;
/**
* @category validation
* @since 1.0.0
*/
export type ToAsserts<S extends Schema<any>> = (input: unknown, options?: ParseOptions) => asserts input is To<S>;
export declare const validateOption: <_, A>(schema: Schema<_, A>) => (a: unknown, options?: ParseOptions) => Option<A>;
/**

@@ -41,3 +77,3 @@ * @category validation

*/
export declare const asserts: <I, A>(schema: Schema<I, A>) => (input: unknown, options?: ParseOptions) => asserts input is A;
export declare const validateEither: <_, A>(schema: Schema<_, A>) => (a: unknown, options?: ParseOptions) => E.Either<PR.ParseError, A>;
/**

@@ -47,3 +83,3 @@ * @category validation

*/
export declare const validateEither: <I, A>(schema: Schema<I, A>) => (input: unknown, options?: ParseOptions) => PR.ParseResult<A>;
export declare const validatePromise: <_, A>(schema: Schema<_, A>) => (i: unknown, options?: ParseOptions) => Promise<A>;
/**

@@ -53,3 +89,3 @@ * @category validation

*/
export declare const validateOption: <I, A>(schema: Schema<I, A>) => (input: unknown, options?: ParseOptions) => O.Option<A>;
export declare const validateEffect: <_, A>(schema: Schema<_, A>) => (a: unknown, options?: ParseOptions) => ParseResult<A>;
/**

@@ -59,8 +95,17 @@ * @category validation

*/
export declare const validate: <I, A>(schema: Schema<I, A>) => (input: unknown, options?: ParseOptions) => A;
export declare const is: <_, A>(schema: Schema<_, A>) => (a: unknown) => a is A;
/**
* @since 1.0.0
*/
export type ToAsserts<S extends Schema<any>> = (input: unknown, options?: ParseOptions) => asserts input is To<S>;
/**
* @category validation
* @since 1.0.0
*/
export declare const asserts: <_, A>(schema: Schema<_, A>) => (a: unknown, options?: ParseOptions) => asserts a is A;
/**
* @category encoding
* @since 1.0.0
*/
export declare const encodeEither: <I, A>(schema: Schema<I, A>) => (a: A, options?: ParseOptions) => PR.ParseResult<I>;
export declare const encode: <I, A>(schema: Schema<I, A>) => (a: A, options?: ParseOptions) => I;
/**

@@ -70,3 +115,3 @@ * @category encoding

*/
export declare const encodeOption: <I, A>(schema: Schema<I, A>) => (input: A, options?: ParseOptions) => O.Option<I>;
export declare const encodeOption: <I, A>(schema: Schema<I, A>) => (input: A, options?: ParseOptions) => Option<I>;
/**

@@ -76,3 +121,13 @@ * @category encoding

*/
export declare const encode: <I, A>(schema: Schema<I, A>) => (a: A, options?: ParseOptions) => I;
export declare const encodeEither: <I, A>(schema: Schema<I, A>) => (a: A, options?: ParseOptions) => E.Either<PR.ParseError, I>;
/**
* @category encoding
* @since 1.0.0
*/
export declare const encodePromise: <I, A>(schema: Schema<I, A>) => (a: A, options?: ParseOptions) => Promise<I>;
/**
* @category encoding
* @since 1.0.0
*/
export declare const encodeEffect: <I, A>(schema: Schema<I, A>) => (a: A, options?: ParseOptions) => ParseResult<I>;
//# sourceMappingURL=Parser.d.ts.map

@@ -6,3 +6,3 @@ "use strict";

});
exports.validateOption = exports.validateEither = exports.validate = exports.is = exports.encodeOption = exports.encodeEither = exports.encode = exports.decodeOption = exports.decodeEither = exports.decode = exports.asserts = exports._getSearchTree = exports._getLiterals = void 0;
exports.validatePromise = exports.validateOption = exports.validateEither = exports.validateEffect = exports.validate = exports.parsePromise = exports.parseOption = exports.parseEither = exports.parseEffect = exports.parse = exports.is = exports.encodePromise = exports.encodeOption = exports.encodeEither = exports.encodeEffect = exports.encode = exports.decodePromise = exports.decodeOption = exports.decodeEither = exports.decodeEffect = exports.decode = exports.asserts = exports._getSearchTree = exports._getLiterals = void 0;
var E = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/data/Either"));

@@ -13,2 +13,4 @@ var _Function = /*#__PURE__*/require("@effect/data/Function");

var RA = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/data/ReadonlyArray"));
var _Debug = /*#__PURE__*/require("@effect/io/Debug");
var Effect = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/io/Effect"));
var AST = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/schema/AST"));

@@ -24,16 +26,25 @@ var I = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/schema/internal/common"));

const parse = ast => {
const parse = go(ast);
const get = ast => {
const parser = go(ast);
return (input, options) => {
const t = parse(input, options);
if (PR.isFailure(t)) {
throw new Error((0, _TreeFormatter.formatErrors)(t.left));
const result = parser(input, options);
const resultComputed = PR.eitherSync(result);
if (E.isLeft(resultComputed)) {
throw new Error((0, _TreeFormatter.formatErrors)(resultComputed.left.errors));
}
return t.right;
return resultComputed.right;
};
};
const parseOption = ast => {
const parse = go(ast);
return (input, options) => O.fromEither(parse(input, options));
const getOption = ast => {
const parser = go(ast);
return (input, options) => O.fromEither(PR.eitherSync(parser(input, options)));
};
const getEither = ast => {
const parser = go(ast);
return (input, options) => PR.eitherSync(parser(input, options));
};
const getPromise = ast => {
const parser = go(ast);
return (input, options) => Effect.runPromise(parser(input, options));
};
/**

@@ -43,3 +54,3 @@ * @category decoding

*/
const decodeEither = schema => go(schema.ast);
const parse = schema => get(schema.ast);
/**

@@ -49,4 +60,4 @@ * @category decoding

*/
exports.decodeEither = decodeEither;
const decodeOption = schema => parseOption(schema.ast);
exports.parse = parse;
const parseOption = schema => getOption(schema.ast);
/**

@@ -56,10 +67,52 @@ * @category decoding

*/
exports.parseOption = parseOption;
const parseEither = schema => getEither(schema.ast);
/**
* @category decoding
* @since 1.0.0
*/
exports.parseEither = parseEither;
const parsePromise = schema => getPromise(schema.ast);
/**
* @category decoding
* @since 1.0.0
*/
exports.parsePromise = parsePromise;
const parseEffect = schema => go(schema.ast);
/**
* @category decoding
* @since 1.0.0
*/
exports.parseEffect = parseEffect;
const decode = parse;
/**
* @category decoding
* @since 1.0.0
*/
exports.decode = decode;
const decodeOption = parseOption;
/**
* @category decoding
* @since 1.0.0
*/
exports.decodeOption = decodeOption;
const decode = schema => parse(schema.ast);
const decodeEither = parseEither;
/**
* @category decoding
* @since 1.0.0
*/
exports.decodeEither = decodeEither;
const decodePromise = parsePromise;
/**
* @category decoding
* @since 1.0.0
*/
exports.decodePromise = decodePromise;
const decodeEffect = parseEffect;
/**
* @category validation
* @since 1.0.0
*/
exports.decode = decode;
const is = schema => (input, options) => E.isRight(go(AST.getTo(schema.ast))(input, options));
exports.decodeEffect = decodeEffect;
const validate = schema => get(AST.getTo(schema.ast));
/**

@@ -69,6 +122,4 @@ * @category validation

*/
exports.is = is;
const asserts = schema => (input, options) => {
parse(AST.getTo(schema.ast))(input, options);
};
exports.validate = validate;
const validateOption = schema => getOption(AST.getTo(schema.ast));
/**

@@ -78,4 +129,4 @@ * @category validation

*/
exports.asserts = asserts;
const validateEither = schema => go(AST.getTo(schema.ast));
exports.validateOption = validateOption;
const validateEither = schema => getEither(AST.getTo(schema.ast));
/**

@@ -86,3 +137,3 @@ * @category validation

exports.validateEither = validateEither;
const validateOption = schema => parseOption(AST.getTo(schema.ast));
const validatePromise = schema => getPromise(AST.getTo(schema.ast));
/**

@@ -92,10 +143,30 @@ * @category validation

*/
exports.validateOption = validateOption;
const validate = schema => parse(AST.getTo(schema.ast));
exports.validatePromise = validatePromise;
const validateEffect = schema => go(AST.getTo(schema.ast));
/**
* @category validation
* @since 1.0.0
*/
exports.validateEffect = validateEffect;
const is = schema => {
const getEither = validateEither(schema);
return a => E.isRight(getEither(a));
};
/**
* @category validation
* @since 1.0.0
*/
exports.is = is;
const asserts = schema => {
const get = validate(schema);
return (a, options) => {
get(a, options);
};
};
/**
* @category encoding
* @since 1.0.0
*/
exports.validate = validate;
const encodeEither = schema => go(AST.reverse(schema.ast));
exports.asserts = asserts;
const encode = schema => get(AST.reverse(schema.ast));
/**

@@ -105,4 +176,16 @@ * @category encoding

*/
exports.encode = encode;
const encodeOption = schema => getOption(AST.reverse(schema.ast));
/**
* @category encoding
* @since 1.0.0
*/
exports.encodeOption = encodeOption;
const encodeEither = schema => getEither(AST.reverse(schema.ast));
/**
* @category encoding
* @since 1.0.0
*/
exports.encodeEither = encodeEither;
const encodeOption = schema => parseOption(AST.reverse(schema.ast));
const encodePromise = schema => getPromise(AST.reverse(schema.ast));
/**

@@ -112,6 +195,9 @@ * @category encoding

*/
exports.encodeOption = encodeOption;
const encode = schema => parse(AST.reverse(schema.ast));
exports.encode = encode;
const go = /*#__PURE__*/I.memoize(ast => {
exports.encodePromise = encodePromise;
const encodeEffect = schema => {
const parser = go(AST.reverse(schema.ast));
return (a, options) => parser(a, options);
};
exports.encodeEffect = encodeEffect;
const go = /*#__PURE__*/I.memoize( /*#__PURE__*/(0, _Debug.untracedMethod)(() => ast => {
switch (ast._tag) {

@@ -156,2 +242,6 @@ case "Declaration":

const rest = (0, _Function.pipe)(ast.rest, O.map(RA.mapNonEmpty(go)));
let requiredLen = ast.elements.filter(e => !e.isOptional).length;
if (O.isSome(ast.rest)) {
requiredLen += ast.rest.value.length - 1;
}
return (input, options) => {

@@ -161,6 +251,36 @@ if (!Array.isArray(input)) {

}
const allErrors = options?.allErrors;
const es = [];
let stepKey = 0;
// ---------------------------------------------
// handle missing indexes
// ---------------------------------------------
const len = input.length;
for (let i = len; i <= requiredLen - 1; i++) {
const e = PR.index(i, [PR.missing]);
if (allErrors) {
es.push([stepKey++, e]);
continue;
} else {
return PR.failure(e);
}
}
// ---------------------------------------------
// handle unexpected indexes
// ---------------------------------------------
const isUnexpectedAllowed = options?.isUnexpectedAllowed;
if (!isUnexpectedAllowed && O.isNone(ast.rest)) {
for (let i = ast.elements.length; i <= len - 1; i++) {
const e = PR.index(i, [PR.unexpected(input[i])]);
if (allErrors) {
es.push([stepKey++, e]);
continue;
} else {
return PR.failures(mutableAppend(sortByIndex(es), e));
}
}
}
const output = [];
const es = [];
const allErrors = options?.allErrors;
let i = 0;
const queue = [];
// ---------------------------------------------

@@ -170,28 +290,44 @@ // handle elements

for (; i < elements.length; i++) {
if (input.length < i + 1) {
if (len < i + 1) {
// the input element is missing...
if (!ast.elements[i].isOptional) {
// ...but the element is required
const e = PR.index(i, [PR.missing]);
if (allErrors) {
es.push(e);
continue;
} else {
return PR.failure(e);
}
if (ast.elements[i].isOptional) {
continue;
}
} else {
const parser = elements[i];
const t = parser(input[i], options);
if (PR.isFailure(t)) {
// the input element is present but is not valid
const e = PR.index(i, t.left);
if (allErrors) {
es.push(e);
continue;
} else {
return PR.failures(mutableAppend(es, e));
const te = parser(input[i], options);
const t = PR.either(te);
if (t) {
if (E.isLeft(t)) {
// the input element is present but is not valid
const e = PR.index(i, t.left.errors);
if (allErrors) {
es.push([stepKey++, e]);
continue;
} else {
return PR.failures(mutableAppend(sortByIndex(es), e));
}
}
output.push([stepKey++, t.right]);
} else {
const nk = stepKey++;
const index = i;
queue.push((0, _Debug.untracedMethod)(() => ({
es,
output
}) => Effect.flatMap(Effect.either(te), t => {
if (E.isLeft(t)) {
// the input element is present but is not valid
const e = PR.index(index, t.left.errors);
if (allErrors) {
es.push([nk, e]);
return Effect.unit();
} else {
return PR.failures(mutableAppend(sortByIndex(es), e));
}
}
output.push([nk, t.right]);
return Effect.unit();
})));
}
output.push(t.right);
}

@@ -205,14 +341,37 @@ }

const tail = RA.tailNonEmpty(rest.value);
for (; i < input.length - tail.length; i++) {
const t = head(input[i], options);
if (PR.isFailure(t)) {
const e = PR.index(i, t.left);
if (allErrors) {
es.push(e);
continue;
for (; i < len - tail.length; i++) {
const te = head(input[i], options);
const t = PR.either(te);
if (t) {
if (E.isLeft(t)) {
const e = PR.index(i, t.left.errors);
if (allErrors) {
es.push([stepKey++, e]);
continue;
} else {
return PR.failures(mutableAppend(sortByIndex(es), e));
}
} else {
return PR.failures(mutableAppend(es, e));
output.push([stepKey++, t.right]);
}
} else {
output.push(t.right);
const nk = stepKey++;
const index = i;
queue.push((0, _Debug.untracedMethod)(() => ({
es,
output
}) => Effect.flatMap(Effect.either(te), t => {
if (E.isLeft(t)) {
const e = PR.index(index, t.left.errors);
if (allErrors) {
es.push([nk, e]);
return Effect.unit();
} else {
return PR.failures(mutableAppend(sortByIndex(es), e));
}
} else {
output.push([nk, t.right]);
return Effect.unit();
}
})));
}

@@ -225,33 +384,39 @@ }

i += j;
if (input.length < i + 1) {
// the input element is missing and the element is required, bail out
return PR.failures(mutableAppend(es, PR.index(i, [PR.missing])));
if (len < i + 1) {
continue;
} else {
const t = tail[j](input[i], options);
if (PR.isFailure(t)) {
// the input element is present but is not valid
const e = PR.index(i, t.left);
if (allErrors) {
es.push(e);
continue;
} else {
return PR.failures(mutableAppend(es, e));
const te = tail[j](input[i], options);
const t = PR.either(te);
if (t) {
if (E.isLeft(t)) {
// the input element is present but is not valid
const e = PR.index(i, t.left.errors);
if (allErrors) {
es.push([stepKey++, e]);
continue;
} else {
return PR.failures(mutableAppend(sortByIndex(es), e));
}
}
}
output.push(t.right);
}
}
} else {
// ---------------------------------------------
// handle unexpected indexes
// ---------------------------------------------
const isUnexpectedAllowed = options?.isUnexpectedAllowed;
for (; i < input.length; i++) {
const e = PR.index(i, [PR.unexpected(input[i])]);
if (!isUnexpectedAllowed) {
if (allErrors) {
es.push(e);
continue;
output.push([stepKey++, t.right]);
} else {
return PR.failures(mutableAppend(es, e));
const nk = stepKey++;
const index = i;
queue.push((0, _Debug.untracedMethod)(() => ({
es,
output
}) => Effect.flatMap(Effect.either(te), t => {
if (E.isLeft(t)) {
// the input element is present but is not valid
const e = PR.index(index, t.left.errors);
if (allErrors) {
es.push([nk, e]);
return Effect.unit();
} else {
return PR.failures(mutableAppend(sortByIndex(es), e));
}
}
output.push([nk, t.right]);
return Effect.unit();
})));
}

@@ -264,3 +429,16 @@ }

// ---------------------------------------------
return RA.isNonEmptyReadonlyArray(es) ? PR.failures(es) : PR.success(output);
const computeResult = ({
es,
output
}) => RA.isNonEmptyArray(es) ? PR.failures(sortByIndex(es)) : PR.success(sortByIndex(output));
return queue.length > 0 ? (0, _Debug.untraced)(() => Effect.suspend(() => {
const state = {
es: Array.from(es),
output: Array.from(output)
};
return Effect.flatMap(Effect.forEachDiscard(queue, f => f(state)), () => computeResult(state));
})) : computeResult({
output,
es
});
};

@@ -279,12 +457,11 @@ }

}
const output = {};
const allErrors = options?.allErrors;
const expectedKeys = {};
const es = [];
const allErrors = options?.allErrors;
let stepKey = 0;
// ---------------------------------------------
// handle property signatures
// handle missing keys
// ---------------------------------------------
for (let i = 0; i < propertySignaturesTypes.length; i++) {
const ps = ast.propertySignatures[i];
const parser = propertySignaturesTypes[i];
const name = ps.name;

@@ -296,3 +473,3 @@ expectedKeys[name] = null;

if (allErrors) {
es.push(e);
es.push([stepKey++, e]);
continue;

@@ -303,18 +480,69 @@ } else {

}
} else {
const t = parser(input[name], options);
if (PR.isFailure(t)) {
// the input key is present but is not valid
const e = PR.key(name, t.left);
}
}
// ---------------------------------------------
// handle unexpected keys
// ---------------------------------------------
const isUnexpectedAllowed = options?.isUnexpectedAllowed;
if (!isUnexpectedAllowed && indexSignatures.length === 0) {
for (const key of Reflect.ownKeys(input)) {
if (!Object.prototype.hasOwnProperty.call(expectedKeys, key)) {
const e = PR.key(key, [PR.unexpected(input[key])]);
if (allErrors) {
es.push(e);
es.push([stepKey++, e]);
continue;
} else {
return PR.failures(mutableAppend(es, e));
return PR.failures(mutableAppend(sortByIndex(es), e));
}
}
output[name] = t.right;
}
}
// ---------------------------------------------
// handle property signatures
// ---------------------------------------------
const output = {};
const queue = [];
for (let i = 0; i < propertySignaturesTypes.length; i++) {
const ps = ast.propertySignatures[i];
const parser = propertySignaturesTypes[i];
const name = ps.name;
if (Object.prototype.hasOwnProperty.call(input, name)) {
const te = parser(input[name], options);
const t = PR.either(te);
if (t) {
if (E.isLeft(t)) {
// the input key is present but is not valid
const e = PR.key(name, t.left.errors);
if (allErrors) {
es.push([stepKey++, e]);
continue;
} else {
return PR.failures(mutableAppend(sortByIndex(es), e));
}
}
output[name] = t.right;
} else {
const nk = stepKey++;
const index = name;
queue.push((0, _Debug.untracedMethod)(() => ({
es,
output
}) => Effect.flatMap(Effect.either(te), t => {
if (E.isLeft(t)) {
// the input key is present but is not valid
const e = PR.key(index, t.left.errors);
if (allErrors) {
es.push([nk, e]);
return Effect.unit();
} else {
return PR.failures(mutableAppend(sortByIndex(es), e));
}
}
output[index] = t.right;
return Effect.unit();
})));
}
}
}
// ---------------------------------------------
// handle index signatures

@@ -331,50 +559,59 @@ // ---------------------------------------------

}
const te = parameter(key, options);
// ---------------------------------------------
// handle keys
// ---------------------------------------------
let t = parameter(key, options);
if (PR.isFailure(t)) {
const e = PR.key(key, t.left);
if (allErrors) {
es.push(e);
continue;
} else {
return PR.failures(mutableAppend(es, e));
const t = PR.either(te);
if (t) {
if (E.isLeft(t)) {
const e = PR.key(key, t.left.errors);
if (allErrors) {
es.push([stepKey++, e]);
continue;
} else {
return PR.failures(mutableAppend(sortByIndex(es), e));
}
}
}
// there's no else here because index signature parameters can't have transformations
// ---------------------------------------------
// handle values
// ---------------------------------------------
t = type(input[key], options);
if (PR.isFailure(t)) {
const e = PR.key(key, t.left);
if (allErrors) {
es.push(e);
continue;
const tve = type(input[key], options);
const tv = PR.either(tve);
if (tv) {
if (E.isLeft(tv)) {
const e = PR.key(key, tv.left.errors);
if (allErrors) {
es.push([stepKey++, e]);
continue;
} else {
return PR.failures(mutableAppend(sortByIndex(es), e));
}
} else {
return PR.failures(mutableAppend(es, e));
output[key] = tv.right;
}
} else {
output[key] = t.right;
const nk = stepKey++;
const index = key;
queue.push((0, _Debug.untracedMethod)(() => ({
es,
output
}) => Effect.flatMap(Effect.either(tve), tv => {
if (E.isLeft(tv)) {
const e = PR.key(index, tv.left.errors);
if (allErrors) {
es.push([nk, e]);
return Effect.unit();
} else {
return PR.failures(mutableAppend(sortByIndex(es), e));
}
} else {
output[key] = tv.right;
return Effect.unit();
}
})));
}
}
}
} else {
// ---------------------------------------------
// handle unexpected keys
// ---------------------------------------------
const isUnexpectedAllowed = options?.isUnexpectedAllowed;
for (const key of Reflect.ownKeys(input)) {
if (!Object.prototype.hasOwnProperty.call(expectedKeys, key)) {
const e = PR.key(key, [PR.unexpected(input[key])]);
if (!isUnexpectedAllowed) {
if (allErrors) {
es.push(e);
continue;
} else {
return PR.failures(mutableAppend(es, e));
}
}
}
}
}

@@ -384,3 +621,16 @@ // ---------------------------------------------

// ---------------------------------------------
return RA.isNonEmptyReadonlyArray(es) ? PR.failures(es) : PR.success(output);
const computeResult = ({
es,
output
}) => RA.isNonEmptyArray(es) ? PR.failures(sortByIndex(es)) : PR.success(output);
return queue.length > 0 ? (0, _Debug.untraced)(() => Effect.suspend(() => {
const state = {
es: Array.from(es),
output: Object.assign({}, output)
};
return Effect.flatMap(Effect.forEachDiscard(queue, f => f(state)), () => computeResult(state));
})) : computeResult({
es,
output
});
};

@@ -393,3 +643,2 @@ }

const len = ownKeys.length;
const otherwise = searchTree.otherwise;
const map = new Map();

@@ -401,2 +650,4 @@ for (let i = 0; i < ast.types.length; i++) {

const es = [];
let stepKey = 0;
let candidates = [];
if (len > 0) {

@@ -414,30 +665,52 @@ // if there is at least one key then input must be an object

// retrive the minimal set of candidates for decoding
const bucket = buckets[literal];
for (let i = 0; i < bucket.length; i++) {
const t = map.get(bucket[i])(input, options);
if (PR.isSuccess(t)) {
return t;
} else {
es.push(PR.unionMember(t.left));
}
}
candidates = candidates.concat(buckets[literal]);
} else {
es.push(PR.key(name, [PR.type(searchTree.keys[name].ast, input[name])]));
es.push([stepKey++, PR.key(name, [PR.type(searchTree.keys[name].ast, input[name])])]);
}
} else {
es.push(PR.key(name, [PR.missing]));
es.push([stepKey++, PR.key(name, [PR.missing])]);
}
}
} else {
es.push(PR.type(unknownRecord, input));
es.push([stepKey++, PR.type(unknownRecord, input)]);
}
}
// if none of the schemas with at least one property with a literal value succeeded,
// proceed with those that have no literal at all
for (let i = 0; i < otherwise.length; i++) {
const t = map.get(otherwise[i])(input, options);
if (PR.isSuccess(t)) {
return t;
if (searchTree.otherwise.length > 0) {
candidates = candidates.concat(searchTree.otherwise);
}
const queue = [];
const finalResult = {
ref: undefined
};
for (let i = 0; i < candidates.length; i++) {
const te = map.get(candidates[i])(input, options);
// the members of a union are ordered based on which one should be decoded first,
// therefore if one member has added a task, all subsequent members must
// also add a task to the queue even if they are synchronous
const t = queue.length === 0 ? PR.either(te) : undefined;
if (t) {
if (E.isRight(t)) {
return PR.success(t.right);
} else {
es.push([stepKey++, PR.unionMember(t.left.errors)]);
}
} else {
es.push(PR.unionMember(t.left));
const nk = stepKey++;
queue.push((0, _Debug.untracedMethod)(() => ({
es,
finalResult
}) => Effect.suspend(() => {
if (finalResult.ref) {
return Effect.unit();
} else {
return Effect.flatMap(Effect.either(te), t => {
if (E.isRight(t)) {
finalResult.ref = PR.success(t.right);
} else {
es.push([nk, PR.unionMember(t.left.errors)]);
}
return Effect.unit();
});
}
})));
}

@@ -448,3 +721,24 @@ }

// ---------------------------------------------
return RA.isNonEmptyReadonlyArray(es) ? PR.failures(es) : PR.failure(PR.type(AST.neverKeyword, input));
const computeResult = ({
es
}) => RA.isNonEmptyArray(es) ? PR.failures(sortByIndex(es)) :
// this should never happen
PR.failure(PR.type(AST.neverKeyword, input));
return queue.length > 0 ? (0, _Debug.untraced)(() => Effect.suspend(() => {
const state = {
es: Array.from(es),
finalResult: {
ref: finalResult.ref
}
};
return Effect.flatMap(Effect.forEachDiscard(queue, f => f(state)), () => {
if (state.finalResult.ref) {
return state.finalResult.ref;
}
return computeResult(state);
});
})) : computeResult({
es,
finalResult
});
};

@@ -459,33 +753,10 @@ }

case "Refinement":
{
const from = go(ast.from);
if (ast.isReversed) {
const to = go(AST.getTo(ast.from));
return (a, options) => (0, _Function.pipe)(to(a, options),
// validate input
E.flatMap(a => ast.decode(a, options)),
// refine
E.flatMap(a => from(a, options)) // encode
);
}
return (u, options) => E.flatMap(from(u, options), a => ast.decode(a, options));
}
case "Transform":
{
const from = go(ast.from);
if (ast.isReversed) {
const to = go(ast.to);
return (a, options) => (0, _Function.pipe)(to(a, options),
// validate input
E.flatMap(a => ast.encode(a, options)),
// transform
E.flatMap(a => from(a, options)) // encode
);
}
return (u, options) => E.flatMap(from(u, options), a => ast.decode(a, options));
const to = go(ast.to);
return (i1, options) => PR.flatMap(from(i1, options), a => PR.flatMap(ast.decode(a, options), i2 => to(i2, options)));
}
}
});
}));
const fromRefinement = (ast, refinement) => u => refinement(u) ? PR.success(u) : PR.failure(PR.type(ast, u));

@@ -502,4 +773,5 @@ /** @internal */

const propertySignature = ast.propertySignatures[i];
if (AST.isLiteral(propertySignature.type) && !propertySignature.isOptional) {
out.push([propertySignature.name, propertySignature.type]);
const type = AST.getFrom(propertySignature.type);
if (AST.isLiteral(type) && !propertySignature.isOptional) {
out.push([propertySignature.name, type]);
}

@@ -510,5 +782,4 @@ }

case "Refinement":
case "Transform":
return _getLiterals(ast.from);
case "Transform":
return ast.isReversed ? _getLiterals(ast.to) : _getLiterals(AST.getFrom(ast.from));
}

@@ -569,4 +840,8 @@ return [];

exports._getSearchTree = _getSearchTree;
const unknownArray = /*#__PURE__*/AST.createTuple([], /*#__PURE__*/O.some([AST.unknownKeyword]), true);
const unknownRecord = /*#__PURE__*/AST.createTypeLiteral([], [/*#__PURE__*/AST.createIndexSignature(AST.stringKeyword, AST.unknownKeyword, true), /*#__PURE__*/AST.createIndexSignature(AST.symbolKeyword, AST.unknownKeyword, true)]);
const unknownArray = /*#__PURE__*/AST.createTuple([], /*#__PURE__*/O.some([AST.unknownKeyword]), true, {
[AST.DescriptionAnnotationId]: "a generic array"
});
const unknownRecord = /*#__PURE__*/AST.createTypeLiteral([], [/*#__PURE__*/AST.createIndexSignature(AST.stringKeyword, AST.unknownKeyword, true), /*#__PURE__*/AST.createIndexSignature(AST.symbolKeyword, AST.unknownKeyword, true)], {
[AST.DescriptionAnnotationId]: "a generic object"
});
const mutableAppend = (self, a) => {

@@ -589,2 +864,5 @@ self.push(a);

};
function sortByIndex(es) {
return es.sort(([a], [b]) => a > b ? 1 : a < b ? -1 : 0).map(([_, a]) => a);
}
//# sourceMappingURL=Parser.js.map
/**
* @since 1.0.0
*/
import type { Either, Left, Right } from "@effect/data/Either";
import * as E from "@effect/data/Either";
import * as O from "@effect/data/Option";
import type { NonEmptyReadonlyArray } from "@effect/data/ReadonlyArray";
import * as Effect from "@effect/io/Effect";
import type * as AST from "@effect/schema/AST";

@@ -10,5 +12,17 @@ /**

*/
export type ParseResult<A> = Either<NonEmptyReadonlyArray<ParseError>, A>;
export interface ParseResult<A> extends Effect.Effect<never, ParseError, A> {
}
/**
* `ParseError` is a type that represents the different types of errors that can occur when decoding a value.
* @since 1.0.0
*/
export interface ParseError {
readonly _tag: "ParseError";
readonly errors: NonEmptyReadonlyArray<ParseErrors>;
}
/**
* @since 1.0.0
*/
export declare const parseError: (errors: readonly [ParseErrors, ...ParseErrors[]]) => ParseError;
/**
* `ParseErrors` is a type that represents the different types of errors that can occur when decoding a value.
*

@@ -18,3 +32,3 @@ * @category model

*/
export type ParseError = Type | Index | Key | Missing | Unexpected | UnionMember;
export type ParseErrors = Type | Index | Key | Missing | Unexpected | UnionMember;
/**

@@ -34,2 +48,3 @@ * The `Type` variant of the `ParseError` type represents an error that occurs when the `actual` value is not of the expected type.

readonly actual: unknown;
readonly message: O.Option<string>;
}

@@ -40,3 +55,3 @@ /**

*/
export declare const type: (expected: AST.AST, actual: unknown) => Type;
export declare const type: (expected: AST.AST, actual: unknown, message?: string) => Type;
/**

@@ -54,3 +69,3 @@ * The `Index` decode error indicates that there was an error at a specific index in an array or tuple.

readonly index: number;
readonly errors: NonEmptyReadonlyArray<ParseError>;
readonly errors: NonEmptyReadonlyArray<ParseErrors>;
}

@@ -61,3 +76,3 @@ /**

*/
export declare const index: (index: number, errors: readonly [ParseError, ...ParseError[]]) => Index;
export declare const index: (index: number, errors: readonly [ParseErrors, ...ParseErrors[]]) => Index;
/**

@@ -76,3 +91,3 @@ * The `Key` variant of the `ParseError` type represents an error that occurs when a key in an object is invalid.

readonly key: PropertyKey;
readonly errors: NonEmptyReadonlyArray<ParseError>;
readonly errors: NonEmptyReadonlyArray<ParseErrors>;
}

@@ -83,3 +98,3 @@ /**

*/
export declare const key: (key: PropertyKey, errors: readonly [ParseError, ...ParseError[]]) => Key;
export declare const key: (key: PropertyKey, errors: readonly [ParseErrors, ...ParseErrors[]]) => Key;
/**

@@ -122,3 +137,3 @@ * Error that occurs when a required key or index is missing.

readonly _tag: "UnionMember";
readonly errors: NonEmptyReadonlyArray<ParseError>;
readonly errors: NonEmptyReadonlyArray<ParseErrors>;
}

@@ -129,3 +144,3 @@ /**

*/
export declare const unionMember: (errors: readonly [ParseError, ...ParseError[]]) => UnionMember;
export declare const unionMember: (errors: readonly [ParseErrors, ...ParseErrors[]]) => UnionMember;
/**

@@ -140,3 +155,3 @@ * @category constructors

*/
export declare const failure: (e: ParseError) => ParseResult<never>;
export declare const failure: (e: ParseErrors) => ParseResult<never>;
/**

@@ -146,13 +161,23 @@ * @category constructors

*/
export declare const failures: (es: readonly [ParseError, ...ParseError[]]) => ParseResult<never>;
export declare const failures: (es: readonly [ParseErrors, ...ParseErrors[]]) => ParseResult<never>;
/**
* @category guards
* @category optimisation
* @since 1.0.0
*/
export declare const isSuccess: <A>(self: ParseResult<A>) => self is Right<A>;
export declare const either: <E, A>(self: Effect.Effect<never, E, A>) => E.Either<E, A> | undefined;
/**
* @category guards
* @category optimisation
* @since 1.0.0
*/
export declare const isFailure: <A>(self: ParseResult<A>) => self is Left<NonEmptyReadonlyArray<ParseError>>;
export declare const eitherSync: <E, A>(self: Effect.Effect<never, E, A>) => E.Either<E, A>;
/**
* @category optimisation
* @since 1.0.0
*/
export declare const flatMap: <E, E1, A, B>(self: Effect.Effect<never, E, A>, f: (self: A) => Effect.Effect<never, E1, B>) => Effect.Effect<never, E | E1, B>;
/**
* @category optimisation
* @since 1.0.0
*/
export declare const map: <E, A, B>(self: Effect.Effect<never, E, A>, f: (self: A) => B) => Effect.Effect<never, E, B>;
//# sourceMappingURL=ParseResult.d.ts.map

@@ -6,4 +6,9 @@ "use strict";

});
exports.unionMember = exports.unexpected = exports.type = exports.success = exports.missing = exports.key = exports.isSuccess = exports.isFailure = exports.index = exports.failures = exports.failure = void 0;
exports.unionMember = exports.unexpected = exports.type = exports.success = exports.parseError = exports.missing = exports.map = exports.key = exports.index = exports.flatMap = exports.failures = exports.failure = exports.eitherSync = exports.either = void 0;
var E = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/data/Either"));
var O = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/data/Option"));
var _Cause = /*#__PURE__*/require("@effect/io/Cause");
var Debug = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/io/Debug"));
var Effect = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/io/Effect"));
var Exit = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/io/Exit"));
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }

@@ -16,9 +21,18 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

/**
* @since 1.0.0
*/
const parseError = errors => ({
_tag: "ParseError",
errors
});
/**
* @category constructors
* @since 1.0.0
*/
const type = (expected, actual) => ({
exports.parseError = parseError;
const type = (expected, actual, message) => ({
_tag: "Type",
expected,
actual
actual,
message: O.fromNullable(message)
});

@@ -76,3 +90,3 @@ /**

exports.unionMember = unionMember;
const success = E.right;
const success = a => Exit.succeed(a);
/**

@@ -83,3 +97,3 @@ * @category constructors

exports.success = success;
const failure = e => E.left([e]);
const failure = e => Exit.fail(parseError([e]));
/**

@@ -90,16 +104,78 @@ * @category constructors

exports.failure = failure;
const failures = es => E.left(es);
const failures = es => Exit.fail(parseError(es));
exports.failures = failures;
const untrace = self => {
// TODO: find a way to detect Traced
const s = self;
return s["_tag"] === "Traced" ? s["i0"] : s;
};
/**
* @category guards
* @category optimisation
* @since 1.0.0
*/
exports.failures = failures;
const isSuccess = E.isRight;
const either = self => {
const untraced = untrace(self);
if ((0, Exit.isExit)(untraced)) {
if (untraced._tag === "Success") {
return E.right(untraced.value);
} else {
const failure = (0, _Cause.failureOption)(untraced.cause);
if (failure._tag === "Some") {
return E.left(failure.value);
}
}
}
};
/**
* @category guards
* @category optimisation
* @since 1.0.0
*/
exports.isSuccess = isSuccess;
const isFailure = E.isLeft;
exports.isFailure = isFailure;
exports.either = either;
const eitherSync = self => {
const untraced = untrace(self);
if ((0, Exit.isExit)(untraced)) {
if (untraced._tag === "Success") {
return E.right(untraced.value);
} else {
const failure = (0, _Cause.failureOption)(untraced.cause);
if (failure._tag === "Some") {
return E.left(failure.value);
}
}
}
return Debug.untraced(() => Effect.runSyncEither(self));
};
/**
* @category optimisation
* @since 1.0.0
*/
exports.eitherSync = eitherSync;
const flatMap = /*#__PURE__*/Debug.methodWithTrace((trace, restore) => (self, f) => {
const e = either(self);
if (e) {
if (E.isRight(e)) {
return restore(f)(e.right);
} else {
return Exit.fail(e.left);
}
}
return Effect.flatMap(self, restore(f)).traced(trace);
});
/**
* @category optimisation
* @since 1.0.0
*/
exports.flatMap = flatMap;
const map = /*#__PURE__*/Debug.methodWithTrace((trace, restore) => (self, f) => {
const e = either(self);
if (e) {
if (E.isRight(e)) {
return Exit.succeed(restore(f)(e.right));
} else {
return Exit.fail(e.left);
}
}
return Effect.map(self, restore(f)).traced(trace);
});
exports.map = map;
//# sourceMappingURL=ParseResult.js.map

@@ -978,4 +978,18 @@ <h3 align="center">

To perform these kinds of transformations, the `@effect/schema` library provides the `transform` and `transformEither` combinators.
To perform these kinds of transformations, the `@effect/schema` library provides the `transform` combinator.
**transform**
```ts
<I1, A1, I2, A2>(from: Schema<I1, A1>, to: Schema<I2, A2>, decode: (a1: A1) => I2, encode: (i2: I2) => A1): Schema<I1, A2>
```
```mermaid
flowchart TD
schema1["from: Schema&lt;I1, A1&gt;"]
schema2["to: Schema&lt;I2, A2&gt;"]
schema1--decode: A1 -> I2-->schema2
schema2--encode: I2 -> A1-->schema1
```
The `transform` combinator takes a target schema, a transformation function from the source type to the target type, and a reverse transformation function from the target type back to the source type. It returns a new schema that applies the transformation function to the output of the original schema before returning it. If the original schema fails to decode a value, the transformed schema will also fail.

@@ -986,8 +1000,2 @@

// define a schema for the string type
const stringSchema: S.Schema<string> = S.string;
// define a schema for a tuple with one element of type string
const tupleSchema: S.Schema<[string]> = S.tuple(S.string);
// define a function that converts a string into a tuple with one element of type string

@@ -997,6 +1005,6 @@ const decode = (s: string): [string] => [s];

// define a function that converts a tuple with one element of type string into a string
const encode = ([s]: [string]): string => s;
const encode = ([s]: readonly [string]): string => s;
// use the transform combinator to convert the string schema into the tuple schema
const transformedSchema: S.Schema<string, [string]> = S.transform(stringSchema, tupleSchema, decode, encode);
const transformedSchema: S.Schema<string, readonly [string]> = S.transform(S.string, S.tuple(S.string), decode, encode);
```

@@ -1011,15 +1019,7 @@

```ts
import { pipe } from "@effect/data/Function";
import * as PR from "@effect/schema/ParseResult";
import * as S from "@effect/schema/Schema";
import * as AST from "@effect/schema/AST";
// define a schema for the string type
const stringSchema: S.Schema<string> = S.string;
// define a schema for the boolean type
const booleanSchema: S.Schema<boolean> = S.boolean;
// define a function that converts a string into a boolean
const decode = (s: string): PR.ParseResult<boolean> =>
const decode = (s: string) =>
s === "true"

@@ -1029,17 +1029,9 @@ ? PR.success(true)

? PR.success(false)
: PR.failure(
PR.type(
AST.createUnion([
AST.createLiteral("true"),
AST.createLiteral("false"),
]),
s
)
);
: PR.failure(PR.type(S.union(S.literal('true'), S.literal('false')).ast, s));
// define a function that converts a boolean into a string
const encode = (b: boolean): ParseResult<string> => PR.success(String(b));
const encode = (b: boolean) => PR.success(String(b));
// use the transformEither combinator to convert the string schema into the boolean schema
const transformedSchema: S.Schema<string, boolean> = S.transformEither(stringSchema, booleanSchema, decode, encode);
const transformedSchema: S.Schema<string, boolean> = S.transformEither(S.string, S.boolean, decode, encode);
```

@@ -1139,3 +1131,3 @@

// const schema: S.Schema<string, Date>
const schema = S.dateFromString(S.string);
const schema = S.dateFromString;
const decode = S.decode(schema);

@@ -1142,0 +1134,0 @@

@@ -7,9 +7,10 @@ /**

import * as D from "@effect/data/Data";
import type { Either } from "@effect/data/Either";
import * as E from "@effect/data/Either";
import type { Either } from "@effect/data/Either";
import type { Option } from "@effect/data/Option";
import type { Predicate, Refinement } from "@effect/data/Predicate";
import type { ParseOptions } from "@effect/schema/AST";
import * as AST from "@effect/schema/AST";
import type { ParseOptions } from "@effect/schema/AST";
import type { ParseResult } from "@effect/schema/ParseResult";
import * as PR from "@effect/schema/ParseResult";
/**

@@ -44,2 +45,6 @@ * @category model

export declare const to: <I, A>(schema: Schema<I, A>) => Schema<A, A>;
/**
* @since 1.0.0
*/
export declare const reverse: <I, A>(schema: Schema<I, A>) => Schema<A, I>;
export {

@@ -57,2 +62,6 @@ /**

*/
decodeEffect,
/**
* @since 1.0.0
*/
decodeEither,

@@ -66,2 +75,6 @@ /**

*/
decodePromise,
/**
* @since 1.0.0
*/
encode,

@@ -71,2 +84,6 @@ /**

*/
encodeEffect,
/**
* @since 1.0.0
*/
encodeEither,

@@ -80,2 +97,6 @@ /**

*/
encodePromise,
/**
* @since 1.0.0
*/
is,

@@ -85,2 +106,22 @@ /**

*/
parse,
/**
* @since 1.0.0
*/
parseEffect,
/**
* @since 1.0.0
*/
parseEither,
/**
* @since 1.0.0
*/
parseOption,
/**
* @since 1.0.0
*/
parsePromise,
/**
* @since 1.0.0
*/
validate,

@@ -90,2 +131,6 @@ /**

*/
validateEffect,
/**
* @since 1.0.0
*/
validateEither,

@@ -95,3 +140,7 @@ /**

*/
validateOption } from "@effect/schema/Parser";
validateOption,
/**
* @since 1.0.0
*/
validatePromise } from "@effect/schema/Parser";
export type {

@@ -331,5 +380,16 @@ /**

*/
export declare const transformEffect: {
<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>;
<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: {
<B, A>(to: Schema<any, B>, decode: (input: A, options?: ParseOptions) => ParseResult<B>, encode: (input: B, options?: ParseOptions) => ParseResult<A>): <I>(self: Schema<I, A>) => Schema<I, B>;
<I, A, B>(self: Schema<I, A>, to: Schema<any, B>, decode: (input: A, options?: ParseOptions) => ParseResult<B>, encode: (input: B, options?: ParseOptions) => ParseResult<A>): Schema<I, B>;
<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>;
};

@@ -344,4 +404,4 @@ /**

export declare const transform: {
<B, A>(to: Schema<any, B>, ab: (a: A) => B, ba: (b: B) => A): <I>(self: Schema<I, A>) => Schema<I, B>;
<I, A, B>(self: Schema<I, A>, to: Schema<any, B>, ab: (a: A) => B, ba: (b: B) => A): Schema<I, B>;
<I2, A2, A1>(to: Schema<I2, A2>, decode: (a1: A1) => I2, encode: (i2: I2) => A1): <I1>(self: Schema<I1, A1>) => Schema<I1, A2>;
<I1, A1, I2, A2>(from: Schema<I1, A1>, to: Schema<I2, A2>, decode: (a1: A1) => I2, encode: (i2: I2) => A1): Schema<I1, A2>;
};

@@ -604,3 +664,3 @@ /**

*/
export declare const dateFromString: <I>(self: Schema<I, string>) => Schema<I, Date>;
export declare const dateFromString: Schema<string, Date>;
/**

@@ -610,3 +670,3 @@ * @category constructors

*/
export declare const eitherFromSelf: <IE, E, IA, A>(left: Schema<IE, E>, right: Schema<IA, A>) => Schema<E.Either<IE, IA>, E.Either<E, A>>;
export declare const eitherFromSelf: <IE, E, IA, A>(left: Schema<IE, E>, right: Schema<IA, A>) => Schema<Either<IE, IA>, Either<E, A>>;
/**

@@ -622,3 +682,3 @@ * @category parsers

readonly right: IA;
}, E.Either<E, A>>;
}, Either<E, A>>;
/**

@@ -625,0 +685,0 @@ * @since 1.0.0

@@ -20,2 +20,8 @@ "use strict";

});
Object.defineProperty(exports, "decodeEffect", {
enumerable: true,
get: function () {
return P.decodeEffect;
}
});
Object.defineProperty(exports, "decodeEither", {

@@ -33,2 +39,8 @@ enumerable: true,

});
Object.defineProperty(exports, "decodePromise", {
enumerable: true,
get: function () {
return P.decodePromise;
}
});
exports.element = exports.eitherFromSelf = exports.either = exports.documentation = exports.description = void 0;

@@ -41,2 +53,8 @@ Object.defineProperty(exports, "encode", {

});
Object.defineProperty(exports, "encodeEffect", {
enumerable: true,
get: function () {
return P.encodeEffect;
}
});
Object.defineProperty(exports, "encodeEither", {

@@ -54,2 +72,8 @@ enumerable: true,

});
Object.defineProperty(exports, "encodePromise", {
enumerable: true,
get: function () {
return P.encodePromise;
}
});
exports.extend = exports.examples = exports.enums = exports.endsWith = void 0;

@@ -64,4 +88,35 @@ exports.filter = filter;

});
exports.multipleOf = exports.minLength = exports.minItems = exports.message = exports.maxLength = exports.maxItems = exports.make = exports.literal = exports.lessThanOrEqualToBigint = exports.lessThanOrEqualTo = exports.lessThanBigint = exports.lessThan = exports.length = exports.lazy = exports.keyof = exports.json = exports.itemsCount = void 0;
exports.unknown = exports.uniqueSymbol = exports.union = exports.undefined = exports.tuple = exports.trimmed = exports.trim = exports.transformEither = exports.transform = exports.to = exports.title = exports.templateLiteral = exports.symbol = exports.struct = exports.string = exports.startsWith = exports.rest = exports.record = exports.readonlySetFromSelf = exports.readonlySet = exports.readonlyMapFromSelf = exports.readonlyMap = exports.positiveBigint = exports.positive = exports.pick = exports.pattern = exports.partial = exports.optionsFromOptionals = exports.optionalElement = exports.optional = exports.optionFromSelf = exports.optionFromNullable = exports.option = exports.omit = exports.object = exports.numberFromString = exports.number = exports.nullable = exports.null = exports.nonPositiveBigint = exports.nonPositive = exports.nonNegativeBigint = exports.nonNegative = exports.nonNaN = exports.nonEmptyArray = exports.nonEmpty = exports.never = exports.negativeBigint = exports.negative = void 0;
exports.maxLength = exports.maxItems = exports.make = exports.literal = exports.lessThanOrEqualToBigint = exports.lessThanOrEqualTo = exports.lessThanBigint = exports.lessThan = exports.length = exports.lazy = exports.keyof = exports.json = exports.itemsCount = void 0;
exports.optionsFromOptionals = exports.optionalElement = exports.optional = exports.optionFromSelf = exports.optionFromNullable = exports.option = exports.omit = exports.object = exports.numberFromString = exports.number = exports.nullable = exports.null = exports.nonPositiveBigint = exports.nonPositive = exports.nonNegativeBigint = exports.nonNegative = exports.nonNaN = exports.nonEmptyArray = exports.nonEmpty = exports.never = exports.negativeBigint = exports.negative = exports.multipleOf = exports.minLength = exports.minItems = exports.message = void 0;
Object.defineProperty(exports, "parse", {
enumerable: true,
get: function () {
return P.parse;
}
});
Object.defineProperty(exports, "parseEffect", {
enumerable: true,
get: function () {
return P.parseEffect;
}
});
Object.defineProperty(exports, "parseEither", {
enumerable: true,
get: function () {
return P.parseEither;
}
});
Object.defineProperty(exports, "parseOption", {
enumerable: true,
get: function () {
return P.parseOption;
}
});
Object.defineProperty(exports, "parsePromise", {
enumerable: true,
get: function () {
return P.parsePromise;
}
});
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;
Object.defineProperty(exports, "validate", {

@@ -73,2 +128,8 @@ enumerable: true,

});
Object.defineProperty(exports, "validateEffect", {
enumerable: true,
get: function () {
return P.validateEffect;
}
});
Object.defineProperty(exports, "validateEither", {

@@ -86,2 +147,8 @@ enumerable: true,

});
Object.defineProperty(exports, "validatePromise", {
enumerable: true,
get: function () {
return P.validatePromise;
}
});
exports.void = void 0;

@@ -99,2 +166,4 @@ var B = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/data/Bigint"));

var RA = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/data/ReadonlyArray"));
var _Debug = /*#__PURE__*/require("@effect/io/Debug");
var Effect = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/io/Effect"));
var AST = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/schema/AST"));

@@ -120,4 +189,9 @@ var I = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect/schema/internal/common"));

const to = schema => make(AST.getTo(schema.ast));
/**
* @since 1.0.0
*/
exports.to = to;
const reverse = schema => make(AST.reverse(schema.ast));
/* c8 ignore start */
exports.to = to;
exports.reverse = reverse;
/* c8 ignore end */

@@ -364,13 +438,13 @@ // ---------------------------------------------

const schema = make(ast);
const decode = P.decode(schema);
const decodeOption = P.decodeOption(schema);
const decodeEither = P.decodeEither(schema);
const validate = P.validate(schema);
const validateOption = P.validateOption(schema);
const validateEither = P.validateEither(schema);
const is = P.is(schema);
const out = Object.assign(input => decode(input), {
const out = Object.assign(input => validate(input), {
[_Brand.RefinedConstructorsTypeId]: _Brand.RefinedConstructorsTypeId,
ast,
option: input => decodeOption(input),
either: input => E.mapLeft(decodeEither(input), errors => [{
option: input => validateOption(input),
either: input => E.mapLeft(validateEither(input), e => [{
meta: input,
message: (0, _TreeFormatter.formatErrors)(errors)
message: (0, _TreeFormatter.formatErrors)(e.errors)
}]),

@@ -397,6 +471,6 @@ refine: input => is(input)

const isOverlappingIndexSignatures = (x, y) => x.indexSignatures.some(ix => y.indexSignatures.some(iy => {
const bx = AST._getParameter(ix.parameter);
const by = AST._getParameter(iy.parameter);
const keyofx = AST._getParameterKeyof(ix.parameter);
const keyofy = AST._getParameterKeyof(iy.parameter);
// there cannot be two string index signatures or two symbol index signatures at the same time
return AST.isStringKeyword(bx) && AST.isStringKeyword(by) || AST.isSymbolKeyword(bx) && AST.isSymbolKeyword(by);
return AST.isStringKeyword(keyofx) && AST.isStringKeyword(keyofy) || AST.isSymbolKeyword(keyofx) && AST.isSymbolKeyword(keyofy);
}));

@@ -464,4 +538,5 @@ const intersectUnionMembers = (xs, ys) => {

function filter(predicate, options) {
return from => {
const ast = AST.createRefinement(from.ast, a => predicate(a) ? PR.success(a) : PR.failure(PR.type(ast, a)), false, toAnnotations(options));
return self => {
const decode = a => predicate(a) ? PR.success(a) : PR.failure(PR.type(ast, a));
const ast = AST.createRefinement(self.ast, AST.getTo(self.ast), decode, decode, toAnnotations(options));
return make(ast);

@@ -477,5 +552,14 @@ };

*/
const transformEither = /*#__PURE__*/(0, _Function.dual)(4, (self, to, decode, encode) => make(AST.createTransform(self.ast, to.ast, decode, encode, false)));
const transformEffect = /*#__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, (i, o) => Effect.fromEither(decode(i, o)), (i, o) => Effect.fromEither(encode(i, o)))));
/**
Create a new `Schema` by transforming the input and output of an existing `Schema`
using the provided mapping functions.

@@ -487,3 +571,3 @@

exports.transformEither = transformEither;
const transform = /*#__PURE__*/(0, _Function.dual)(4, (self, to, ab, ba) => transformEither(self, to, a => PR.success(ab(a)), b => PR.success(ba(b))));
const transform = /*#__PURE__*/(0, _Function.dual)(4, (from, to, decode, encode) => transformEffect(from, to, a => PR.success(decode(a)), b => PR.success(encode(b))));
/**

@@ -796,3 +880,3 @@ * Attaches a property signature with the specified key and value to the schema.

exports.nonPositiveBigint = nonPositiveBigint;
const clampBigint = (min, max) => self => transform(self, (0, _Function.pipe)(self, betweenBigint(min, max)), self => B.clamp(self, min, max), self => B.clamp(self, min, max));
const clampBigint = (min, max) => self => transform(self, (0, _Function.pipe)(self, to, betweenBigint(min, max)), self => B.clamp(self, min, max), _Function.identity);
// ---------------------------------------------

@@ -811,7 +895,10 @@ // data/Brand

exports.BrandTypeId = BrandTypeId;
const fromBrand = (constructor, options) => self => (0, _Function.pipe)(self, filter(x => constructor.refine(x), {
typeId: BrandTypeId,
message: a => constructor.either(a).left.map(v => v.message).join(", "),
...options
}));
const fromBrand = (constructor, options) => self => {
const decode = (0, _Debug.untracedMethod)(() => a => Effect.fromEither(E.mapLeft(constructor.either(a), brandErrors => PR.parseError([PR.type(ast, a, brandErrors.map(v => v.message).join(", "))]))));
const ast = AST.createRefinement(self.ast, AST.getTo(self.ast), decode, decode, toAnnotations({
typeId: BrandTypeId,
...options
}));
return make(ast);
};
// ---------------------------------------------

@@ -832,4 +919,4 @@ // data/Chunk

}), item => {
const items = P.decodeEither(array(item));
return (u, options) => !C.isChunk(u) ? PR.failure(PR.type(schema.ast, u)) : E.map(items(C.toReadonlyArray(u), options), C.fromIterable);
const parse = P.parseEffect(array(item));
return (u, options) => !C.isChunk(u) ? PR.failure(PR.type(schema.ast, u)) : PR.map(parse(C.toReadonlyArray(u), options), C.fromIterable);
}, {

@@ -847,3 +934,3 @@ [AST.IdentifierAnnotationId]: "Chunk",

exports.chunkFromSelf = chunkFromSelf;
const chunk = item => transform(array(item), chunkFromSelf(item), C.fromIterable, C.toReadonlyArray);
const chunk = item => transform(array(item), to(chunkFromSelf(item)), C.fromIterable, C.toReadonlyArray);
// ---------------------------------------------

@@ -862,4 +949,4 @@ // data/Data

const schema = declare([item], item, item => {
const decode = P.decodeEither(item);
return (u, options) => !Equal.isEqual(u) ? PR.failure(PR.type(schema.ast, u)) : E.map(decode(u, options), toData);
const parse = P.parseEffect(item);
return (u, options) => !Equal.isEqual(u) ? PR.failure(PR.type(schema.ast, u)) : PR.map(parse(u, options), toData);
}, {

@@ -877,3 +964,3 @@ [AST.IdentifierAnnotationId]: "Data",

exports.dataFromSelf = dataFromSelf;
const data = item => transform(item, dataFromSelf(item), toData, a => Array.isArray(a) ? Array.from(a) : Object.assign({}, a));
const data = item => transform(item, to(dataFromSelf(item)), toData, a => Array.isArray(a) ? Array.from(a) : Object.assign({}, a));
// ---------------------------------------------

@@ -901,9 +988,6 @@ // data/Date

exports.date = date;
const dateFromString = self => {
const schema = transformEither(self, date, s => {
const n = Date.parse(s);
return isNaN(n) ? PR.failure(PR.type(schema.ast, s)) : PR.success(new Date(n));
}, n => PR.success(n.toISOString()));
return schema;
};
const dateFromString = /*#__PURE__*/transformEffect(string, date, s => {
const n = Date.parse(s);
return isNaN(n) ? PR.failure(PR.type(dateFromString.ast, s)) : PR.success(new Date(n));
}, n => PR.success(n.toISOString()));
// ---------------------------------------------

@@ -928,5 +1012,5 @@ // data/Either

const schema = declare([left, right], eitherInline(left, right), (left, right) => {
const decodeLeft = P.decodeEither(left);
const decodeRight = P.decodeEither(right);
return (u, options) => !E.isEither(u) ? PR.failure(PR.type(schema.ast, u)) : E.isLeft(u) ? E.map(decodeLeft(u.left, options), E.left) : E.map(decodeRight(u.right, options), E.right);
const parseLeft = P.parseEffect(left);
const parseRight = P.parseEffect(right);
return (u, options) => !E.isEither(u) ? PR.failure(PR.type(schema.ast, u)) : E.isLeft(u) ? PR.map(parseLeft(u.left, options), E.left) : PR.map(parseRight(u.right, options), E.right);
}, {

@@ -944,3 +1028,3 @@ [AST.IdentifierAnnotationId]: "Either",

exports.eitherFromSelf = eitherFromSelf;
const either = (left, right) => transform(eitherInline(left, right), eitherFromSelf(left, right), a => a._tag === "Left" ? E.left(a.left) : E.right(a.right), E.match(left => ({
const either = (left, right) => transform(eitherInline(left, right), to(eitherFromSelf(left, right)), a => a._tag === "Left" ? E.left(a.left) : E.right(a.right), E.match(left => ({
_tag: "Left",

@@ -1188,3 +1272,3 @@ left

exports.nonPositive = nonPositive;
const clamp = (min, max) => self => transform(self, (0, _Function.pipe)(self, between(min, max)), self => N.clamp(self, min, max), self => N.clamp(self, min, max));
const clamp = (min, max) => self => transform(self, (0, _Function.pipe)(self, to, between(min, max)), self => N.clamp(self, min, max), _Function.identity);
/**

@@ -1200,3 +1284,3 @@ Transforms a `string` into a `number` by parsing the string using `parseFloat`.

const numberFromString = self => {
const schema = transformEither(self, number, s => {
const schema = transformEffect(self, number, s => {
if (s === "NaN") {

@@ -1258,4 +1342,4 @@ return PR.success(NaN);

const schema = declare([value], optionInline(value), value => {
const decodeValue = P.decodeEither(value);
return (u, options) => !O.isOption(u) ? PR.failure(PR.type(schema.ast, u)) : O.isNone(u) ? PR.success(O.none()) : E.map(decodeValue(u.value, options), O.some);
const parse = P.parseEffect(value);
return (u, options) => !O.isOption(u) ? PR.failure(PR.type(schema.ast, u)) : O.isNone(u) ? PR.success(O.none()) : PR.map(parse(u.value, options), O.some);
}, {

@@ -1273,3 +1357,3 @@ [AST.IdentifierAnnotationId]: "Option",

exports.optionFromSelf = optionFromSelf;
const option = value => transform(optionInline(value), optionFromSelf(value), a => a._tag === "None" ? O.none() : O.some(a.value), O.match(() => ({
const option = value => transform(optionInline(value), to(optionFromSelf(value)), a => a._tag === "None" ? O.none() : O.some(a.value), O.match(() => ({
_tag: "None"

@@ -1285,3 +1369,3 @@ }), value => ({

exports.option = option;
const optionFromNullable = value => transform(union(_undefined, _null, value), optionFromSelf(value), O.fromNullable, O.getOrNull);
const optionFromNullable = value => transform(union(_undefined, _null, value), to(optionFromSelf(value)), O.fromNullable, O.getOrNull);
/**

@@ -1318,3 +1402,3 @@ * @category parsers

return PR.success(out);
}, false);
});
return make(out);

@@ -1397,4 +1481,4 @@ }

}), (key, value) => {
const items = P.decodeEither(array(tuple(key, value)));
return (u, options) => !isMap(u) ? PR.failure(PR.type(schema.ast, u)) : E.map(items(Array.from(u.entries()), options), as => new Map(as));
const parse = P.parseEffect(array(tuple(key, value)));
return (u, options) => !isMap(u) ? PR.failure(PR.type(schema.ast, u)) : PR.map(parse(Array.from(u.entries()), options), as => new Map(as));
}, {

@@ -1412,3 +1496,3 @@ [AST.IdentifierAnnotationId]: "ReadonlyMap",

exports.readonlyMapFromSelf = readonlyMapFromSelf;
const readonlyMap = (key, value) => transform(array(tuple(key, value)), readonlyMapFromSelf(key, value), as => new Map(as), map => Array.from(map.entries()));
const readonlyMap = (key, value) => transform(array(tuple(key, value)), to(readonlyMapFromSelf(key, value)), as => new Map(as), map => Array.from(map.entries()));
// ---------------------------------------------

@@ -1429,4 +1513,4 @@ // data/ReadonlySet

}), item => {
const items = P.decodeEither(array(item));
return (u, options) => !isSet(u) ? PR.failure(PR.type(schema.ast, u)) : E.map(items(Array.from(u.values()), options), as => new Set(as));
const parse = P.parseEffect(array(item));
return (u, options) => !isSet(u) ? PR.failure(PR.type(schema.ast, u)) : PR.map(parse(Array.from(u.values()), options), as => new Set(as));
}, {

@@ -1444,3 +1528,3 @@ [AST.IdentifierAnnotationId]: "ReadonlySet",

exports.readonlySetFromSelf = readonlySetFromSelf;
const readonlySet = item => transform(array(item), readonlySetFromSelf(item), as => new Set(as), set => Array.from(set));
const readonlySet = item => transform(array(item), to(readonlySetFromSelf(item)), as => new Set(as), set => Array.from(set));
// ---------------------------------------------

@@ -1604,3 +1688,3 @@ // data/String

exports.includes = includes;
const trim = self => transform(self, (0, _Function.pipe)(self, trimmed()), s => s.trim(), s => s.trim());
const trim = self => transform(self, (0, _Function.pipe)(to(self), trimmed()), s => s.trim(), _Function.identity);
/**

@@ -1607,0 +1691,0 @@ * @since 1.0.0

@@ -11,2 +11,3 @@ /**

import * as I from "@effect/schema/internal/common"
import { eitherSync } from "@effect/schema/ParseResult"
import type { Schema } from "@effect/schema/Schema"

@@ -205,15 +206,14 @@ import type * as FastCheck from "fast-check"

}
case "Refinement": {
const from = go(ast.from)
case "Refinement":
case "Transform": {
const to = go(ast.to)
return pipe(
getHook(ast),
O.match(
() => (fc) => from(fc).filter((a) => E.isRight(ast.decode(a))),
(handler) => handler(from)
() => (fc) => to(fc).filter((a) => E.isRight(eitherSync(ast.decode(a)))),
(handler) => handler(to)
)
)
}
case "Transform":
return go(ast.to)
}
})

@@ -174,2 +174,17 @@ /**

*/
export interface HasTransformation {
readonly hasTransformation: boolean
}
/**
* @since 1.0.0
*/
export const hasTransformation = (ast: AST): boolean =>
isRefinement(ast) || isTransform(ast) || (
"hasTransformation" in ast && ast.hasTransformation
)
/**
* @since 1.0.0
*/
export const getAnnotation = <A>(key: PropertyKey) =>

@@ -185,3 +200,3 @@ (annotated: Annotated): O.Option<A> =>

*/
export interface Declaration extends Annotated {
export interface Declaration extends Annotated, HasTransformation {
readonly _tag: "Declaration"

@@ -206,3 +221,10 @@ readonly typeParameters: ReadonlyArray<AST>

annotations: Annotated["annotations"] = {}
): Declaration => ({ _tag: "Declaration", typeParameters, type, decode, annotations })
): Declaration => ({
_tag: "Declaration",
typeParameters,
type,
decode,
annotations,
hasTransformation: hasTransformation(type) || typeParameters.some(hasTransformation)
})

@@ -325,2 +347,8 @@ /**

/**
* @category guards
* @since 1.0.0
*/
export const isNeverKeyword = (ast: AST): ast is NeverKeyword => ast._tag === "NeverKeyword"
/**
* @category model

@@ -593,3 +621,3 @@ * @since 1.0.0

*/
export interface Tuple extends Annotated {
export interface Tuple extends Annotated, HasTransformation {
readonly _tag: "Tuple"

@@ -615,3 +643,5 @@ readonly elements: ReadonlyArray<Element>

isReadonly,
annotations
annotations,
hasTransformation: elements.some((e) => hasTransformation(e.type)) ||
(O.isSome(rest) && rest.value.some(hasTransformation))
})

@@ -650,3 +680,3 @@

export interface IndexSignature {
readonly parameter: StringKeyword | SymbolKeyword | TemplateLiteral | Refinement
readonly parameter: AST
readonly type: AST

@@ -660,6 +690,13 @@ readonly isReadonly: boolean

export const createIndexSignature = (
parameter: StringKeyword | SymbolKeyword | TemplateLiteral | Refinement,
parameter: AST,
type: AST,
isReadonly: boolean
): IndexSignature => ({ parameter, type, isReadonly })
): IndexSignature => {
if (isNeverKeyword(_getParameterKeyof(parameter))) {
throw new Error(
"An index signature parameter type must be 'string', 'symbol', a template literal type or a refinement of the previous types"
)
}
return ({ parameter, type, isReadonly })
}

@@ -670,3 +707,3 @@ /**

*/
export interface TypeLiteral extends Annotated {
export interface TypeLiteral extends Annotated, HasTransformation {
readonly _tag: "TypeLiteral"

@@ -689,3 +726,5 @@ readonly propertySignatures: ReadonlyArray<PropertySignature>

indexSignatures: sortByCardinalityAsc(indexSignatures),
annotations
annotations,
hasTransformation: propertySignatures.some((p) => hasTransformation(p.type)) ||
indexSignatures.some((is) => hasTransformation(is.type))
})

@@ -703,3 +742,3 @@

*/
export interface Union extends Annotated {
export interface Union extends Annotated, HasTransformation {
readonly _tag: "Union"

@@ -724,3 +763,8 @@ readonly types: readonly [AST, AST, ...Array<AST>]

default: {
return { _tag: "Union", types: sortByWeightDesc(types) as any, annotations }
return {
_tag: "Union",
types: sortByWeightDesc(types) as any,
annotations,
hasTransformation: types.some(hasTransformation)
}
}

@@ -740,3 +784,3 @@ }

*/
export interface Lazy extends Annotated {
export interface Lazy extends Annotated, HasTransformation {
readonly _tag: "Lazy"

@@ -753,3 +797,8 @@ readonly f: () => AST

annotations: Annotated["annotations"] = {}
): Lazy => ({ _tag: "Lazy", f, annotations })
): Lazy => ({
_tag: "Lazy",
f,
annotations,
hasTransformation: true
})

@@ -769,4 +818,5 @@ /**

readonly from: AST
readonly to: AST
readonly decode: (input: any, options?: ParseOptions) => ParseResult<any>
readonly isReversed: boolean
readonly encode: (input: any, options?: ParseOptions) => ParseResult<any>
}

@@ -780,6 +830,7 @@

from: AST,
decode: (input: any, options?: ParseOptions) => ParseResult<any>,
isReversed: boolean,
to: AST,
decode: Refinement["decode"],
encode: Refinement["encode"],
annotations: Annotated["annotations"] = {}
): Refinement => ({ _tag: "Refinement", from, decode, isReversed, annotations })
): Refinement => ({ _tag: "Refinement", from, to, decode, encode, annotations })

@@ -811,3 +862,2 @@ /**

readonly encode: (input: any, options?: ParseOptions) => ParseResult<any>
readonly isReversed: boolean
}

@@ -824,13 +874,4 @@

encode: Transform["encode"],
isReversed: boolean,
annotations: Annotated["annotations"] = {}
): Transform => ({
_tag: "Transform",
from,
to: getTo(to),
decode,
encode,
isReversed,
annotations
})
): Transform => ({ _tag: "Transform", from, to, decode, encode, annotations })

@@ -1001,3 +1042,2 @@ /**

case "Refinement":
return partial(ast.from)
case "Transform":

@@ -1038,26 +1078,33 @@ return partial(ast.to)

export const getTo = (ast: AST): AST => {
switch (ast._tag) {
case "Declaration":
return createDeclaration(ast.typeParameters.map(getTo), ast.type, ast.decode, ast.annotations)
case "Tuple":
return createTuple(
ast.elements.map((e) => ({ ...e, type: getTo(e.type) })),
O.map(ast.rest, RA.mapNonEmpty(getTo)),
ast.isReadonly,
ast.annotations
)
case "TypeLiteral":
return createTypeLiteral(
ast.propertySignatures.map((p) => ({ ...p, type: getTo(p.type) })),
ast.indexSignatures.map((is) => ({ ...is, type: getTo(is.type) })),
ast.annotations
)
case "Union":
return createUnion(ast.types.map(getTo), ast.annotations)
case "Lazy":
return createLazy(() => getTo(ast.f()), ast.annotations)
case "Refinement":
return createRefinement(getTo(ast.from), ast.decode, false, ast.annotations)
case "Transform":
return getTo(ast.to)
if (hasTransformation(ast)) {
switch (ast._tag) {
case "Declaration":
return createDeclaration(
ast.typeParameters.map(getTo),
ast.type,
ast.decode,
ast.annotations
)
case "Tuple":
return createTuple(
ast.elements.map((e) => ({ ...e, type: getTo(e.type) })),
O.map(ast.rest, RA.mapNonEmpty(getTo)),
ast.isReadonly,
ast.annotations
)
case "TypeLiteral":
return createTypeLiteral(
ast.propertySignatures.map((p) => ({ ...p, type: getTo(p.type) })),
ast.indexSignatures.map((is) => ({ ...is, type: getTo(is.type) })),
ast.annotations
)
case "Union":
return createUnion(ast.types.map(getTo), ast.annotations)
case "Lazy":
return createLazy(() => getTo(ast.f()), ast.annotations)
case "Refinement":
return createRefinement(ast.to, ast.to, ast.decode, ast.decode, ast.annotations)
case "Transform":
return ast.to
}
}

@@ -1071,30 +1118,32 @@ return ast

export const getFrom = (ast: AST): AST => {
switch (ast._tag) {
case "Declaration":
return createDeclaration(
ast.typeParameters.map(getFrom),
ast.type,
ast.decode,
ast.annotations
)
case "Tuple":
return createTuple(
ast.elements.map((e) => ({ ...e, type: getFrom(e.type) })),
O.map(ast.rest, RA.mapNonEmpty(getFrom)),
ast.isReadonly,
ast.annotations
)
case "TypeLiteral":
return createTypeLiteral(
ast.propertySignatures.map((p) => ({ ...p, type: getFrom(p.type) })),
ast.indexSignatures.map((is) => ({ ...is, type: getFrom(is.type) })),
ast.annotations
)
case "Union":
return createUnion(ast.types.map(getFrom), ast.annotations)
case "Lazy":
return createLazy(() => getFrom(ast.f()), ast.annotations)
case "Refinement":
case "Transform":
return getFrom(ast.from)
if (hasTransformation(ast)) {
switch (ast._tag) {
case "Declaration":
return createDeclaration(
ast.typeParameters.map(getFrom),
ast.type,
ast.decode,
ast.annotations
)
case "Tuple":
return createTuple(
ast.elements.map((e) => ({ ...e, type: getFrom(e.type) })),
O.map(ast.rest, RA.mapNonEmpty(getFrom)),
ast.isReadonly,
ast.annotations
)
case "TypeLiteral":
return createTypeLiteral(
ast.propertySignatures.map((p) => ({ ...p, type: getFrom(p.type) })),
ast.indexSignatures.map((is) => ({ ...is, type: getFrom(is.type) })),
ast.annotations
)
case "Union":
return createUnion(ast.types.map(getFrom), ast.annotations)
case "Lazy":
return createLazy(() => getFrom(ast.f()), ast.annotations)
case "Refinement":
case "Transform":
return getFrom(ast.from)
}
}

@@ -1108,31 +1157,39 @@ return ast

export const reverse = (ast: AST): AST => {
switch (ast._tag) {
case "Declaration":
return createDeclaration(
ast.typeParameters.map(reverse),
ast.type,
ast.decode,
ast.annotations
)
case "Tuple":
return createTuple(
ast.elements.map((e) => ({ ...e, type: reverse(e.type) })),
O.map(ast.rest, RA.mapNonEmpty(reverse)),
ast.isReadonly,
ast.annotations
)
case "TypeLiteral":
return createTypeLiteral(
ast.propertySignatures.map((p) => ({ ...p, type: reverse(p.type) })),
ast.indexSignatures.map((is) => ({ ...is, type: reverse(is.type) })),
ast.annotations
)
case "Union":
return createUnion(ast.types.map(reverse), ast.annotations)
case "Lazy":
return createLazy(() => reverse(ast.f()), ast.annotations)
case "Refinement":
return createRefinement(ast.from, ast.decode, !ast.isReversed, ast.annotations)
case "Transform":
return createTransform(reverse(ast.from), ast.to, ast.decode, ast.encode, !ast.isReversed)
if (hasTransformation(ast)) {
switch (ast._tag) {
case "Declaration":
return createDeclaration(
ast.typeParameters.map(reverse),
ast.type,
ast.decode,
ast.annotations
)
case "Tuple":
return createTuple(
ast.elements.map((e) => ({ ...e, type: reverse(e.type) })),
O.map(ast.rest, RA.mapNonEmpty(reverse)),
ast.isReadonly,
ast.annotations
)
case "TypeLiteral":
return createTypeLiteral(
ast.propertySignatures.map((p) => ({ ...p, type: reverse(p.type) })),
ast.indexSignatures.map((is) => ({ ...is, type: reverse(is.type) })),
ast.annotations
)
case "Union":
return createUnion(ast.types.map(reverse), ast.annotations)
case "Lazy":
return createLazy(() => reverse(ast.f()), ast.annotations)
case "Refinement":
return createRefinement(
reverse(ast.to),
reverse(ast.from),
ast.encode,
ast.decode,
ast.annotations
)
case "Transform":
return createTransform(reverse(ast.to), reverse(ast.from), ast.encode, ast.decode)
}
}

@@ -1171,3 +1228,2 @@ return ast

case "Refinement":
return _getCardinality(ast.from)
case "Transform":

@@ -1198,3 +1254,2 @@ return _getCardinality(ast.to)

case "Refinement":
return _getWeight(ast.from)
case "Transform":

@@ -1249,6 +1304,15 @@ return _getWeight(ast.to)

/** @internal */
export const _getParameter = (
x: IndexSignature["parameter"]
): StringKeyword | SymbolKeyword | TemplateLiteral =>
isRefinement(x) ? _getParameter(x.from as any) : x
export const _getParameterKeyof = (
ast: AST
): StringKeyword | SymbolKeyword | TemplateLiteral | NeverKeyword => {
switch (ast._tag) {
case "StringKeyword":
case "SymbolKeyword":
case "TemplateLiteral":
return ast
case "Refinement":
return _getParameterKeyof(ast.from)
}
return neverKeyword
}

@@ -1267,3 +1331,3 @@ const _keyof = (ast: AST): ReadonlyArray<AST> => {

typeof p.name === "symbol" ? createUniqueSymbol(p.name) : createLiteral(p.name)
).concat(ast.indexSignatures.map((is) => _getParameter(is.parameter)))
).concat(ast.indexSignatures.map((is) => _getParameterKeyof(is.parameter)))
case "Union": {

@@ -1277,3 +1341,2 @@ return _getPropertySignatures(ast).map((p): AST =>

case "Refinement":
return _keyof(ast.from)
case "Transform":

@@ -1323,3 +1386,2 @@ return _keyof(ast.to)

case "Refinement":
return _getPropertySignatures(ast.from)
case "Transform":

@@ -1326,0 +1388,0 @@ return _getPropertySignatures(ast.to)

@@ -28,3 +28,3 @@ /**

input: { readonly [x: PropertyKey]: unknown },
parameter: AST.IndexSignature["parameter"]
parameter: AST.AST
): ReadonlyArray<string> | ReadonlyArray<symbol> => {

@@ -38,4 +38,6 @@ switch (parameter._tag) {

case "Refinement":
return getKeysForIndexSignature(input, parameter.from as any)
case "Transform":
return getKeysForIndexSignature(input, parameter.from)
}
return []
}

@@ -42,0 +44,0 @@

@@ -7,32 +7,45 @@ /**

import { pipe } from "@effect/data/Function"
import type { Option } from "@effect/data/Option"
import * as O from "@effect/data/Option"
import type { Option } from "@effect/data/Option"
import * as P from "@effect/data/Predicate"
import type { NonEmptyReadonlyArray } from "@effect/data/ReadonlyArray"
import * as RA from "@effect/data/ReadonlyArray"
import type { NonEmptyReadonlyArray } from "@effect/data/ReadonlyArray"
import { untraced, untracedMethod } from "@effect/io/Debug"
import * as Effect from "@effect/io/Effect"
import type { ParseOptions } from "@effect/schema/AST"
import * as AST from "@effect/schema/AST"
import type { ParseOptions } from "@effect/schema/AST"
import * as I from "@effect/schema/internal/common"
import type { ParseResult } from "@effect/schema/ParseResult"
import * as PR from "@effect/schema/ParseResult"
import type { ParseResult } from "@effect/schema/ParseResult"
import type { Schema, To } from "@effect/schema/Schema"
import { formatErrors } from "@effect/schema/TreeFormatter"
const parse = (ast: AST.AST) => {
const parse = go(ast)
const get = (ast: AST.AST) => {
const parser = go(ast)
return (input: unknown, options?: ParseOptions) => {
const t = parse(input, options)
if (PR.isFailure(t)) {
throw new Error(formatErrors(t.left))
const result = parser(input, options)
const resultComputed = PR.eitherSync(result)
if (E.isLeft(resultComputed)) {
throw new Error(formatErrors(resultComputed.left.errors))
}
return t.right
return resultComputed.right
}
}
const parseOption = (ast: AST.AST) => {
const parse = go(ast)
return (input: unknown, options?: ParseOptions): Option<any> =>
O.fromEither(parse(input, options))
const getOption = (ast: AST.AST) => {
const parser = go(ast)
return (input: unknown, options?: ParseOptions) =>
O.fromEither(PR.eitherSync(parser(input, options)))
}
const getEither = (ast: AST.AST) => {
const parser = go(ast)
return (input: unknown, options?: ParseOptions) => PR.eitherSync(parser(input, options))
}
const getPromise = (ast: AST.AST) => {
const parser = go(ast)
return (input: unknown, options?: ParseOptions) => Effect.runPromise(parser(input, options))
}
/**

@@ -42,5 +55,50 @@ * @category decoding

*/
export const decodeEither = <I, A>(
export const parse = <_, A>(schema: Schema<_, A>): (i: unknown, options?: ParseOptions) => A =>
get(schema.ast)
/**
* @category decoding
* @since 1.0.0
*/
export const parseOption = <_, A>(
schema: Schema<_, A>
): (i: unknown, options?: ParseOptions) => Option<A> => getOption(schema.ast)
/**
* @category decoding
* @since 1.0.0
*/
export const parseEither = <_, A>(
schema: Schema<_, A>
): (i: unknown, options?: ParseOptions) => E.Either<PR.ParseError, A> => getEither(schema.ast)
/**
* @category decoding
* @since 1.0.0
*/
export const parsePromise = <_, A>(
schema: Schema<_, A>
): (i: unknown, options?: ParseOptions) => Promise<A> => getPromise(schema.ast)
/**
* @category decoding
* @since 1.0.0
*/
export const parseEffect = <_, A>(
schema: Schema<_, A>
): (i: unknown, options?: ParseOptions) => PR.ParseResult<A> => go(schema.ast)
/**
* @category decoding
* @since 1.0.0
*/
export const decode: <I, A>(schema: Schema<I, A>) => (i: I, options?: ParseOptions) => A = parse
/**
* @category decoding
* @since 1.0.0
*/
export const decodeOption: <I, A>(
schema: Schema<I, A>
): (input: unknown, options?: ParseOptions) => ParseResult<A> => go(schema.ast)
) => (i: I, options?: ParseOptions) => Option<A> = parseOption

@@ -51,5 +109,5 @@ /**

*/
export const decodeOption = <I, A>(
export const decodeEither: <I, A>(
schema: Schema<I, A>
): (input: unknown, options?: ParseOptions) => Option<A> => parseOption(schema.ast)
) => (i: I, options?: ParseOptions) => E.Either<PR.ParseError, A> = parseEither

@@ -60,20 +118,29 @@ /**

*/
export const decode = <I, A>(schema: Schema<I, A>): (input: unknown, options?: ParseOptions) => A =>
parse(schema.ast)
export const decodePromise: <I, A>(
schema: Schema<I, A>
) => (i: I, options?: ParseOptions) => Promise<A> = parsePromise
/**
* @category decoding
* @since 1.0.0
*/
export const decodeEffect: <_, A>(
schema: Schema<_, A>
) => (i: unknown, options?: ParseOptions | undefined) => ParseResult<A> = parseEffect
/**
* @category validation
* @since 1.0.0
*/
export const is = <I, A>(schema: Schema<I, A>) =>
(input: unknown, options?: ParseOptions): input is A =>
E.isRight(go(AST.getTo(schema.ast))(input, options))
export const validate = <_, A>(
schema: Schema<_, A>
): (a: unknown, options?: ParseOptions) => A => get(AST.getTo(schema.ast))
/**
* @category validation
* @since 1.0.0
*/
export type ToAsserts<S extends Schema<any>> = (
input: unknown,
options?: ParseOptions
) => asserts input is To<S>
export const validateOption = <_, A>(
schema: Schema<_, A>
): (a: unknown, options?: ParseOptions) => Option<A> => getOption(AST.getTo(schema.ast))

@@ -84,6 +151,6 @@ /**

*/
export const asserts = <I, A>(schema: Schema<I, A>) =>
(input: unknown, options?: ParseOptions): asserts input is A => {
parse(AST.getTo(schema.ast))(input, options)
}
export const validateEither = <_, A>(
schema: Schema<_, A>
): (a: unknown, options?: ParseOptions) => E.Either<PR.ParseError, A> =>
getEither(AST.getTo(schema.ast))

@@ -94,5 +161,5 @@ /**

*/
export const validateEither = <I, A>(
schema: Schema<I, A>
): (input: unknown, options?: ParseOptions) => ParseResult<A> => go(AST.getTo(schema.ast))
export const validatePromise = <_, A>(
schema: Schema<_, A>
): (i: unknown, options?: ParseOptions) => Promise<A> => getPromise(AST.getTo(schema.ast))

@@ -103,5 +170,5 @@ /**

*/
export const validateOption = <I, A>(
schema: Schema<I, A>
): (input: unknown, options?: ParseOptions) => Option<A> => parseOption(AST.getTo(schema.ast))
export const validateEffect = <_, A>(
schema: Schema<_, A>
): (a: unknown, options?: ParseOptions) => PR.ParseResult<A> => go(AST.getTo(schema.ast))

@@ -112,5 +179,40 @@ /**

*/
export const validate = <I, A>(
export const is = <_, A>(schema: Schema<_, A>) => {
const getEither = validateEither(schema)
return (a: unknown): a is A => E.isRight(getEither(a))
}
/**
* @since 1.0.0
*/
export type ToAsserts<S extends Schema<any>> = (
input: unknown,
options?: ParseOptions
) => asserts input is To<S>
/**
* @category validation
* @since 1.0.0
*/
export const asserts = <_, A>(schema: Schema<_, A>) => {
const get = validate(schema)
return (a: unknown, options?: ParseOptions): asserts a is A => {
get(a, options)
}
}
/**
* @category encoding
* @since 1.0.0
*/
export const encode = <I, A>(schema: Schema<I, A>): (a: A, options?: ParseOptions) => I =>
get(AST.reverse(schema.ast))
/**
* @category encoding
* @since 1.0.0
*/
export const encodeOption = <I, A>(
schema: Schema<I, A>
): (input: unknown, options?: ParseOptions) => A => parse(AST.getTo(schema.ast))
): (input: A, options?: ParseOptions) => Option<I> => getOption(AST.reverse(schema.ast))

@@ -123,3 +225,4 @@ /**

schema: Schema<I, A>
): (a: A, options?: ParseOptions) => ParseResult<I> => go(AST.reverse(schema.ast))
): (a: A, options?: ParseOptions) => E.Either<PR.ParseError, I> =>
getEither(AST.reverse(schema.ast))

@@ -130,5 +233,5 @@ /**

*/
export const encodeOption = <I, A>(
export const encodePromise = <I, A>(
schema: Schema<I, A>
): (input: A, options?: ParseOptions) => Option<I> => parseOption(AST.reverse(schema.ast))
): (a: A, options?: ParseOptions) => Promise<I> => getPromise(AST.reverse(schema.ast))

@@ -139,131 +242,76 @@ /**

*/
export const encode = <I, A>(schema: Schema<I, A>): (a: A, options?: ParseOptions) => I =>
parse(AST.reverse(schema.ast))
export const encodeEffect = <I, A>(
schema: Schema<I, A>
) => {
const parser = go(AST.reverse(schema.ast))
return (a: A, options?: ParseOptions): PR.ParseResult<I> => parser(a, options)
}
interface Parser {
(input: unknown, options?: ParseOptions): ParseResult<any>
interface Parser<I, A> {
(i: I, options?: ParseOptions): ParseResult<A>
}
const go = I.memoize((ast: AST.AST): Parser => {
switch (ast._tag) {
case "Declaration":
return ast.decode(...ast.typeParameters)
case "Literal":
return fromRefinement(ast, (u): u is typeof ast.literal => u === ast.literal)
case "UniqueSymbol":
return fromRefinement(ast, (u): u is typeof ast.symbol => u === ast.symbol)
case "UndefinedKeyword":
return fromRefinement(ast, P.isUndefined)
case "VoidKeyword":
return fromRefinement(ast, P.isUndefined)
case "NeverKeyword":
return fromRefinement(ast, P.isNever)
case "UnknownKeyword":
case "AnyKeyword":
return PR.success
case "StringKeyword":
return fromRefinement(ast, P.isString)
case "NumberKeyword":
return fromRefinement(ast, P.isNumber)
case "BooleanKeyword":
return fromRefinement(ast, P.isBoolean)
case "BigIntKeyword":
return fromRefinement(ast, P.isBigint)
case "SymbolKeyword":
return fromRefinement(ast, P.isSymbol)
case "ObjectKeyword":
return fromRefinement(ast, P.isObject)
case "Enums":
return fromRefinement(ast, (u): u is any => ast.enums.some(([_, value]) => value === u))
case "TemplateLiteral": {
const regex = getTemplateLiteralRegex(ast)
return fromRefinement(ast, (u): u is any => P.isString(u) && regex.test(u))
}
case "Tuple": {
const elements = ast.elements.map((e) => go(e.type))
const rest = pipe(ast.rest, O.map(RA.mapNonEmpty(go)))
return (input: unknown, options) => {
if (!Array.isArray(input)) {
return PR.failure(PR.type(unknownArray, input))
const go = I.memoize(untracedMethod(() =>
(ast: AST.AST): Parser<any, any> => {
switch (ast._tag) {
case "Declaration":
return ast.decode(...ast.typeParameters)
case "Literal":
return fromRefinement(ast, (u): u is typeof ast.literal => u === ast.literal)
case "UniqueSymbol":
return fromRefinement(ast, (u): u is typeof ast.symbol => u === ast.symbol)
case "UndefinedKeyword":
return fromRefinement(ast, P.isUndefined)
case "VoidKeyword":
return fromRefinement(ast, P.isUndefined)
case "NeverKeyword":
return fromRefinement(ast, P.isNever)
case "UnknownKeyword":
case "AnyKeyword":
return PR.success
case "StringKeyword":
return fromRefinement(ast, P.isString)
case "NumberKeyword":
return fromRefinement(ast, P.isNumber)
case "BooleanKeyword":
return fromRefinement(ast, P.isBoolean)
case "BigIntKeyword":
return fromRefinement(ast, P.isBigint)
case "SymbolKeyword":
return fromRefinement(ast, P.isSymbol)
case "ObjectKeyword":
return fromRefinement(ast, P.isObject)
case "Enums":
return fromRefinement(ast, (u): u is any => ast.enums.some(([_, value]) => value === u))
case "TemplateLiteral": {
const regex = getTemplateLiteralRegex(ast)
return fromRefinement(ast, (u): u is any => P.isString(u) && regex.test(u))
}
case "Tuple": {
const elements = ast.elements.map((e) => go(e.type))
const rest = pipe(ast.rest, O.map(RA.mapNonEmpty(go)))
let requiredLen = ast.elements.filter((e) => !e.isOptional).length
if (O.isSome(ast.rest)) {
requiredLen += ast.rest.value.length - 1
}
const output: Array<any> = []
const es: Array<PR.ParseError> = []
const allErrors = options?.allErrors
let i = 0
// ---------------------------------------------
// handle elements
// ---------------------------------------------
for (; i < elements.length; i++) {
if (input.length < i + 1) {
// the input element is missing...
if (!ast.elements[i].isOptional) {
// ...but the element is required
const e = PR.index(i, [PR.missing])
if (allErrors) {
es.push(e)
continue
} else {
return PR.failure(e)
}
}
} else {
const parser = elements[i]
const t = parser(input[i], options)
if (PR.isFailure(t)) {
// the input element is present but is not valid
const e = PR.index(i, t.left)
if (allErrors) {
es.push(e)
continue
} else {
return PR.failures(mutableAppend(es, e))
}
}
output.push(t.right)
return (input: unknown, options) => {
if (!Array.isArray(input)) {
return PR.failure(PR.type(unknownArray, input))
}
}
// ---------------------------------------------
// handle rest element
// ---------------------------------------------
if (O.isSome(rest)) {
const head = RA.headNonEmpty(rest.value)
const tail = RA.tailNonEmpty(rest.value)
for (; i < input.length - tail.length; i++) {
const t = head(input[i], options)
if (PR.isFailure(t)) {
const e = PR.index(i, t.left)
if (allErrors) {
es.push(e)
continue
} else {
return PR.failures(mutableAppend(es, e))
}
} else {
output.push(t.right)
}
}
const allErrors = options?.allErrors
const es: Array<[number, PR.ParseErrors]> = []
let stepKey = 0
// ---------------------------------------------
// handle post rest elements
// handle missing indexes
// ---------------------------------------------
for (let j = 0; j < tail.length; j++) {
i += j
if (input.length < i + 1) {
// the input element is missing and the element is required, bail out
return PR.failures(mutableAppend(es, PR.index(i, [PR.missing])))
const len = input.length
for (let i = len; i <= requiredLen - 1; i++) {
const e = PR.index(i, [PR.missing])
if (allErrors) {
es.push([stepKey++, e])
continue
} else {
const t = tail[j](input[i], options)
if (PR.isFailure(t)) {
// the input element is present but is not valid
const e = PR.index(i, t.left)
if (allErrors) {
es.push(e)
continue
} else {
return PR.failures(mutableAppend(es, e))
}
}
output.push(t.right)
return PR.failure(e)
}
}
} else {
// ---------------------------------------------

@@ -273,116 +321,224 @@ // handle unexpected indexes

const isUnexpectedAllowed = options?.isUnexpectedAllowed
for (; i < input.length; i++) {
const e = PR.index(i, [PR.unexpected(input[i])])
if (!isUnexpectedAllowed) {
if (!isUnexpectedAllowed && O.isNone(ast.rest)) {
for (let i = ast.elements.length; i <= len - 1; i++) {
const e = PR.index(i, [PR.unexpected(input[i])])
if (allErrors) {
es.push(e)
es.push([stepKey++, e])
continue
} else {
return PR.failures(mutableAppend(es, e))
return PR.failures(mutableAppend(sortByIndex(es), e))
}
}
}
}
// ---------------------------------------------
// compute output
// ---------------------------------------------
return RA.isNonEmptyReadonlyArray(es) ?
PR.failures(es) :
PR.success(output)
}
}
case "TypeLiteral": {
if (ast.propertySignatures.length === 0 && ast.indexSignatures.length === 0) {
return fromRefinement(ast, P.isNotNullable)
}
const propertySignaturesTypes = ast.propertySignatures.map((f) => go(f.type))
const indexSignatures = ast.indexSignatures.map((is) =>
[go(is.parameter), go(is.type)] as const
)
return (input: unknown, options) => {
if (!P.isRecord(input)) {
return PR.failure(PR.type(unknownRecord, input))
}
const output: any = {}
const expectedKeys: any = {}
const es: Array<PR.ParseError> = []
const allErrors = options?.allErrors
// ---------------------------------------------
// handle property signatures
// ---------------------------------------------
for (let i = 0; i < propertySignaturesTypes.length; i++) {
const ps = ast.propertySignatures[i]
const parser = propertySignaturesTypes[i]
const name = ps.name
expectedKeys[name] = null
if (!Object.prototype.hasOwnProperty.call(input, name)) {
if (!ps.isOptional) {
const e = PR.key(name, [PR.missing])
if (allErrors) {
es.push(e)
const output: Array<[number, any]> = []
let i = 0
type State = {
es: typeof es
output: typeof output
}
const queue: Array<(_: State) => PR.ParseResult<void>> = []
// ---------------------------------------------
// handle elements
// ---------------------------------------------
for (; i < elements.length; i++) {
if (len < i + 1) {
// the input element is missing...
if (ast.elements[i].isOptional) {
continue
}
} else {
const parser = elements[i]
const te = parser(input[i], options)
const t = PR.either(te)
if (t) {
if (E.isLeft(t)) {
// the input element is present but is not valid
const e = PR.index(i, t.left.errors)
if (allErrors) {
es.push([stepKey++, e])
continue
} else {
return PR.failures(mutableAppend(sortByIndex(es), e))
}
}
output.push([stepKey++, t.right])
} else {
return PR.failure(e)
const nk = stepKey++
const index = i
queue.push(
untracedMethod(() =>
({ es, output }: State) =>
Effect.flatMap(Effect.either(te), (t) => {
if (E.isLeft(t)) {
// the input element is present but is not valid
const e = PR.index(index, t.left.errors)
if (allErrors) {
es.push([nk, e])
return Effect.unit()
} else {
return PR.failures(mutableAppend(sortByIndex(es), e))
}
}
output.push([nk, t.right])
return Effect.unit()
})
)
)
}
}
} else {
const t = parser(input[name], options)
if (PR.isFailure(t)) {
// the input key is present but is not valid
const e = PR.key(name, t.left)
if (allErrors) {
es.push(e)
}
// ---------------------------------------------
// handle rest element
// ---------------------------------------------
if (O.isSome(rest)) {
const head = RA.headNonEmpty(rest.value)
const tail = RA.tailNonEmpty(rest.value)
for (; i < len - tail.length; i++) {
const te = head(input[i], options)
const t = PR.either(te)
if (t) {
if (E.isLeft(t)) {
const e = PR.index(i, t.left.errors)
if (allErrors) {
es.push([stepKey++, e])
continue
} else {
return PR.failures(mutableAppend(sortByIndex(es), e))
}
} else {
output.push([stepKey++, t.right])
}
} else {
const nk = stepKey++
const index = i
queue.push(
untracedMethod(() =>
({ es, output }: State) =>
Effect.flatMap(Effect.either(te), (t) => {
if (E.isLeft(t)) {
const e = PR.index(index, t.left.errors)
if (allErrors) {
es.push([nk, e])
return Effect.unit()
} else {
return PR.failures(mutableAppend(sortByIndex(es), e))
}
} else {
output.push([nk, t.right])
return Effect.unit()
}
})
)
)
}
}
// ---------------------------------------------
// handle post rest elements
// ---------------------------------------------
for (let j = 0; j < tail.length; j++) {
i += j
if (len < i + 1) {
continue
} else {
return PR.failures(mutableAppend(es, e))
const te = tail[j](input[i], options)
const t = PR.either(te)
if (t) {
if (E.isLeft(t)) {
// the input element is present but is not valid
const e = PR.index(i, t.left.errors)
if (allErrors) {
es.push([stepKey++, e])
continue
} else {
return PR.failures(mutableAppend(sortByIndex(es), e))
}
}
output.push([stepKey++, t.right])
} else {
const nk = stepKey++
const index = i
queue.push(
untracedMethod(() =>
({ es, output }: State) =>
Effect.flatMap(Effect.either(te), (t) => {
if (E.isLeft(t)) {
// the input element is present but is not valid
const e = PR.index(index, t.left.errors)
if (allErrors) {
es.push([nk, e])
return Effect.unit()
} else {
return PR.failures(mutableAppend(sortByIndex(es), e))
}
}
output.push([nk, t.right])
return Effect.unit()
})
)
)
}
}
}
output[name] = t.right
}
}
// ---------------------------------------------
// handle index signatures
// ---------------------------------------------
if (indexSignatures.length > 0) {
for (let i = 0; i < indexSignatures.length; i++) {
const parameter = indexSignatures[i][0]
const type = indexSignatures[i][1]
const keys = I.getKeysForIndexSignature(input, ast.indexSignatures[i].parameter)
for (const key of keys) {
if (Object.prototype.hasOwnProperty.call(expectedKeys, key)) {
continue
}
// ---------------------------------------------
// handle keys
// ---------------------------------------------
let t = parameter(key, options)
if (PR.isFailure(t)) {
const e = PR.key(key, t.left)
if (allErrors) {
es.push(e)
continue
} else {
return PR.failures(mutableAppend(es, e))
// ---------------------------------------------
// compute output
// ---------------------------------------------
const computeResult = ({ es, output }: State) =>
RA.isNonEmptyArray(es) ?
PR.failures(sortByIndex(es)) :
PR.success(sortByIndex(output))
return queue.length > 0 ?
untraced(() =>
Effect.suspend(() => {
const state: State = {
es: Array.from(es),
output: Array.from(output)
}
}
// ---------------------------------------------
// handle values
// ---------------------------------------------
t = type(input[key], options)
if (PR.isFailure(t)) {
const e = PR.key(key, t.left)
return Effect.flatMap(
Effect.forEachDiscard(queue, (f) => f(state)),
() => computeResult(state)
)
})
) :
computeResult({ output, es })
}
}
case "TypeLiteral": {
if (ast.propertySignatures.length === 0 && ast.indexSignatures.length === 0) {
return fromRefinement(ast, P.isNotNullable)
}
const propertySignaturesTypes = ast.propertySignatures.map((f) => go(f.type))
const indexSignatures = ast.indexSignatures.map((is) =>
[go(is.parameter), go(is.type)] as const
)
return (input: unknown, options) => {
if (!P.isRecord(input)) {
return PR.failure(PR.type(unknownRecord, input))
}
const allErrors = options?.allErrors
const expectedKeys: any = {}
const es: Array<[number, PR.ParseErrors]> = []
let stepKey = 0
// ---------------------------------------------
// handle missing keys
// ---------------------------------------------
for (let i = 0; i < propertySignaturesTypes.length; i++) {
const ps = ast.propertySignatures[i]
const name = ps.name
expectedKeys[name] = null
if (!Object.prototype.hasOwnProperty.call(input, name)) {
if (!ps.isOptional) {
const e = PR.key(name, [PR.missing])
if (allErrors) {
es.push(e)
es.push([stepKey++, e])
continue
} else {
return PR.failures(mutableAppend(es, e))
return PR.failure(e)
}
} else {
output[key] = t.right
}
}
}
} else {
// ---------------------------------------------

@@ -392,11 +548,11 @@ // handle unexpected keys

const isUnexpectedAllowed = options?.isUnexpectedAllowed
for (const key of Reflect.ownKeys(input)) {
if (!(Object.prototype.hasOwnProperty.call(expectedKeys, key))) {
const e = PR.key(key, [PR.unexpected(input[key])])
if (!isUnexpectedAllowed) {
if (!isUnexpectedAllowed && indexSignatures.length === 0) {
for (const key of Reflect.ownKeys(input)) {
if (!(Object.prototype.hasOwnProperty.call(expectedKeys, key))) {
const e = PR.key(key, [PR.unexpected(input[key])])
if (allErrors) {
es.push(e)
es.push([stepKey++, e])
continue
} else {
return PR.failures(mutableAppend(es, e))
return PR.failures(mutableAppend(sortByIndex(es), e))
}

@@ -406,117 +562,297 @@ }

}
}
// ---------------------------------------------
// compute output
// ---------------------------------------------
return RA.isNonEmptyReadonlyArray(es) ?
PR.failures(es) :
PR.success(output)
}
}
case "Union": {
const searchTree = _getSearchTree(ast.types)
const ownKeys = Reflect.ownKeys(searchTree.keys)
const len = ownKeys.length
const otherwise = searchTree.otherwise
const map = new Map()
for (let i = 0; i < ast.types.length; i++) {
map.set(ast.types[i], go(ast.types[i]))
}
return (input, options) => {
const es: Array<PR.ParseError> = []
// ---------------------------------------------
// handle property signatures
// ---------------------------------------------
const output: any = {}
type State = {
es: typeof es
output: typeof output
}
const queue: Array<(state: State) => PR.ParseResult<void>> = []
if (len > 0) {
// if there is at least one key then input must be an object
if (P.isRecord(input)) {
for (let i = 0; i < len; i++) {
const name = ownKeys[i]
const buckets = searchTree.keys[name].buckets
// for each property that should contain a literal, check if the input contains that property
if (Object.prototype.hasOwnProperty.call(input, name)) {
const literal = String(input[name])
// check that the value obtained from the input for the property corresponds to an existing bucket
if (Object.prototype.hasOwnProperty.call(buckets, literal)) {
// retrive the minimal set of candidates for decoding
const bucket = buckets[literal]
for (let i = 0; i < bucket.length; i++) {
const t = map.get(bucket[i])(input, options)
if (PR.isSuccess(t)) {
return t
for (let i = 0; i < propertySignaturesTypes.length; i++) {
const ps = ast.propertySignatures[i]
const parser = propertySignaturesTypes[i]
const name = ps.name
if (Object.prototype.hasOwnProperty.call(input, name)) {
const te = parser(input[name], options)
const t = PR.either(te)
if (t) {
if (E.isLeft(t)) {
// the input key is present but is not valid
const e = PR.key(name, t.left.errors)
if (allErrors) {
es.push([stepKey++, e])
continue
} else {
return PR.failures(mutableAppend(sortByIndex(es), e))
}
}
output[name] = t.right
} else {
const nk = stepKey++
const index = name
queue.push(
untracedMethod(() =>
({ es, output }: State) =>
Effect.flatMap(Effect.either(te), (t) => {
if (E.isLeft(t)) {
// the input key is present but is not valid
const e = PR.key(index, t.left.errors)
if (allErrors) {
es.push([nk, e])
return Effect.unit()
} else {
return PR.failures(mutableAppend(sortByIndex(es), e))
}
}
output[index] = t.right
return Effect.unit()
})
)
)
}
}
}
// ---------------------------------------------
// handle index signatures
// ---------------------------------------------
if (indexSignatures.length > 0) {
for (let i = 0; i < indexSignatures.length; i++) {
const parameter = indexSignatures[i][0]
const type = indexSignatures[i][1]
const keys = I.getKeysForIndexSignature(input, ast.indexSignatures[i].parameter)
for (const key of keys) {
if (Object.prototype.hasOwnProperty.call(expectedKeys, key)) {
continue
}
const te = parameter(key, options)
// ---------------------------------------------
// handle keys
// ---------------------------------------------
const t = PR.either(te)
if (t) {
if (E.isLeft(t)) {
const e = PR.key(key, t.left.errors)
if (allErrors) {
es.push([stepKey++, e])
continue
} else {
es.push(PR.unionMember(t.left))
return PR.failures(mutableAppend(sortByIndex(es), e))
}
}
}
// there's no else here because index signature parameters can't have transformations
// ---------------------------------------------
// handle values
// ---------------------------------------------
const tve = type(input[key], options)
const tv = PR.either(tve)
if (tv) {
if (E.isLeft(tv)) {
const e = PR.key(key, tv.left.errors)
if (allErrors) {
es.push([stepKey++, e])
continue
} else {
return PR.failures(mutableAppend(sortByIndex(es), e))
}
} else {
output[key] = tv.right
}
} else {
es.push(
PR.key(name, [
PR.type(
const nk = stepKey++
const index = key
queue.push(
untracedMethod(() =>
({ es, output }: State) =>
Effect.flatMap(
Effect.either(tve),
(tv) => {
if (E.isLeft(tv)) {
const e = PR.key(index, tv.left.errors)
if (allErrors) {
es.push([nk, e])
return Effect.unit()
} else {
return PR.failures(mutableAppend(sortByIndex(es), e))
}
} else {
output[key] = tv.right
return Effect.unit()
}
}
)
)
)
}
}
}
}
// ---------------------------------------------
// compute output
// ---------------------------------------------
const computeResult = ({ es, output }: State) =>
RA.isNonEmptyArray(es) ?
PR.failures(sortByIndex(es)) :
PR.success(output)
return queue.length > 0 ?
untraced(() =>
Effect.suspend(() => {
const state: State = {
es: Array.from(es),
output: Object.assign({}, output)
}
return Effect.flatMap(
Effect.forEachDiscard(queue, (f) => f(state)),
() => computeResult(state)
)
})
) :
computeResult({ es, output })
}
}
case "Union": {
const searchTree = _getSearchTree(ast.types)
const ownKeys = Reflect.ownKeys(searchTree.keys)
const len = ownKeys.length
const map = new Map<any, Parser<any, any>>()
for (let i = 0; i < ast.types.length; i++) {
map.set(ast.types[i], go(ast.types[i]))
}
return (input, options) => {
const es: Array<[number, PR.ParseErrors]> = []
let stepKey = 0
let candidates: Array<AST.AST> = []
if (len > 0) {
// if there is at least one key then input must be an object
if (P.isRecord(input)) {
for (let i = 0; i < len; i++) {
const name = ownKeys[i]
const buckets = searchTree.keys[name].buckets
// for each property that should contain a literal, check if the input contains that property
if (Object.prototype.hasOwnProperty.call(input, name)) {
const literal = String(input[name])
// check that the value obtained from the input for the property corresponds to an existing bucket
if (Object.prototype.hasOwnProperty.call(buckets, literal)) {
// retrive the minimal set of candidates for decoding
candidates = candidates.concat(buckets[literal])
} else {
es.push([
stepKey++,
PR.key(name, [PR.type(
searchTree.keys[name].ast,
input[name]
)
)])
])
)
}
} else {
es.push([stepKey++, PR.key(name, [PR.missing])])
}
}
} else {
es.push([stepKey++, PR.type(unknownRecord, input)])
}
}
if (searchTree.otherwise.length > 0) {
candidates = candidates.concat(searchTree.otherwise)
}
const queue: Array<(state: State) => PR.ParseResult<unknown>> = []
const finalResult: { ref: any } = {
ref: undefined
}
type State = {
finalResult: typeof finalResult
es: typeof es
}
for (let i = 0; i < candidates.length; i++) {
const te = map.get(candidates[i])!(input, options)
// the members of a union are ordered based on which one should be decoded first,
// therefore if one member has added a task, all subsequent members must
// also add a task to the queue even if they are synchronous
const t = queue.length === 0 ? PR.either(te) : undefined
if (t) {
if (E.isRight(t)) {
return PR.success(t.right)
} else {
es.push(PR.key(name, [PR.missing]))
es.push([stepKey++, PR.unionMember(t.left.errors)])
}
} else {
const nk = stepKey++
queue.push(
untracedMethod(() =>
({ es, finalResult }) =>
Effect.suspend(() => {
if (finalResult.ref) {
return Effect.unit()
} else {
return Effect.flatMap(Effect.either(te), (t) => {
if (E.isRight(t)) {
finalResult.ref = PR.success(t.right)
} else {
es.push([nk, PR.unionMember(t.left.errors)])
}
return Effect.unit()
})
}
})
)
)
}
} else {
es.push(PR.type(unknownRecord, input))
}
// ---------------------------------------------
// compute output
// ---------------------------------------------
const computeResult = ({ es }: State) =>
RA.isNonEmptyArray(es) ?
PR.failures(sortByIndex(es)) :
// this should never happen
PR.failure(PR.type(AST.neverKeyword, input))
return queue.length > 0 ?
untraced(() =>
Effect.suspend(() => {
const state: State = {
es: Array.from(es),
finalResult: { ref: finalResult.ref }
}
return Effect.flatMap(
Effect.forEachDiscard(queue, (f) => f(state)),
() => {
if (state.finalResult.ref) {
return state.finalResult.ref
}
return computeResult(state)
}
)
})
) :
computeResult({ es, finalResult })
}
// if none of the schemas with at least one property with a literal value succeeded,
// proceed with those that have no literal at all
for (let i = 0; i < otherwise.length; i++) {
const t = map.get(otherwise[i])(input, options)
if (PR.isSuccess(t)) {
return t
} else {
es.push(PR.unionMember(t.left))
}
}
// ---------------------------------------------
// compute output
// ---------------------------------------------
return RA.isNonEmptyReadonlyArray(es) ?
PR.failures(es) :
PR.failure(PR.type(AST.neverKeyword, input))
}
}
case "Lazy": {
const f = () => go(ast.f())
const get = I.memoize<typeof f, Parser>(f)
return (a, options) => get(f)(a, options)
}
case "Refinement": {
const from = go(ast.from)
if (ast.isReversed) {
const to = go(AST.getTo(ast.from))
return (a, options) =>
pipe(
to(a, options), // validate input
E.flatMap((a) => ast.decode(a, options)), // refine
E.flatMap((a) => from(a, options)) // encode
)
case "Lazy": {
const f = () => go(ast.f())
const get = I.memoize<typeof f, Parser<any, any>>(f)
return (a, options) => get(f)(a, options)
}
return (u, options) => E.flatMap(from(u, options), (a) => ast.decode(a, options))
}
case "Transform": {
const from = go(ast.from)
if (ast.isReversed) {
case "Refinement":
case "Transform": {
const from = go(ast.from)
const to = go(ast.to)
return (a, options) =>
pipe(
to(a, options), // validate input
E.flatMap((a) => ast.encode(a, options)), // transform
E.flatMap((a) => from(a, options)) // encode
return (i1, options) =>
PR.flatMap(
from(i1, options),
(a) => PR.flatMap(ast.decode(a, options), (i2) => to(i2, options))
)
}
return (u, options) => E.flatMap(from(u, options), (a) => ast.decode(a, options))
}
}
})
))
const fromRefinement = <A>(ast: AST.AST, refinement: (u: unknown) => u is A): Parser =>
const fromRefinement = <A>(ast: AST.AST, refinement: (u: unknown) => u is A): Parser<unknown, A> =>
(u) => refinement(u) ? PR.success(u) : PR.failure(PR.type(ast, u))

@@ -535,4 +871,5 @@

const propertySignature = ast.propertySignatures[i]
if (AST.isLiteral(propertySignature.type) && !propertySignature.isOptional) {
out.push([propertySignature.name, propertySignature.type])
const type = AST.getFrom(propertySignature.type)
if (AST.isLiteral(type) && !propertySignature.isOptional) {
out.push([propertySignature.name, type])
}

@@ -543,5 +880,4 @@ }

case "Refinement":
case "Transform":
return _getLiterals(ast.from)
case "Transform":
return ast.isReversed ? _getLiterals(ast.to) : _getLiterals(AST.getFrom(ast.from))
}

@@ -611,3 +947,5 @@ return []

const unknownArray = AST.createTuple([], O.some([AST.unknownKeyword]), true)
const unknownArray = AST.createTuple([], O.some([AST.unknownKeyword]), true, {
[AST.DescriptionAnnotationId]: "a generic array"
})

@@ -617,3 +955,5 @@ const unknownRecord = AST.createTypeLiteral([], [

AST.createIndexSignature(AST.symbolKeyword, AST.unknownKeyword, true)
])
], {
[AST.DescriptionAnnotationId]: "a generic object"
})

@@ -638,1 +978,7 @@ const mutableAppend = <A>(self: Array<A>, a: A): NonEmptyReadonlyArray<A> => {

}
function sortByIndex<T>(es: RA.NonEmptyArray<[number, T]>): RA.NonEmptyArray<T>
function sortByIndex<T>(es: Array<[number, T]>): Array<T>
function sortByIndex(es: Array<[number, any]>): any {
return es.sort(([a], [b]) => a > b ? 1 : a < b ? -1 : 0).map(([_, a]) => a)
}

@@ -5,5 +5,10 @@ /**

import type { Either, Left, Right } from "@effect/data/Either"
import * as E from "@effect/data/Either"
import * as O from "@effect/data/Option"
import type { NonEmptyReadonlyArray } from "@effect/data/ReadonlyArray"
import { failureOption } from "@effect/io/Cause"
import * as Debug from "@effect/io/Debug"
import * as Effect from "@effect/io/Effect"
import * as Exit from "@effect/io/Exit"
import { isExit } from "@effect/io/Exit"
import type * as AST from "@effect/schema/AST"

@@ -14,6 +19,22 @@

*/
export type ParseResult<A> = Either<NonEmptyReadonlyArray<ParseError>, A>
export interface ParseResult<A> extends Effect.Effect<never, ParseError, A> {}
/**
* `ParseError` is a type that represents the different types of errors that can occur when decoding a value.
* @since 1.0.0
*/
export interface ParseError {
readonly _tag: "ParseError"
readonly errors: NonEmptyReadonlyArray<ParseErrors>
}
/**
* @since 1.0.0
*/
export const parseError = (errors: NonEmptyReadonlyArray<ParseErrors>): ParseError => ({
_tag: "ParseError",
errors
})
/**
* `ParseErrors` is a type that represents the different types of errors that can occur when decoding a value.
*

@@ -23,3 +44,3 @@ * @category model

*/
export type ParseError =
export type ParseErrors =
| Type

@@ -46,2 +67,3 @@ | Index

readonly actual: unknown
readonly message: O.Option<string>
}

@@ -53,6 +75,7 @@

*/
export const type = (expected: AST.AST, actual: unknown): Type => ({
export const type = (expected: AST.AST, actual: unknown, message?: string): Type => ({
_tag: "Type",
expected,
actual
actual,
message: O.fromNullable(message)
})

@@ -72,3 +95,3 @@

readonly index: number
readonly errors: NonEmptyReadonlyArray<ParseError>
readonly errors: NonEmptyReadonlyArray<ParseErrors>
}

@@ -82,3 +105,3 @@

index: number,
errors: NonEmptyReadonlyArray<ParseError>
errors: NonEmptyReadonlyArray<ParseErrors>
): Index => ({

@@ -103,3 +126,3 @@ _tag: "Index",

readonly key: PropertyKey
readonly errors: NonEmptyReadonlyArray<ParseError>
readonly errors: NonEmptyReadonlyArray<ParseErrors>
}

@@ -113,3 +136,3 @@

key: PropertyKey,
errors: NonEmptyReadonlyArray<ParseError>
errors: NonEmptyReadonlyArray<ParseErrors>
): Key => ({

@@ -167,3 +190,3 @@ _tag: "Key",

readonly _tag: "UnionMember"
readonly errors: NonEmptyReadonlyArray<ParseError>
readonly errors: NonEmptyReadonlyArray<ParseErrors>
}

@@ -176,3 +199,3 @@

export const unionMember = (
errors: NonEmptyReadonlyArray<ParseError>
errors: NonEmptyReadonlyArray<ParseErrors>
): UnionMember => ({

@@ -187,3 +210,3 @@ _tag: "UnionMember",

*/
export const success: <A>(a: A) => ParseResult<A> = E.right
export const success: <A>(a: A) => ParseResult<A> = (a) => Exit.succeed(a)

@@ -194,3 +217,3 @@ /**

*/
export const failure = (e: ParseError): ParseResult<never> => E.left([e])
export const failure = (e: ParseErrors): ParseResult<never> => Exit.fail(parseError([e]))

@@ -202,17 +225,88 @@ /**

export const failures = (
es: NonEmptyReadonlyArray<ParseError>
): ParseResult<never> => E.left(es)
es: NonEmptyReadonlyArray<ParseErrors>
): ParseResult<never> => Exit.fail(parseError(es))
const untrace = <E, A>(self: Effect.Effect<never, E, A>): Effect.Effect<never, E, A> => {
// TODO: find a way to detect Traced
const s: any = self
return s["_tag"] === "Traced" ? s["i0"] : s
}
/**
* @category guards
* @category optimisation
* @since 1.0.0
*/
export const isSuccess: <A>(self: ParseResult<A>) => self is Right<A> = E.isRight
export const either = <E, A>(self: Effect.Effect<never, E, A>): E.Either<E, A> | undefined => {
const untraced = untrace(self)
if (isExit(untraced)) {
if (untraced._tag === "Success") {
return E.right(untraced.value as A)
} else {
const failure = failureOption(untraced.cause)
if (failure._tag === "Some") {
return E.left(failure.value as E)
}
}
}
}
/**
* @category guards
* @category optimisation
* @since 1.0.0
*/
export const isFailure: <A>(
self: ParseResult<A>
) => self is Left<NonEmptyReadonlyArray<ParseError>> = E.isLeft
export const eitherSync = <E, A>(self: Effect.Effect<never, E, A>): E.Either<E, A> => {
const untraced = untrace(self)
if (isExit(untraced)) {
if (untraced._tag === "Success") {
return E.right(untraced.value as A)
} else {
const failure = failureOption(untraced.cause)
if (failure._tag === "Some") {
return E.left(failure.value as E)
}
}
}
return Debug.untraced(() => Effect.runSyncEither(self))
}
/**
* @category optimisation
* @since 1.0.0
*/
export const flatMap = Debug.methodWithTrace((trace, restore) =>
<E, E1, A, B>(
self: Effect.Effect<never, E, A>,
f: (self: A) => Effect.Effect<never, E1, B>
): Effect.Effect<never, E | E1, B> => {
const e = either(self)
if (e) {
if (E.isRight(e)) {
return restore(f)(e.right)
} else {
return Exit.fail(e.left)
}
}
return Effect.flatMap(self, restore(f)).traced(trace)
}
)
/**
* @category optimisation
* @since 1.0.0
*/
export const map = Debug.methodWithTrace((trace, restore) =>
<E, A, B>(
self: Effect.Effect<never, E, A>,
f: (self: A) => B
): Effect.Effect<never, E, B> => {
const e = either(self)
if (e) {
if (E.isRight(e)) {
return Exit.succeed(restore(f)(e.right))
} else {
return Exit.fail(e.left)
}
}
return Effect.map(self, restore(f)).traced(trace)
}
)

@@ -11,15 +11,17 @@ /**

import * as D from "@effect/data/Data"
import type { Either } from "@effect/data/Either"
import * as E from "@effect/data/Either"
import type { Either } from "@effect/data/Either"
import * as Equal from "@effect/data/Equal"
import { dual, pipe } from "@effect/data/Function"
import { dual, identity, pipe } from "@effect/data/Function"
import * as N from "@effect/data/Number"
import type { Option } from "@effect/data/Option"
import * as O from "@effect/data/Option"
import type { Predicate, Refinement } from "@effect/data/Predicate"
import { isDate } from "@effect/data/Predicate"
import type { Predicate, Refinement } from "@effect/data/Predicate"
import * as RA from "@effect/data/ReadonlyArray"
import { untracedMethod } from "@effect/io/Debug"
import * as Effect from "@effect/io/Effect"
import type { Arbitrary } from "@effect/schema/Arbitrary"
import type { ParseOptions } from "@effect/schema/AST"
import * as AST from "@effect/schema/AST"
import type { ParseOptions } from "@effect/schema/AST"
import * as I from "@effect/schema/internal/common"

@@ -62,2 +64,7 @@ import * as P from "@effect/schema/Parser"

/**
* @since 1.0.0
*/
export const reverse = <I, A>(schema: Schema<I, A>): Schema<A, I> => make(AST.reverse(schema.ast))
/* c8 ignore start */

@@ -76,2 +83,6 @@ export {

*/
decodeEffect,
/**
* @since 1.0.0
*/
decodeEither,

@@ -85,2 +96,6 @@ /**

*/
decodePromise,
/**
* @since 1.0.0
*/
encode,

@@ -90,2 +105,6 @@ /**

*/
encodeEffect,
/**
* @since 1.0.0
*/
encodeEither,

@@ -99,2 +118,6 @@ /**

*/
encodePromise,
/**
* @since 1.0.0
*/
is,

@@ -104,2 +127,22 @@ /**

*/
parse,
/**
* @since 1.0.0
*/
parseEffect,
/**
* @since 1.0.0
*/
parseEither,
/**
* @since 1.0.0
*/
parseOption,
/**
* @since 1.0.0
*/
parsePromise,
/**
* @since 1.0.0
*/
validate,

@@ -109,2 +152,6 @@ /**

*/
validateEffect,
/**
* @since 1.0.0
*/
validateEither,

@@ -114,3 +161,7 @@ /**

*/
validateOption
validateOption,
/**
* @since 1.0.0
*/
validatePromise
} from "@effect/schema/Parser"

@@ -525,14 +576,14 @@

const schema = make(ast)
const decode = P.decode(schema)
const decodeOption = P.decodeOption(schema)
const decodeEither = P.decodeEither(schema)
const validate = P.validate(schema)
const validateOption = P.validateOption(schema)
const validateEither = P.validateEither(schema)
const is = P.is(schema)
const out: any = Object.assign((input: unknown) => decode(input), {
const out: any = Object.assign((input: unknown) => validate(input), {
[RefinedConstructorsTypeId]: RefinedConstructorsTypeId,
ast,
option: (input: unknown) => decodeOption(input),
option: (input: unknown) => validateOption(input),
either: (input: unknown) =>
E.mapLeft(
decodeEither(input),
(errors) => [{ meta: input, message: formatErrors(errors) }]
validateEither(input),
(e) => [{ meta: input, message: formatErrors(e.errors) }]
),

@@ -570,7 +621,7 @@ refine: (input: unknown): input is A & Brand<B> => is(input)

y.indexSignatures.some((iy) => {
const bx = AST._getParameter(ix.parameter)
const by = AST._getParameter(iy.parameter)
const keyofx = AST._getParameterKeyof(ix.parameter)
const keyofy = AST._getParameterKeyof(iy.parameter)
// there cannot be two string index signatures or two symbol index signatures at the same time
return (AST.isStringKeyword(bx) && AST.isStringKeyword(by)) ||
(AST.isSymbolKeyword(bx) && AST.isSymbolKeyword(by))
return (AST.isStringKeyword(keyofx) && AST.isStringKeyword(keyofy)) ||
(AST.isSymbolKeyword(keyofx) && AST.isSymbolKeyword(keyofy))
})

@@ -690,7 +741,9 @@ )

): <I>(self: Schema<I, A>) => Schema<I, A> {
return (from) => {
return (self) => {
const decode = (a: A) => predicate(a) ? PR.success(a) : PR.failure(PR.type(ast, a))
const ast = AST.createRefinement(
from.ast,
(a: A) => predicate(a) ? PR.success(a) : PR.failure(PR.type(ast, a)),
false,
self.ast,
AST.getTo(self.ast),
decode,
decode,
toAnnotations(options)

@@ -709,20 +762,66 @@ )

*/
export const transformEffect: {
<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>
<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>
} = dual(4, <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> => 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
*/
export const transformEither: {
<B, A>(
to: Schema<any, B>,
decode: (input: A, options?: ParseOptions) => ParseResult<B>,
encode: (input: B, options?: ParseOptions) => ParseResult<A>
): <I>(self: Schema<I, A>) => Schema<I, B>
<I, A, B>(
self: Schema<I, A>,
to: Schema<any, B>,
decode: (input: A, options?: ParseOptions) => ParseResult<B>,
encode: (input: B, options?: ParseOptions) => ParseResult<A>
): Schema<I, B>
} = dual(4, <I, A, B>(
self: Schema<I, A>,
to: Schema<any, B>,
decode: (input: A, options?: ParseOptions) => ParseResult<B>,
encode: (input: B, options?: ParseOptions) => ParseResult<A>
): Schema<I, B> => make(AST.createTransform(self.ast, to.ast, decode, encode, false)))
<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, (i, o) =>
Effect.fromEither(decode(i, o)), (i, o) =>
Effect.fromEither(encode(i, o)))
))

@@ -737,16 +836,22 @@ /**

export const transform: {
<B, A>(
to: Schema<any, B>,
ab: (a: A) => B,
ba: (b: B) => A
): <I>(self: Schema<I, A>) => Schema<I, B>
<I, A, B>(self: Schema<I, A>, to: Schema<any, B>, ab: (a: A) => B, ba: (b: B) => A): Schema<I, B>
<I2, A2, A1>(
to: Schema<I2, A2>,
decode: (a1: A1) => I2,
encode: (i2: I2) => A1
): <I1>(self: Schema<I1, A1>) => Schema<I1, A2>
<I1, A1, I2, A2>(
from: Schema<I1, A1>,
to: Schema<I2, A2>,
decode: (a1: A1) => I2,
encode: (i2: I2) => A1
): Schema<I1, A2>
} = dual(
4,
<I, A, B>(
self: Schema<I, A>,
to: Schema<any, B>,
ab: (a: A) => B,
ba: (b: B) => A
): Schema<I, B> => transformEither(self, to, (a) => PR.success(ab(a)), (b) => PR.success(ba(b)))
<I1, A1, I2, A2>(
from: Schema<I1, A1>,
to: Schema<I2, A2>,
decode: (a1: A1) => I2,
encode: (i2: I2) => A1
): Schema<I1, A2> =>
transformEffect(from, to, (a) => PR.success(decode(a)), (b) => PR.success(encode(b)))
)

@@ -787,3 +892,3 @@

<I, A extends object>(schema: Schema<I, A>): Schema<I, Spread<A & { readonly [k in K]: V }>> =>
transform<I, A, any>(
transform<I, A, any, any>(
schema,

@@ -1143,5 +1248,5 @@ pipe(to(schema), extend(struct({ [key]: literal(value) }))),

self,
pipe(self, betweenBigint(min, max)),
pipe(self, to, betweenBigint(min, max)),
(self) => B.clamp(self, min, max) as A,
(self) => B.clamp(self, min, max) as A
identity
)

@@ -1166,16 +1271,22 @@

) =>
<I, A extends Brand.Unbranded<C>>(self: Schema<I, A>): Schema<I, A & C> =>
pipe(
self,
filter<A, A & C>(
(x): x is A & C => constructor.refine(x),
{
typeId: BrandTypeId,
message: (a) =>
(constructor.either(a) as E.Left<Brand.BrandErrors>).left.map((v) => v.message)
.join(", "),
...options
}
)
<I, A extends Brand.Unbranded<C>>(self: Schema<I, A>): Schema<I, A & C> => {
const decode = untracedMethod(() =>
(a: A): ParseResult<C> =>
Effect.fromEither(
E.mapLeft(
constructor.either(a),
(brandErrors) =>
PR.parseError([PR.type(ast, a, brandErrors.map((v) => v.message).join(", "))])
)
)
)
const ast = AST.createRefinement(
self.ast,
AST.getTo(self.ast),
decode,
decode,
toAnnotations({ typeId: BrandTypeId, ...options })
)
return make(ast)
}

@@ -1204,7 +1315,7 @@ // ---------------------------------------------

<A>(item: Schema<A>) => {
const items = P.decodeEither(array(item))
const parse = P.parseEffect(array(item))
return (u, options) =>
!C.isChunk(u) ?
PR.failure(PR.type(schema.ast, u)) :
E.map(items(C.toReadonlyArray(u), options), C.fromIterable)
PR.map(parse(C.toReadonlyArray(u), options), C.fromIterable)
},

@@ -1225,3 +1336,3 @@ {

export const chunk = <I, A>(item: Schema<I, A>): Schema<ReadonlyArray<I>, Chunk<A>> =>
transform(array(item), chunkFromSelf(item), C.fromIterable, C.toReadonlyArray)
transform(array(item), to(chunkFromSelf(item)), C.fromIterable, C.toReadonlyArray)

@@ -1259,7 +1370,7 @@ // ---------------------------------------------

) => {
const decode = P.decodeEither(item)
const parse = P.parseEffect(item)
return (u, options) =>
!Equal.isEqual(u) ?
PR.failure(PR.type(schema.ast, u)) :
E.map(decode(u, options), toData)
PR.map(parse(u, options), toData)
},

@@ -1287,3 +1398,3 @@ {

item,
dataFromSelf(item),
to(dataFromSelf(item)),
toData,

@@ -1322,16 +1433,13 @@ (a) => Array.isArray(a) ? Array.from(a) : Object.assign({}, a) as any

*/
export const dateFromString = <I>(self: Schema<I, string>): Schema<I, Date> => {
const schema: Schema<I, Date> = transformEither(
self,
date,
(s) => {
const n = Date.parse(s)
return isNaN(n)
? PR.failure(PR.type(schema.ast, s))
: PR.success(new Date(n))
},
(n) => PR.success(n.toISOString())
)
return schema
}
export const dateFromString: Schema<string, Date> = transformEffect(
string,
date,
(s) => {
const n = Date.parse(s)
return isNaN(n)
? PR.failure(PR.type(dateFromString.ast, s))
: PR.success(new Date(n))
},
(n) => PR.success(n.toISOString())
)

@@ -1380,4 +1488,4 @@ // ---------------------------------------------

) => {
const decodeLeft = P.decodeEither(left)
const decodeRight = P.decodeEither(right)
const parseLeft = P.parseEffect(left)
const parseRight = P.parseEffect(right)
return (u, options) =>

@@ -1387,4 +1495,4 @@ !E.isEither(u) ?

E.isLeft(u) ?
E.map(decodeLeft(u.left, options), E.left) :
E.map(decodeRight(u.right, options), E.right)
PR.map(parseLeft(u.left, options), E.left) :
PR.map(parseRight(u.right, options), E.right)
},

@@ -1413,3 +1521,3 @@ {

eitherInline(left, right),
eitherFromSelf(left, right),
to(eitherFromSelf(left, right)),
(a) => a._tag === "Left" ? E.left(a.left) : E.right(a.right),

@@ -1754,5 +1862,5 @@ E.match(

self,
pipe(self, between<A>(min, max)),
pipe(self, to, between<A>(min, max)),
(self) => N.clamp(self, min, max) as A,
(self) => N.clamp(self, min, max) as A
identity
)

@@ -1769,3 +1877,3 @@

export const numberFromString = <I>(self: Schema<I, string>): Schema<I, number> => {
const schema: Schema<I, number> = transformEither(
const schema: Schema<I, number> = transformEffect(
self,

@@ -1857,3 +1965,3 @@ number,

<A>(value: Schema<A>) => {
const decodeValue = P.decodeEither(value)
const parse = P.parseEffect(value)
return (u, options) =>

@@ -1864,3 +1972,3 @@ !O.isOption(u) ?

PR.success(O.none()) :
E.map(decodeValue(u.value, options), O.some)
PR.map(parse(u.value, options), O.some)
},

@@ -1885,3 +1993,3 @@ {

optionInline(value),
optionFromSelf(value),
to(optionFromSelf(value)),
(a) => a._tag === "None" ? O.none() : O.some(a.value),

@@ -1898,3 +2006,3 @@ O.match(() => ({ _tag: "None" as const }), (value) => ({ _tag: "Some" as const, value }))

): Schema<I | null | undefined, Option<A>> =>
transform(union(_undefined, _null, value), optionFromSelf(value), O.fromNullable, O.getOrNull)
transform(union(_undefined, _null, value), to(optionFromSelf(value)), O.fromNullable, O.getOrNull)

@@ -1959,3 +2067,3 @@ /**

return PR.success(out)
}, false)
})
return make(out)

@@ -2082,7 +2190,7 @@ }

) => {
const items = P.decodeEither(array(tuple(key, value)))
const parse = P.parseEffect(array(tuple(key, value)))
return (u, options) =>
!isMap(u) ?
PR.failure(PR.type(schema.ast, u)) :
E.map(items(Array.from(u.entries()), options), (as) => new Map(as))
PR.map(parse(Array.from(u.entries()), options), (as) => new Map(as))
},

@@ -2108,3 +2216,3 @@ {

array(tuple(key, value)),
readonlyMapFromSelf(key, value),
to(readonlyMapFromSelf(key, value)),
(as) => new Map(as),

@@ -2139,7 +2247,7 @@ (map) => Array.from(map.entries())

<A>(item: Schema<A>) => {
const items = P.decodeEither(array(item))
const parse = P.parseEffect(array(item))
return (u, options) =>
!isSet(u) ?
PR.failure(PR.type(schema.ast, u)) :
E.map(items(Array.from(u.values()), options), (as) => new Set(as))
PR.map(parse(Array.from(u.values()), options), (as) => new Set(as))
},

@@ -2162,3 +2270,3 @@ {

array(item),
readonlySetFromSelf(item),
to(readonlySetFromSelf(item)),
(as) => new Set(as),

@@ -2368,5 +2476,5 @@ (set) => Array.from(set)

self,
pipe(self, trimmed()),
pipe(to(self), trimmed()),
(s) => s.trim(),
(s) => s.trim()
identity
)

@@ -2373,0 +2481,0 @@

@@ -9,3 +9,3 @@ /**

import * as AST from "@effect/schema/AST"
import type * as PR from "@effect/schema/ParseResult"
import type { ParseErrors } from "@effect/schema/ParseResult"

@@ -15,4 +15,4 @@ interface Forest<A> extends ReadonlyArray<Tree<A>> {}

interface Tree<A> {
value: A
forest: Forest<A>
readonly value: A
readonly forest: Forest<A>
}

@@ -28,3 +28,3 @@

*/
export const formatErrors = (errors: NonEmptyReadonlyArray<PR.ParseError>): string =>
export const formatErrors = (errors: NonEmptyReadonlyArray<ParseErrors>): string =>
drawTree(make(`error(s) found`, errors.map(go)))

@@ -123,4 +123,2 @@

return ast.types.map(formatExpected).join(" or ")
case "Refinement":
return pipe(getExpected(ast), O.getOrElse(() => "<anonymous refinement schema>"))
case "TemplateLiteral":

@@ -147,8 +145,12 @@ return pipe(getExpected(ast), O.getOrElse(() => formatTemplateLiteral(ast)))

)
case "Refinement":
case "Transform":
return `a parsable value from ${formatExpected(ast.from)} to ${formatExpected(ast.to)}`
return pipe(
getExpected(ast),
O.getOrElse(() => `${formatExpected(ast.from)} -> ${formatExpected(ast.to)}`)
)
}
}
const go = (e: PR.ParseError): Tree<string> => {
const go = (e: ParseErrors): Tree<string> => {
switch (e._tag) {

@@ -160,2 +162,3 @@ case "Type":

O.map((f) => f(e.actual)),
O.orElse(() => e.message),
O.getOrElse(() =>

@@ -162,0 +165,0 @@ `Expected ${formatExpected(e.expected)}, actual ${formatActual(e.actual)}`

/**
* @since 1.0.0
*/
import type * as PR from "@effect/schema/ParseResult";
import type { ParseErrors } from "@effect/schema/ParseResult";
/**
* @since 1.0.0
*/
export declare const formatErrors: (errors: readonly [PR.ParseError, ...PR.ParseError[]]) => string;
export declare const formatErrors: (errors: readonly [ParseErrors, ...ParseErrors[]]) => string;
//# sourceMappingURL=TreeFormatter.d.ts.map

@@ -97,4 +97,2 @@ "use strict";

return ast.types.map(formatExpected).join(" or ");
case "Refinement":
return (0, _Function.pipe)(getExpected(ast), O.getOrElse(() => "<anonymous refinement schema>"));
case "TemplateLiteral":

@@ -112,4 +110,5 @@ return (0, _Function.pipe)(getExpected(ast), O.getOrElse(() => formatTemplateLiteral(ast)));

return (0, _Function.pipe)(getExpected(ast), O.getOrElse(() => "<anonymous declaration schema>"));
case "Refinement":
case "Transform":
return `a parsable value from ${formatExpected(ast.from)} to ${formatExpected(ast.to)}`;
return (0, _Function.pipe)(getExpected(ast), O.getOrElse(() => `${formatExpected(ast.from)} -> ${formatExpected(ast.to)}`));
}

@@ -121,3 +120,3 @@ };

case "Type":
return make((0, _Function.pipe)(getMessage(e.expected), O.map(f => f(e.actual)), O.getOrElse(() => `Expected ${formatExpected(e.expected)}, actual ${formatActual(e.actual)}`)));
return make((0, _Function.pipe)(getMessage(e.expected), O.map(f => f(e.actual)), O.orElse(() => e.message), O.getOrElse(() => `Expected ${formatExpected(e.expected)}, actual ${formatActual(e.actual)}`)));
case "Index":

@@ -124,0 +123,0 @@ {

@@ -31,3 +31,2 @@ {

"forceConsistentCasingInFileNames": true,
"suppressImplicitAnyIndexErrors": true,
"stripInternal": true,

@@ -34,0 +33,0 @@ "noImplicitAny": true,

@@ -7,5 +7,8 @@ {

"tsBuildInfoFile": "build/tsbuildinfo/esm.tsbuildinfo",
"rootDir": "src"
"rootDir": "src",
"target": "ES2022"
},
"include": ["src/**/*.ts"]
"include": [
"src/**/*.ts"
]
}

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

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

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

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

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

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

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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc