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.0.0-snapshot-78b767c2b1625186e17131761a0edbac25d21850 to 0.0.0-snapshot-79dc882eafd6ddb60780764e2f663a6087b52622

40

dist/cjs/Arbitrary.js

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

exports.makeLazy = exports.make = exports.getConstraints = exports.combineConstraints = exports.arbitrary = exports.StringConstraints = exports.NumberConstraints = exports.IntegerConstraints = exports.BigIntConstraints = exports.ArrayConstraints = exports.ArbitraryHookId = void 0;
var Array = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Array"));
var Arr = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Array"));
var Option = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Option"));

@@ -64,3 +64,3 @@ var Predicate = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Predicate"));

exports.arbitrary = arbitrary;
const makeLazy = schema => go(schema.ast, {});
const makeLazy = schema => go(schema.ast, {}, []);
/**

@@ -91,3 +91,3 @@ * Returns a fast-check Arbitrary for the `A` type of the provided schema.

const getHook = /*#__PURE__*/AST.getAnnotation(ArbitraryHookId);
const getRefinementFromArbitrary = (ast, options) => {
const getRefinementFromArbitrary = (ast, options, path) => {
const constraints = combineConstraints(options.constraints, getConstraints(ast));

@@ -97,5 +97,6 @@ return go(ast.from, constraints ? {

constraints
} : options);
} : options, path);
};
const go = (ast, options) => {
const getArbitraryErrorMessage = (message, path) => errors_.getErrorMessageWithPath(`cannot build an Arbitrary for ${message}`, path);
const go = (ast, options, path) => {
const hook = getHook(ast);

@@ -105,5 +106,5 @@ if (Option.isSome(hook)) {

case "Declaration":
return hook.value(...ast.typeParameters.map(p => go(p, options)));
return hook.value(...ast.typeParameters.map(p => go(p, options, path)));
case "Refinement":
return hook.value(getRefinementFromArbitrary(ast, options));
return hook.value(getRefinementFromArbitrary(ast, options, path));
default:

@@ -116,3 +117,3 @@ return hook.value();

{
throw new Error(errors_.getArbitraryErrorMessage(`a declaration without annotations (${ast})`));
throw new Error(getArbitraryErrorMessage(`a declaration without annotations (${ast})`, path));
}

@@ -128,3 +129,3 @@ case "Literal":

return () => {
throw new Error(errors_.getArbitraryErrorMessage("`never`"));
throw new Error(getArbitraryErrorMessage("`never`", path));
};

@@ -197,4 +198,5 @@ case "UnknownKeyword":

let hasOptionals = false;
let i = 0;
for (const element of ast.elements) {
elements.push(go(element.type, options));
elements.push(go(element.type, options, path.concat(i++)));
if (element.isOptional) {

@@ -204,3 +206,3 @@ hasOptionals = true;

}
const rest = ast.rest.map(e => go(e, options));
const rest = ast.rest.map(e => go(e, options, path));
return fc => {

@@ -225,3 +227,3 @@ // ---------------------------------------------

// ---------------------------------------------
if (Array.isNonEmptyReadonlyArray(rest)) {
if (Arr.isNonEmptyReadonlyArray(rest)) {
const [head, ...tail] = rest;

@@ -256,4 +258,4 @@ const arb = head(fc);

{
const propertySignaturesTypes = ast.propertySignatures.map(f => go(f.type, options));
const indexSignatures = ast.indexSignatures.map(is => [go(is.parameter, options), go(is.type, options)]);
const propertySignaturesTypes = ast.propertySignatures.map(ps => go(ps.type, options, path.concat(ps.name)));
const indexSignatures = ast.indexSignatures.map(is => [go(is.parameter, options, path), go(is.type, options, path)]);
return fc => {

@@ -294,3 +296,3 @@ const arbs = {};

{
const types = ast.types.map(t => go(t, options));
const types = ast.types.map(t => go(t, options, path));
return fc => fc.oneof({

@@ -303,3 +305,3 @@ depthSize

if (ast.enums.length === 0) {
throw new Error(errors_.getArbitraryErrorMessage("an empty enum"));
throw new Error(getArbitraryErrorMessage("an empty enum", path));
}

@@ -310,3 +312,3 @@ return fc => fc.oneof(...ast.enums.map(([_, value]) => fc.constant(value)));

{
const from = getRefinementFromArbitrary(ast, options);
const from = getRefinementFromArbitrary(ast, options, path);
return fc => from(fc).filter(a => Option.isNone(ast.filter(a, AST.defaultParseOption, ast)));

@@ -319,7 +321,7 @@ }

isSuspend: true
}));
}, path));
return fc => fc.constant(null).chain(() => get()(fc));
}
case "Transformation":
return go(ast.to, options);
return go(ast.to, options, path);
}

@@ -326,0 +328,0 @@ };

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

exports.formatIssueSync = exports.formatIssue = exports.formatErrorSync = exports.formatError = void 0;
var Array = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Array"));
var Arr = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Array"));
var Effect = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Effect"));

@@ -64,10 +64,12 @@ var TreeFormatter = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./TreeFormatter.js"));

exports.formatErrorSync = formatErrorSync;
const succeed = issue => Effect.succeed([issue]);
const getArray = (issue, path, onFailure) => Effect.matchEffect(TreeFormatter.getMessage(issue), {
onFailure,
onSuccess: message => Effect.succeed([{
onSuccess: message => succeed({
_tag: issue._tag,
path,
message
}])
})
});
const flatten = eff => Effect.map(eff, Arr.flatten);
const go = (e, path = []) => {

@@ -83,21 +85,21 @@ const _tag = e._tag;

case "Forbidden":
return Effect.succeed([{
return succeed({
_tag,
path,
message: TreeFormatter.formatForbiddenMessage(e)
}]);
});
case "Unexpected":
return Effect.succeed([{
return succeed({
_tag,
path,
message: `is unexpected, expected ${e.ast.toString(true)}`
}]);
});
case "Missing":
return Effect.succeed([{
return succeed({
_tag,
path,
message: "is missing"
}]);
});
case "Union":
return getArray(e, path, () => Effect.map(Effect.forEach(e.errors, e => {
return getArray(e, path, () => flatten(Effect.forEach(e.errors, e => {
switch (e._tag) {

@@ -109,10 +111,10 @@ case "Member":

}
}), Array.flatten));
})));
case "TupleType":
return getArray(e, path, () => Effect.map(Effect.forEach(e.errors, index => go(index.error, [...path, index.index])), Array.flatten));
return getArray(e, path, () => flatten(Effect.forEach(e.errors, index => go(index.error, path.concat(index.index)))));
case "TypeLiteral":
return getArray(e, path, () => Effect.map(Effect.forEach(e.errors, key => go(key.error, [...path, key.key])), Array.flatten));
return getArray(e, path, () => flatten(Effect.forEach(e.errors, key => go(key.error, path.concat(key.key)))));
case "Declaration":
case "Refinement":
case "Transformation":
case "Refinement":
case "Declaration":
return getArray(e, path, () => go(e.error, path));

@@ -119,0 +121,0 @@ }

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

exports.make = exports.equivalence = exports.EquivalenceHookId = void 0;
var Array = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Array"));
var Arr = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Array"));
var Equal = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Equal"));

@@ -63,6 +63,7 @@ var Equivalence = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Equivalence"));

exports.equivalence = equivalence;
const make = schema => go(schema.ast);
const make = schema => go(schema.ast, []);
exports.make = make;
const getHook = /*#__PURE__*/AST.getAnnotation(EquivalenceHookId);
const go = ast => {
const getEquivalenceErrorMessage = (message, path) => errors_.getErrorMessageWithPath(`cannot build an Equivalence for ${message}`, path);
const go = (ast, path) => {
const hook = getHook(ast);

@@ -72,5 +73,5 @@ if (Option.isSome(hook)) {

case "Declaration":
return hook.value(...ast.typeParameters.map(go));
return hook.value(...ast.typeParameters.map(tp => go(tp, path)));
case "Refinement":
return hook.value(go(ast.from));
return hook.value(go(ast.from, path));
default:

@@ -82,5 +83,5 @@ return hook.value();

case "NeverKeyword":
throw new Error(errors_.getEquivalenceErrorMessage("`never`"));
throw new Error(getEquivalenceErrorMessage("`never`", path));
case "Transformation":
return go(ast.to);
return go(ast.to, path);
case "Declaration":

@@ -103,6 +104,6 @@ case "Literal":

case "Refinement":
return go(ast.from);
return go(ast.from, path);
case "Suspend":
{
const get = util_.memoizeThunk(() => go(ast.f()));
const get = util_.memoizeThunk(() => go(ast.f(), path));
return (a, b) => get()(a, b);

@@ -112,4 +113,4 @@ }

{
const elements = ast.elements.map(element => go(element.type));
const rest = ast.rest.map(go);
const elements = ast.elements.map((element, i) => go(element.type, path.concat(i)));
const rest = ast.rest.map(ast => go(ast, path));
return Equivalence.make((a, b) => {

@@ -132,3 +133,3 @@ const len = a.length;

// ---------------------------------------------
if (Array.isNonEmptyReadonlyArray(rest)) {
if (Arr.isNonEmptyReadonlyArray(rest)) {
const [head, ...tail] = rest;

@@ -158,4 +159,4 @@ for (; i < len - tail.length; i++) {

}
const propertySignatures = ast.propertySignatures.map(ps => go(ps.type));
const indexSignatures = ast.indexSignatures.map(is => go(is.type));
const propertySignatures = ast.propertySignatures.map(ps => go(ps.type, path.concat(ps.name)));
const indexSignatures = ast.indexSignatures.map(is => go(is.type, path));
return Equivalence.make((a, b) => {

@@ -234,3 +235,3 @@ const aStringKeys = Object.keys(a);

}
const tuples = candidates.map(ast => [go(ast), ParseResult.is({
const tuples = candidates.map(ast => [go(ast, path), ParseResult.is({
ast

@@ -237,0 +238,0 @@ })]);

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

});
exports.getRequiredElementFollowinAnOptionalElementErrorMessage = exports.getPrettyErrorMessage = exports.getIndexSignatureParameterErrorMessage = exports.getEquivalenceErrorMessage = exports.getDuplicatePropertySignatureTransformationErrorMessage = exports.getDuplicatePropertySignatureErrorMessage = exports.getDuplicateIndexSignatureErrorMessage = exports.getArbitraryErrorMessage = exports.getAPIErrorMessage = void 0;
exports.getErrorMessageWithPath = exports.getErrorMessage = exports.getDuplicatePropertySignatureErrorMessage = void 0;
var util_ = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./util.js"));

@@ -38,23 +38,13 @@ function _getRequireWildcardCache(e) {

exports.getDuplicatePropertySignatureErrorMessage = getDuplicatePropertySignatureErrorMessage;
const getDuplicateIndexSignatureErrorMessage = name => `Duplicate index signature for type \`${name}\``;
const getErrorMessage = (api, message) => `${api}: ${message}`;
/** @internal */
exports.getDuplicateIndexSignatureErrorMessage = getDuplicateIndexSignatureErrorMessage;
const getIndexSignatureParameterErrorMessage = exports.getIndexSignatureParameterErrorMessage = "An index signature parameter type must be `string`, `symbol`, a template literal type or a refinement of the previous types";
/** @internal */
const getRequiredElementFollowinAnOptionalElementErrorMessage = exports.getRequiredElementFollowinAnOptionalElementErrorMessage = "A required element cannot follow an optional element. ts(1257)";
/** @internal */
const getDuplicatePropertySignatureTransformationErrorMessage = name => `Duplicate property signature transformation ${util_.formatUnknown(name)}`;
/** @internal */
exports.getDuplicatePropertySignatureTransformationErrorMessage = getDuplicatePropertySignatureTransformationErrorMessage;
const getArbitraryErrorMessage = message => `cannot build an Arbitrary for ${message}`;
/** @internal */
exports.getArbitraryErrorMessage = getArbitraryErrorMessage;
const getPrettyErrorMessage = message => `cannot build a Pretty for ${message}`;
/** @internal */
exports.getPrettyErrorMessage = getPrettyErrorMessage;
const getEquivalenceErrorMessage = message => `cannot build an Equivalence for ${message}`;
/** @internal */
exports.getEquivalenceErrorMessage = getEquivalenceErrorMessage;
const getAPIErrorMessage = (api, message) => `${api}: ${message}`;
exports.getAPIErrorMessage = getAPIErrorMessage;
exports.getErrorMessage = getErrorMessage;
const getErrorMessageWithPath = (message, path) => {
let out = message;
if (path.length > 0) {
out += ` (path [${path.map(util_.formatPropertyKey).join(", ")}])`;
}
return out;
};
exports.getErrorMessageWithPath = getErrorMessageWithPath;
//# sourceMappingURL=errors.js.map

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

});
exports.ownKeys = exports.memoizeThunk = exports.getKeysForIndexSignature = exports.formatUnknown = void 0;
exports.ownKeys = exports.memoizeThunk = exports.getKeysForIndexSignature = exports.formatUnknown = exports.formatPropertyKey = void 0;
var Predicate = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Predicate"));

@@ -86,3 +86,6 @@ function _getRequireWildcardCache(e) {

};
/** @internal */
exports.formatUnknown = formatUnknown;
const formatPropertyKey = name => typeof name === "string" ? JSON.stringify(name) : String(name);
exports.formatPropertyKey = formatPropertyKey;
//# sourceMappingURL=util.js.map

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

var AST = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./AST.js"));
var errors_ = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./internal/errors.js"));
function _getRequireWildcardCache(e) {

@@ -47,3 +48,3 @@ if ("function" != typeof WeakMap) return null;

const $defs = {};
const jsonSchema = go(schema.ast, $defs);
const jsonSchema = go(schema.ast, $defs, true, []);
const out = {

@@ -88,3 +89,3 @@ $schema,

const $schema = "http://json-schema.org/draft-07/schema#";
const getMeta = annotated => Record.getSomes({
const getJsonSchemaAnnotations = annotated => Record.getSomes({
description: AST.getDescriptionAnnotation(annotated),

@@ -102,36 +103,49 @@ title: AST.getTitleAnnotation(annotated),

};
const getMissingAnnotationError = name => {
const out = new Error(`cannot build a JSON Schema for ${name} without a JSON Schema annotation`);
out.name = "MissingAnnotation";
return out;
};
const getUnsupportedIndexSignatureParameterErrorMessage = parameter => `Unsupported index signature parameter (${parameter})`;
const getMissingAnnotationErrorMessage = (name, path) => errors_.getErrorMessageWithPath(`cannot build a JSON Schema for ${name} without a JSON Schema annotation`, path);
const getUnsupportedIndexSignatureParameterErrorMessage = (parameter, path) => errors_.getErrorMessageWithPath(`unsupported index signature parameter (${parameter})`, path);
/** @internal */
const DEFINITION_PREFIX = exports.DEFINITION_PREFIX = "#/$defs/";
const get$ref = id => `${DEFINITION_PREFIX}${id}`;
const go = (ast, $defs, handleIdentifier = true) => {
const hasTransformation = ast => {
switch (ast.from._tag) {
case "Transformation":
return true;
case "Refinement":
return hasTransformation(ast.from);
case "Suspend":
{
const from = ast.from.f();
if (AST.isRefinement(from)) {
return hasTransformation(from);
}
}
break;
}
return false;
};
const go = (ast, $defs, handleIdentifier, path) => {
const hook = AST.getJSONSchemaAnnotation(ast);
if (Option.isSome(hook)) {
const handler = hook.value;
switch (ast._tag) {
case "Refinement":
try {
return {
...go(ast.from, $defs),
...getMeta(ast),
...handler
};
} catch (e) {
if (e instanceof Error && e.name === "MissingAnnotation") {
return {
...getMeta(ast),
...handler
};
}
throw e;
}
if (AST.isRefinement(ast) && !hasTransformation(ast)) {
try {
return {
...go(ast.from, $defs, true, path),
...getJsonSchemaAnnotations(ast),
...handler
};
} catch (e) {
return {
...getJsonSchemaAnnotations(ast),
...handler
};
}
}
return handler;
}
if (handleIdentifier) {
const surrogate = AST.getSurrogateAnnotation(ast);
if (Option.isSome(surrogate)) {
return go(surrogate.value, $defs, handleIdentifier, path);
}
if (handleIdentifier && !AST.isTransformation(ast)) {
const identifier = AST.getJSONIdentifier(ast);

@@ -145,3 +159,3 @@ if (Option.isSome(identifier)) {

$defs[id] = out;
$defs[id] = go(ast, $defs, false);
$defs[id] = go(ast, $defs, false, path);
}

@@ -153,3 +167,3 @@ return out;

case "Declaration":
throw getMissingAnnotationError("a declaration");
throw new Error(getMissingAnnotationErrorMessage("a declaration", path));
case "Literal":

@@ -161,3 +175,3 @@ {

const: null,
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -167,3 +181,3 @@ } else if (Predicate.isString(literal)) {

const: literal,
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -173,3 +187,3 @@ } else if (Predicate.isNumber(literal)) {

const: literal,
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -179,19 +193,19 @@ } else if (Predicate.isBoolean(literal)) {

const: literal,
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};
}
throw getMissingAnnotationError("a bigint literal");
throw new Error(getMissingAnnotationErrorMessage("a bigint literal", path));
}
case "UniqueSymbol":
throw getMissingAnnotationError("a unique symbol");
throw new Error(getMissingAnnotationErrorMessage("a unique symbol", path));
case "UndefinedKeyword":
throw getMissingAnnotationError("`undefined`");
throw new Error(getMissingAnnotationErrorMessage("`undefined`", path));
case "VoidKeyword":
throw getMissingAnnotationError("`void`");
throw new Error(getMissingAnnotationErrorMessage("`void`", path));
case "NeverKeyword":
throw getMissingAnnotationError("`never`");
throw new Error(getMissingAnnotationErrorMessage("`never`", path));
case "UnknownKeyword":
return {
...unknownJsonSchema,
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -201,3 +215,3 @@ case "AnyKeyword":

...anyJsonSchema,
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -207,3 +221,3 @@ case "ObjectKeyword":

...objectJsonSchema,
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -213,3 +227,3 @@ case "StringKeyword":

type: "string",
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -219,3 +233,3 @@ case "NumberKeyword":

type: "number",
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -225,12 +239,13 @@ case "BooleanKeyword":

type: "boolean",
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};
case "BigIntKeyword":
throw getMissingAnnotationError("`bigint`");
throw new Error(getMissingAnnotationErrorMessage("`bigint`", path));
case "SymbolKeyword":
throw getMissingAnnotationError("`symbol`");
throw new Error(getMissingAnnotationErrorMessage("`symbol`", path));
case "TupleType":
{
const elements = ast.elements.map(e => go(e.type, $defs));
const rest = ast.rest.map(ast => go(ast, $defs));
const len = ast.elements.length;
const elements = ast.elements.map((e, i) => go(e.type, $defs, true, path.concat(i)));
const rest = ast.rest.map(ast => go(ast, $defs, true, path));
const output = {

@@ -242,3 +257,2 @@ type: "array"

// ---------------------------------------------
const len = elements.length;
if (len > 0) {

@@ -262,3 +276,3 @@ output.minItems = len - ast.elements.filter(element => element.isOptional).length;

if (rest.length > 1) {
throw new Error("Generating a JSON Schema for post-rest elements is not currently supported. You're welcome to contribute by submitting a Pull Request.");
throw new Error(errors_.getErrorMessageWithPath("Generating a JSON Schema for post-rest elements is not currently supported. You're welcome to contribute by submitting a Pull Request.", path));
}

@@ -274,3 +288,3 @@ } else {

...output,
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -283,3 +297,3 @@ }

...empty(),
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -294,3 +308,3 @@ }

{
additionalProperties = go(is.type, $defs);
additionalProperties = go(is.type, $defs, true, path);
break;

@@ -301,3 +315,3 @@ }

patternProperties = {
[AST.getTemplateLiteralRegExp(parameter).source]: go(is.type, $defs)
[AST.getTemplateLiteralRegExp(parameter).source]: go(is.type, $defs, true, path)
};

@@ -311,10 +325,10 @@ break;

patternProperties = {
[hook.value.pattern]: go(is.type, $defs)
[hook.value.pattern]: go(is.type, $defs, true, path)
};
break;
}
throw new Error(getUnsupportedIndexSignatureParameterErrorMessage(parameter));
throw new Error(getUnsupportedIndexSignatureParameterErrorMessage(parameter, path));
}
case "SymbolKeyword":
throw new Error(getUnsupportedIndexSignatureParameterErrorMessage(parameter));
throw new Error(getUnsupportedIndexSignatureParameterErrorMessage(parameter, path));
}

@@ -324,4 +338,4 @@ }

return {
...go(pruneUndefinedKeyword(ps), $defs),
...getMeta(ps)
...go(pruneUndefinedKeyword(ps), $defs, true, path.concat(ps.name)),
...getJsonSchemaAnnotations(ps)
};

@@ -349,3 +363,3 @@ });

} else {
throw new Error(`cannot encode ${String(name)} key to JSON Schema`);
throw new Error(errors_.getErrorMessageWithPath(`cannot encode ${String(name)} key to JSON Schema`, path));
}

@@ -364,3 +378,3 @@ }

...output,
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -373,3 +387,3 @@ }

for (const type of ast.types) {
const schema = go(type, $defs);
const schema = go(type, $defs, true, path);
if ("const" in schema) {

@@ -389,3 +403,3 @@ if (Object.keys(schema).length > 1) {

const: enums[0],
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -395,3 +409,3 @@ } else {

enum: enums,
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -411,3 +425,3 @@ }

anyOf,
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -424,3 +438,3 @@ }

})),
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -430,3 +444,3 @@ }

{
throw new Error("cannot build a JSON Schema for a refinement without a JSON Schema annotation");
throw new Error(errors_.getErrorMessageWithPath("cannot build a JSON Schema for a refinement without a JSON Schema annotation", path));
}

@@ -440,3 +454,3 @@ case "TemplateLiteral":

pattern: regex.source,
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -448,10 +462,10 @@ }

if (Option.isNone(identifier)) {
throw new Error("Generating a JSON Schema for suspended schemas requires an identifier annotation");
throw new Error(errors_.getErrorMessageWithPath("Generating a JSON Schema for suspended schemas requires an identifier annotation", path));
}
return go(ast.f(), $defs);
return go(ast.f(), $defs, true, path);
}
case "Transformation":
return go(ast.to, $defs);
return go(ast.from, $defs, true, path);
}
};
//# sourceMappingURL=JSONSchema.js.map

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

exports.validateSync = exports.validatePromise = exports.validateOption = exports.validateEither = exports.validate = exports.try = exports.succeed = exports.parseError = exports.orElse = exports.missing = exports.mergeParseOptions = exports.mapError = exports.mapBoth = exports.map = exports.is = exports.getSearchTree = exports.getLiterals = exports.getFinalTransformation = exports.fromOption = exports.flatMap = exports.fail = exports.encodeUnknownSync = exports.encodeUnknownPromise = exports.encodeUnknownOption = exports.encodeUnknownEither = exports.encodeUnknown = exports.encodeSync = exports.encodePromise = exports.encodeOption = exports.encodeEither = exports.encode = exports.eitherOrUndefined = exports.decodeUnknownSync = exports.decodeUnknownPromise = exports.decodeUnknownOption = exports.decodeUnknownEither = exports.decodeUnknown = exports.decodeSync = exports.decodePromise = exports.decodeOption = exports.decodeEither = exports.decode = exports.asserts = exports.Union = exports.Unexpected = exports.TypeLiteral = exports.Type = exports.TupleType = exports.Transformation = exports.Refinement = exports.ParseError = exports.Missing = exports.Member = exports.Key = exports.Index = exports.Forbidden = exports.Declaration = void 0;
var Array = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Array"));
var Arr = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Array"));
var _Data = /*#__PURE__*/require("effect/Data");

@@ -460,12 +460,12 @@ var Effect = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Effect"));

/** @internal */
const mergeParseOptions = (a, b) => {
if (a === undefined) {
return b;
const mergeParseOptions = (options, overrideOptions) => {
if (overrideOptions === undefined || Predicate.isNumber(overrideOptions)) {
return options;
}
if (b === undefined) {
return a;
if (options === undefined) {
return overrideOptions;
}
const out = {};
out.errors = b.errors ?? a.errors;
out.onExcessProperty = b.onExcessProperty ?? a.onExcessProperty;
out.errors = overrideOptions.errors ?? options.errors;
out.onExcessProperty = overrideOptions.onExcessProperty ?? options.onExcessProperty;
return out;

@@ -480,3 +480,5 @@ };

const parser = getEither(ast, isDecoding, options);
return (input, overrideOptions) => Either.getOrThrowWith(parser(input, overrideOptions), e => new Error(TreeFormatter.formatIssueSync(e)));
return (input, overrideOptions) => Either.getOrThrowWith(parser(input, overrideOptions), issue => new Error(TreeFormatter.formatIssueSync(issue), {
cause: issue
}));
};

@@ -642,3 +644,5 @@ const getOption = (ast, isDecoding, options) => {

if (Either.isLeft(result)) {
throw new Error(TreeFormatter.formatIssueSync(result.left));
throw new Error(TreeFormatter.formatIssueSync(result.left), {
cause: result.left
});
}

@@ -759,3 +763,3 @@ };

return (input, options) => {
if (!Array.isArray(input)) {
if (!Arr.isArray(input)) {
return Either.left(new Type(ast, input));

@@ -850,3 +854,3 @@ }

// ---------------------------------------------
if (Array.isNonEmptyReadonlyArray(rest)) {
if (Arr.isNonEmptyReadonlyArray(rest)) {
const [head, ...tail] = rest;

@@ -948,3 +952,3 @@ for (; i < len - tail.length; i++) {

output
}) => Array.isNonEmptyArray(es) ? Either.left(new TupleType(ast, input, sortByIndex(es), sortByIndex(output))) : Either.right(sortByIndex(output));
}) => Arr.isNonEmptyArray(es) ? Either.left(new TupleType(ast, input, sortByIndex(es), sortByIndex(output))) : Either.right(sortByIndex(output));
if (queue && queue.length > 0) {

@@ -954,4 +958,4 @@ const cqueue = queue;

const state = {
es: Array.copy(es),
output: Array.copy(output)
es: Arr.copy(es),
output: Arr.copy(output)
};

@@ -1145,3 +1149,3 @@ return Effect.flatMap(Effect.forEach(cqueue, f => f(state), {

output
}) => Array.isNonEmptyArray(es) ? Either.left(new TypeLiteral(ast, input, sortByIndex(es), output)) : Either.right(output);
}) => Arr.isNonEmptyArray(es) ? Either.left(new TypeLiteral(ast, input, sortByIndex(es), output)) : Either.right(output);
if (queue && queue.length > 0) {

@@ -1151,3 +1155,3 @@ const cqueue = queue;

const state = {
es: Array.copy(es),
es: Arr.copy(es),
output: Object.assign({}, output)

@@ -1250,3 +1254,3 @@ };

// ---------------------------------------------
const computeResult = es => Array.isNonEmptyArray(es) ? es.length === 1 && es[0][1]._tag === "Type" ? Either.left(es[0][1]) : Either.left(new Union(ast, input, sortByIndex(es))) :
const computeResult = es => Arr.isNonEmptyArray(es) ? es.length === 1 && es[0][1]._tag === "Type" ? Either.left(es[0][1]) : Either.left(new Union(ast, input, sortByIndex(es))) :
// this should never happen

@@ -1258,3 +1262,3 @@ Either.left(new Type(AST.neverKeyword, input));

const state = {
es: Array.copy(es)
es: Arr.copy(es)
};

@@ -1261,0 +1265,0 @@ return Effect.flatMap(Effect.forEach(cqueue, f => f(state), {

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

exports.pretty = exports.match = exports.make = exports.PrettyHookId = void 0;
var Array = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Array"));
var Arr = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Array"));
var Option = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Option"));

@@ -60,3 +60,3 @@ var AST = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./AST.js"));

exports.pretty = pretty;
const make = schema => compile(schema.ast);
const make = schema => compile(schema.ast, []);
exports.make = make;

@@ -71,2 +71,3 @@ const getHook = /*#__PURE__*/AST.getAnnotation(PrettyHookId);

const formatUnknown = /*#__PURE__*/getMatcher(util_.formatUnknown);
const getPrettyErrorMessage = (message, path) => errors_.getErrorMessageWithPath(`cannot build a Pretty for ${message}`, path);
/**

@@ -76,8 +77,8 @@ * @since 1.0.0

const match = exports.match = {
"Declaration": (ast, go) => {
"Declaration": (ast, go, path) => {
const hook = getHook(ast);
if (Option.isSome(hook)) {
return hook.value(...ast.typeParameters.map(go));
return hook.value(...ast.typeParameters.map(tp => go(tp, path)));
}
throw new Error(errors_.getPrettyErrorMessage(`a declaration without annotations (${ast})`));
throw new Error(getPrettyErrorMessage(`a declaration without annotations (${ast})`, path));
},

@@ -101,3 +102,3 @@ "VoidKeyword": /*#__PURE__*/getMatcher(() => "void(0)"),

"Enums": stringify,
"TupleType": (ast, go) => {
"TupleType": (ast, go, path) => {
const hook = getHook(ast);

@@ -107,4 +108,4 @@ if (Option.isSome(hook)) {

}
const elements = ast.elements.map(e => go(e.type));
const rest = ast.rest.map(go);
const elements = ast.elements.map((e, i) => go(e.type, path.concat(i)));
const rest = ast.rest.map(ast => go(ast, path));
return input => {

@@ -128,3 +129,3 @@ const output = [];

// ---------------------------------------------
if (Array.isNonEmptyReadonlyArray(rest)) {
if (Arr.isNonEmptyReadonlyArray(rest)) {
const [head, ...tail] = rest;

@@ -145,3 +146,3 @@ for (; i < input.length - tail.length; i++) {

},
"TypeLiteral": (ast, go) => {
"TypeLiteral": (ast, go, path) => {
const hook = getHook(ast);

@@ -151,4 +152,4 @@ if (Option.isSome(hook)) {

}
const propertySignaturesTypes = ast.propertySignatures.map(f => go(f.type));
const indexSignatureTypes = ast.indexSignatures.map(is => go(is.type));
const propertySignaturesTypes = ast.propertySignatures.map(ps => go(ps.type, path.concat(ps.name)));
const indexSignatureTypes = ast.indexSignatures.map(is => go(is.type, path));
const expectedKeys = {};

@@ -169,3 +170,3 @@ for (let i = 0; i < propertySignaturesTypes.length; i++) {

}
output.push(`${getPrettyPropertyKey(name)}: ${propertySignaturesTypes[i](input[name])}`);
output.push(`${util_.formatPropertyKey(name)}: ${propertySignaturesTypes[i](input[name])}`);
}

@@ -183,10 +184,10 @@ // ---------------------------------------------

}
output.push(`${getPrettyPropertyKey(key)}: ${type(input[key])}`);
output.push(`${util_.formatPropertyKey(key)}: ${type(input[key])}`);
}
}
}
return Array.isNonEmptyReadonlyArray(output) ? "{ " + output.join(", ") + " }" : "{}";
return Arr.isNonEmptyReadonlyArray(output) ? "{ " + output.join(", ") + " }" : "{}";
};
},
"Union": (ast, go) => {
"Union": (ast, go, path) => {
const hook = getHook(ast);

@@ -198,3 +199,3 @@ if (Option.isSome(hook)) {

ast
}), go(ast)]);
}), go(ast, path)]);
return a => {

@@ -205,6 +206,6 @@ const index = types.findIndex(([is]) => is(a));

},
"Suspend": (ast, go) => {
"Suspend": (ast, go, path) => {
return Option.match(getHook(ast), {
onNone: () => {
const get = util_.memoizeThunk(() => go(ast.f()));
const get = util_.memoizeThunk(() => go(ast.f(), path));
return a => get()(a);

@@ -215,11 +216,11 @@ },

},
"Refinement": (ast, go) => {
"Refinement": (ast, go, path) => {
return Option.match(getHook(ast), {
onNone: () => go(ast.from),
onNone: () => go(ast.from, path),
onSome: handler => handler()
});
},
"Transformation": (ast, go) => {
"Transformation": (ast, go, path) => {
return Option.match(getHook(ast), {
onNone: () => go(ast.to),
onNone: () => go(ast.to, path),
onSome: handler => handler()

@@ -230,3 +231,2 @@ });

const compile = /*#__PURE__*/AST.getCompiler(match);
const getPrettyPropertyKey = name => typeof name === "string" ? JSON.stringify(name) : String(name);
//# sourceMappingURL=Pretty.js.map

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

};
const getPrevMessage = issue => {
const getInnerMessage = issue => {
switch (issue._tag) {

@@ -111,3 +111,5 @@ case "Refinement":

case "Transformation":
return getMessage(issue.error);
{
return getMessage(issue.error);
}
}

@@ -118,6 +120,26 @@ return Option.none();

const out = annotation(issue);
return Predicate.isString(out) ? Effect.succeed(out) : out;
return Predicate.isString(out) ? Effect.succeed({
message: out,
override: false
}) : Effect.isEffect(out) ? Effect.map(out, message => ({
message,
override: false
})) : Predicate.isString(out.message) ? Effect.succeed({
message: out.message,
override: out.override
}) : Effect.map(out.message, message => ({
message,
override: out.override
}));
}));
/** @internal */
const getMessage = issue => Effect.catchAll(getPrevMessage(issue), () => getCurrentMessage(issue));
const getMessage = issue => {
const current = getCurrentMessage(issue);
return getInnerMessage(issue).pipe(Effect.flatMap(inner => Effect.map(current, current => current.override ? current.message : inner)), Effect.catchAll(() => Effect.flatMap(current, current => {
if (!current.override && (issue._tag === "Refinement" && issue.kind !== "Predicate" || issue._tag === "Transformation" && issue.kind !== "Transformation")) {
return Option.none();
}
return Effect.succeed(current.message);
})));
};
exports.getMessage = getMessage;

@@ -156,5 +178,5 @@ const getParseIssueTitleAnnotation = issue => Option.filterMap(AST.getParseIssueTitleAnnotation(issue.ast), annotation => Option.fromNullable(annotation(issue)));

case "TupleType":
return getTree(e, () => Effect.map(Effect.forEach(e.errors, index => Effect.map(go(index.error), tree => make(`[${index.index}]`, [tree]))), forest => make(getParseIssueTitle(e), forest)));
return getTree(e, () => Effect.map(Effect.forEach(e.errors, index => Effect.map(go(index.error), tree => make(`[${util_.formatPropertyKey(index.index)}]`, [tree]))), forest => make(getParseIssueTitle(e), forest)));
case "TypeLiteral":
return getTree(e, () => Effect.map(Effect.forEach(e.errors, key => Effect.map(go(key.error), tree => make(`[${util_.formatUnknown(key.key)}]`, [tree]))), forest => make(getParseIssueTitle(e), forest)));
return getTree(e, () => Effect.map(Effect.forEach(e.errors, key => Effect.map(go(key.error), tree => make(`[${util_.formatPropertyKey(key.key)}]`, [tree]))), forest => make(getParseIssueTitle(e), forest)));
case "Transformation":

@@ -161,0 +183,0 @@ return getTree(e, () => Effect.map(go(e.error), tree => make(getParseIssueTitle(e), [make(formatTransformationKind(e.kind), [tree])])));

/**
* @since 1.0.0
*/
import * as Array from "effect/Array";
import * as Effect from "effect/Effect";

@@ -12,3 +11,3 @@ import type * as ParseResult from "./ParseResult.js";

export interface Issue {
readonly _tag: ParseResult.ParseIssue["_tag"] | ParseResult.Missing["_tag"] | ParseResult.Unexpected["_tag"];
readonly _tag: "Transformation" | "Type" | "Declaration" | "Refinement" | "TupleType" | "TypeLiteral" | "Union" | "Forbidden" | "Missing" | "Unexpected";
readonly path: ReadonlyArray<PropertyKey>;

@@ -15,0 +14,0 @@ readonly message: string;

/**
* @since 1.0.0
*/
import * as Array from "effect/Array";
import * as Arr from "effect/Array";
import type { Effect } from "effect/Effect";

@@ -18,3 +18,3 @@ import * as Option from "effect/Option";

*/
export type BrandAnnotation = Array.NonEmptyReadonlyArray<string | symbol>;
export type BrandAnnotation = Arr.NonEmptyReadonlyArray<string | symbol>;
/**

@@ -39,3 +39,6 @@ * @category annotations

*/
export type MessageAnnotation = (issue: ParseIssue) => string | Effect<string>;
export type MessageAnnotation = (issue: ParseIssue) => string | Effect<string> | {
readonly message: string | Effect<string>;
readonly override: boolean;
};
/**

@@ -80,3 +83,3 @@ * @category annotations

*/
export type ExamplesAnnotation<A> = Array.NonEmptyReadonlyArray<A>;
export type ExamplesAnnotation<A> = Arr.NonEmptyReadonlyArray<A>;
/**

@@ -700,3 +703,3 @@ * @category annotations

readonly head: string;
readonly spans: Array.NonEmptyReadonlyArray<TemplateLiteralSpan>;
readonly spans: Arr.NonEmptyReadonlyArray<TemplateLiteralSpan>;
readonly annotations: Annotations;

@@ -1106,3 +1109,3 @@ static make: (head: string, spans: ReadonlyArray<TemplateLiteralSpan>, annotations?: Annotations) => TemplateLiteral | Literal;

*/
export type Compiler<A> = (ast: AST) => A;
export type Compiler<A> = (ast: AST, path: ReadonlyArray<PropertyKey>) => A;
/**

@@ -1114,3 +1117,3 @@ * @since 1.0.0

_tag: K;
}>, compile: Compiler<A>) => A;
}>, compile: Compiler<A>, path: ReadonlyArray<PropertyKey>) => A;
};

@@ -1129,6 +1132,2 @@ /**

export declare const encodedAST: (ast: AST) => AST;
/**
* @since 1.0.0
*/
export declare const hash: (ast: AST) => number;
//# sourceMappingURL=AST.d.ts.map

@@ -10,3 +10,13 @@ /**

*/
export interface JsonSchema7Any {
export interface JsonSchemaAnnotations {
title?: string;
description?: string;
default?: unknown;
examples?: Array<unknown>;
}
/**
* @category model
* @since 1.0.0
*/
export interface JsonSchema7Any extends JsonSchemaAnnotations {
$id: "/schemas/any";

@@ -18,3 +28,3 @@ }

*/
export interface JsonSchema7Unknown {
export interface JsonSchema7Unknown extends JsonSchemaAnnotations {
$id: "/schemas/unknown";

@@ -26,3 +36,3 @@ }

*/
export interface JsonSchema7object {
export interface JsonSchema7object extends JsonSchemaAnnotations {
$id: "/schemas/object";

@@ -42,3 +52,3 @@ oneOf: [

*/
export interface JsonSchema7empty {
export interface JsonSchema7empty extends JsonSchemaAnnotations {
$id: "/schemas/{}";

@@ -58,3 +68,3 @@ oneOf: [

*/
export interface JsonSchema7Ref {
export interface JsonSchema7Ref extends JsonSchemaAnnotations {
$ref: string;

@@ -66,3 +76,3 @@ }

*/
export interface JsonSchema7Const {
export interface JsonSchema7Const extends JsonSchemaAnnotations {
const: AST.LiteralValue;

@@ -74,3 +84,3 @@ }

*/
export interface JsonSchema7String {
export interface JsonSchema7String extends JsonSchemaAnnotations {
type: "string";

@@ -80,3 +90,2 @@ minLength?: number;

pattern?: string;
description?: string;
}

@@ -87,3 +96,3 @@ /**

*/
export interface JsonSchema7Numeric {
export interface JsonSchema7Numeric extends JsonSchemaAnnotations {
minimum?: number;

@@ -112,3 +121,3 @@ exclusiveMinimum?: number;

*/
export interface JsonSchema7Boolean {
export interface JsonSchema7Boolean extends JsonSchemaAnnotations {
type: "boolean";

@@ -120,3 +129,3 @@ }

*/
export interface JsonSchema7Array {
export interface JsonSchema7Array extends JsonSchemaAnnotations {
type: "array";

@@ -132,3 +141,3 @@ items?: JsonSchema7 | Array<JsonSchema7>;

*/
export interface JsonSchema7OneOf {
export interface JsonSchema7OneOf extends JsonSchemaAnnotations {
oneOf: Array<JsonSchema7>;

@@ -140,3 +149,3 @@ }

*/
export interface JsonSchema7Enum {
export interface JsonSchema7Enum extends JsonSchemaAnnotations {
enum: Array<AST.LiteralValue>;

@@ -148,3 +157,3 @@ }

*/
export interface JsonSchema7Enums {
export interface JsonSchema7Enums extends JsonSchemaAnnotations {
$comment: "/schemas/enums";

@@ -160,3 +169,3 @@ oneOf: Array<{

*/
export interface JsonSchema7AnyOf {
export interface JsonSchema7AnyOf extends JsonSchemaAnnotations {
anyOf: Array<JsonSchema7>;

@@ -168,3 +177,3 @@ }

*/
export interface JsonSchema7Object {
export interface JsonSchema7Object extends JsonSchemaAnnotations {
type: "object";

@@ -171,0 +180,0 @@ required: Array<string>;

/**
* @since 1.0.0
*/
import * as Array from "effect/Array";
import * as Arr from "effect/Array";
import * as Effect from "effect/Effect";

@@ -61,3 +61,3 @@ import * as Either from "effect/Either";

readonly actual: unknown;
readonly errors: Array.NonEmptyReadonlyArray<Index>;
readonly errors: Arr.NonEmptyReadonlyArray<Index>;
readonly output: ReadonlyArray<unknown>;

@@ -68,3 +68,3 @@ /**

readonly _tag = "TupleType";
constructor(ast: AST.TupleType, actual: unknown, errors: Array.NonEmptyReadonlyArray<Index>, output?: ReadonlyArray<unknown>);
constructor(ast: AST.TupleType, actual: unknown, errors: Arr.NonEmptyReadonlyArray<Index>, output?: ReadonlyArray<unknown>);
}

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

readonly actual: unknown;
readonly errors: Array.NonEmptyReadonlyArray<Key>;
readonly errors: Arr.NonEmptyReadonlyArray<Key>;
readonly output: {

@@ -104,3 +104,3 @@ readonly [x: string]: unknown;

readonly _tag = "TypeLiteral";
constructor(ast: AST.TypeLiteral, actual: unknown, errors: Array.NonEmptyReadonlyArray<Key>, output?: {
constructor(ast: AST.TypeLiteral, actual: unknown, errors: Arr.NonEmptyReadonlyArray<Key>, output?: {
readonly [x: string]: unknown;

@@ -235,3 +235,3 @@ });

readonly actual: unknown;
readonly errors: Array.NonEmptyReadonlyArray<Type | TypeLiteral | Member>;
readonly errors: Arr.NonEmptyReadonlyArray<Type | TypeLiteral | Member>;
/**

@@ -241,3 +241,3 @@ * @since 1.0.0

readonly _tag = "Union";
constructor(ast: AST.Union, actual: unknown, errors: Array.NonEmptyReadonlyArray<Type | TypeLiteral | Member>);
constructor(ast: AST.Union, actual: unknown, errors: Arr.NonEmptyReadonlyArray<Type | TypeLiteral | Member>);
}

@@ -469,3 +469,3 @@ declare const ParseError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & {

*/
export declare const is: <A, I, R>(schema: Schema.Schema<A, I, R>, options?: AST.ParseOptions) => (u: unknown, overrideOptions?: AST.ParseOptions) => u is A;
export declare const is: <A, I, R>(schema: Schema.Schema<A, I, R>, options?: AST.ParseOptions) => (u: unknown, overrideOptions?: AST.ParseOptions | number) => u is A;
/**

@@ -472,0 +472,0 @@ * @category validation

@@ -46,6 +46,6 @@ /**

*/
export interface WithResult<A, I, E, EI, R> {
export interface WithResult<SuccessA, SuccessI, FailureA, FailureI, SuccessAndFailureR> {
readonly [symbolResult]: {
readonly Success: Schema.Schema<A, I, R>;
readonly Failure: Schema.Schema<E, EI, R>;
readonly Success: Schema.Schema<SuccessA, SuccessI, SuccessAndFailureR>;
readonly Failure: Schema.Schema<FailureA, FailureI, SuccessAndFailureR>;
};

@@ -82,3 +82,3 @@ }

*/
export interface SerializableWithResult<S, SI, SR, A, AI, E, EI, RR> extends Serializable<S, SI, SR>, WithResult<A, AI, E, EI, RR> {
export interface SerializableWithResult<Self, FieldsI, FieldsR, SuccessA, SuccessI, FailureA, FailureI, SuccessAndFailureR> extends Serializable<Self, FieldsI, FieldsR>, WithResult<SuccessA, SuccessI, FailureA, FailureI, SuccessAndFailureR> {
}

@@ -85,0 +85,0 @@ /**

/**
* @since 1.0.0
*/
import * as Array from "effect/Array";
import * as Arr from "effect/Array";
import * as Option from "effect/Option";

@@ -30,3 +30,3 @@ import * as Predicate from "effect/Predicate";

*/
export const makeLazy = schema => go(schema.ast, {});
export const makeLazy = schema => go(schema.ast, {}, []);
/**

@@ -55,3 +55,3 @@ * Returns a fast-check Arbitrary for the `A` type of the provided schema.

const getHook = /*#__PURE__*/AST.getAnnotation(ArbitraryHookId);
const getRefinementFromArbitrary = (ast, options) => {
const getRefinementFromArbitrary = (ast, options, path) => {
const constraints = combineConstraints(options.constraints, getConstraints(ast));

@@ -61,5 +61,6 @@ return go(ast.from, constraints ? {

constraints
} : options);
} : options, path);
};
const go = (ast, options) => {
const getArbitraryErrorMessage = (message, path) => errors_.getErrorMessageWithPath(`cannot build an Arbitrary for ${message}`, path);
const go = (ast, options, path) => {
const hook = getHook(ast);

@@ -69,5 +70,5 @@ if (Option.isSome(hook)) {

case "Declaration":
return hook.value(...ast.typeParameters.map(p => go(p, options)));
return hook.value(...ast.typeParameters.map(p => go(p, options, path)));
case "Refinement":
return hook.value(getRefinementFromArbitrary(ast, options));
return hook.value(getRefinementFromArbitrary(ast, options, path));
default:

@@ -80,3 +81,3 @@ return hook.value();

{
throw new Error(errors_.getArbitraryErrorMessage(`a declaration without annotations (${ast})`));
throw new Error(getArbitraryErrorMessage(`a declaration without annotations (${ast})`, path));
}

@@ -92,3 +93,3 @@ case "Literal":

return () => {
throw new Error(errors_.getArbitraryErrorMessage("`never`"));
throw new Error(getArbitraryErrorMessage("`never`", path));
};

@@ -161,4 +162,5 @@ case "UnknownKeyword":

let hasOptionals = false;
let i = 0;
for (const element of ast.elements) {
elements.push(go(element.type, options));
elements.push(go(element.type, options, path.concat(i++)));
if (element.isOptional) {

@@ -168,3 +170,3 @@ hasOptionals = true;

}
const rest = ast.rest.map(e => go(e, options));
const rest = ast.rest.map(e => go(e, options, path));
return fc => {

@@ -189,3 +191,3 @@ // ---------------------------------------------

// ---------------------------------------------
if (Array.isNonEmptyReadonlyArray(rest)) {
if (Arr.isNonEmptyReadonlyArray(rest)) {
const [head, ...tail] = rest;

@@ -220,4 +222,4 @@ const arb = head(fc);

{
const propertySignaturesTypes = ast.propertySignatures.map(f => go(f.type, options));
const indexSignatures = ast.indexSignatures.map(is => [go(is.parameter, options), go(is.type, options)]);
const propertySignaturesTypes = ast.propertySignatures.map(ps => go(ps.type, options, path.concat(ps.name)));
const indexSignatures = ast.indexSignatures.map(is => [go(is.parameter, options, path), go(is.type, options, path)]);
return fc => {

@@ -258,3 +260,3 @@ const arbs = {};

{
const types = ast.types.map(t => go(t, options));
const types = ast.types.map(t => go(t, options, path));
return fc => fc.oneof({

@@ -267,3 +269,3 @@ depthSize

if (ast.enums.length === 0) {
throw new Error(errors_.getArbitraryErrorMessage("an empty enum"));
throw new Error(getArbitraryErrorMessage("an empty enum", path));
}

@@ -274,3 +276,3 @@ return fc => fc.oneof(...ast.enums.map(([_, value]) => fc.constant(value)));

{
const from = getRefinementFromArbitrary(ast, options);
const from = getRefinementFromArbitrary(ast, options, path);
return fc => from(fc).filter(a => Option.isNone(ast.filter(a, AST.defaultParseOption, ast)));

@@ -283,7 +285,7 @@ }

isSuspend: true
}));
}, path));
return fc => fc.constant(null).chain(() => get()(fc));
}
case "Transformation":
return go(ast.to, options);
return go(ast.to, options, path);
}

@@ -290,0 +292,0 @@ };

/**
* @since 1.0.0
*/
import * as Array from "effect/Array";
import * as Arr from "effect/Array";
import * as Effect from "effect/Effect";

@@ -27,10 +27,12 @@ import * as TreeFormatter from "./TreeFormatter.js";

export const formatErrorSync = error => formatIssueSync(error.error);
const succeed = issue => Effect.succeed([issue]);
const getArray = (issue, path, onFailure) => Effect.matchEffect(TreeFormatter.getMessage(issue), {
onFailure,
onSuccess: message => Effect.succeed([{
onSuccess: message => succeed({
_tag: issue._tag,
path,
message
}])
})
});
const flatten = eff => Effect.map(eff, Arr.flatten);
const go = (e, path = []) => {

@@ -46,21 +48,21 @@ const _tag = e._tag;

case "Forbidden":
return Effect.succeed([{
return succeed({
_tag,
path,
message: TreeFormatter.formatForbiddenMessage(e)
}]);
});
case "Unexpected":
return Effect.succeed([{
return succeed({
_tag,
path,
message: `is unexpected, expected ${e.ast.toString(true)}`
}]);
});
case "Missing":
return Effect.succeed([{
return succeed({
_tag,
path,
message: "is missing"
}]);
});
case "Union":
return getArray(e, path, () => Effect.map(Effect.forEach(e.errors, e => {
return getArray(e, path, () => flatten(Effect.forEach(e.errors, e => {
switch (e._tag) {

@@ -72,10 +74,10 @@ case "Member":

}
}), Array.flatten));
})));
case "TupleType":
return getArray(e, path, () => Effect.map(Effect.forEach(e.errors, index => go(index.error, [...path, index.index])), Array.flatten));
return getArray(e, path, () => flatten(Effect.forEach(e.errors, index => go(index.error, path.concat(index.index)))));
case "TypeLiteral":
return getArray(e, path, () => Effect.map(Effect.forEach(e.errors, key => go(key.error, [...path, key.key])), Array.flatten));
return getArray(e, path, () => flatten(Effect.forEach(e.errors, key => go(key.error, path.concat(key.key)))));
case "Declaration":
case "Refinement":
case "Transformation":
case "Refinement":
case "Declaration":
return getArray(e, path, () => go(e.error, path));

@@ -82,0 +84,0 @@ }

/**
* @since 1.0.0
*/
import * as Array from "effect/Array";
import * as Arr from "effect/Array";
import { dual, identity } from "effect/Function";
import { globalValue } from "effect/GlobalValue";
import * as Hash from "effect/Hash";
import * as Number from "effect/Number";

@@ -812,3 +811,3 @@ import * as Option from "effect/Option";

annotations;
static make = (head, spans, annotations = {}) => Array.isNonEmptyReadonlyArray(spans) ? new TemplateLiteral(head, spans, annotations) : new Literal(head);
static make = (head, spans, annotations = {}) => Arr.isNonEmptyReadonlyArray(spans) ? new TemplateLiteral(head, spans, annotations) : new Literal(head);
/**

@@ -903,3 +902,3 @@ * @since 1.0.0

if (hasIllegalRequiredElement || hasOptionalElement && rest.length > 1) {
throw new Error(errors_.getRequiredElementFollowinAnOptionalElementErrorMessage);
throw new Error(getRequiredElementFollowinAnOptionalElementErrorMessage);
}

@@ -928,3 +927,3 @@ }

const formattedElements = ast.elements.map(String).join(", ");
return Array.matchLeft(ast.rest, {
return Arr.matchLeft(ast.rest, {
onEmpty: () => `readonly [${formattedElements}]`,

@@ -1017,3 +1016,3 @@ onNonEmpty: (head, tail) => {

} else {
throw new Error(errors_.getIndexSignatureParameterErrorMessage);
throw new Error(getIndexSignatureParameterErrorMessage);
}

@@ -1070,3 +1069,3 @@ }

if (parameters.string) {
throw new Error(errors_.getDuplicateIndexSignatureErrorMessage("string"));
throw new Error(getDuplicateIndexSignatureErrorMessage("string"));
}

@@ -1076,3 +1075,3 @@ parameters.string = true;

if (parameters.symbol) {
throw new Error(errors_.getDuplicateIndexSignatureErrorMessage("symbol"));
throw new Error(getDuplicateIndexSignatureErrorMessage("symbol"));
}

@@ -1104,5 +1103,5 @@ parameters.symbol = true;

const formatTypeLiteral = ast => {
const formattedPropertySignatures = ast.propertySignatures.map(ps => String(ps.name) + (ps.isOptional ? "?" : "") + ": " + ps.type).join("; ");
const formattedPropertySignatures = ast.propertySignatures.map(ps => (ps.isReadonly ? "readonly " : "") + String(ps.name) + (ps.isOptional ? "?" : "") + ": " + ps.type).join("; ");
if (ast.indexSignatures.length > 0) {
const formattedIndexSignatures = ast.indexSignatures.map(is => `[x: ${getParameterBase(is.parameter)}]: ${is.type}`).join("; ");
const formattedIndexSignatures = ast.indexSignatures.map(is => (is.isReadonly ? "readonly " : "") + `[x: ${getParameterBase(is.parameter)}]: ${is.type}`).join("; ");
if (ast.propertySignatures.length > 0) {

@@ -1127,3 +1126,3 @@ return `{ ${formattedPropertySignatures}; ${formattedIndexSignatures} }`;

const removeNevers = candidates => candidates.filter(ast => !(ast === neverKeyword));
const sortCandidates = /*#__PURE__*/Array.sort( /*#__PURE__*/Order.mapInput(Number.Order, ast => {
const sortCandidates = /*#__PURE__*/Arr.sort( /*#__PURE__*/Order.mapInput(Number.Order, ast => {
switch (ast._tag) {

@@ -1152,3 +1151,3 @@ case "AnyKeyword":

/** @internal */
export const flatten = candidates => Array.flatMap(candidates, ast => isUnion(ast) ? flatten(ast.types) : [ast]);
export const flatten = candidates => Arr.flatMap(candidates, ast => isUnion(ast) ? flatten(ast.types) : [ast]);
/** @internal */

@@ -1381,3 +1380,3 @@ export const unify = candidates => {

toString(verbose = false) {
return Option.getOrElse(getExpected(this, verbose), () => "<refinement schema>");
return Option.getOrElse(getExpected(this, verbose), () => `{ ${this.from} | filter }`);
}

@@ -1514,2 +1513,3 @@ /**

}
const isRenamingPropertySignatureTransformation = t => t.decode === identity && t.encode === identity;
/**

@@ -1533,3 +1533,3 @@ * @category model

if (fromKeys[from]) {
throw new Error(errors_.getDuplicatePropertySignatureTransformationErrorMessage(from));
throw new Error(getDuplicatePropertySignatureTransformationErrorMessage(from));
}

@@ -1539,3 +1539,3 @@ fromKeys[from] = true;

if (toKeys[to]) {
throw new Error(errors_.getDuplicatePropertySignatureTransformationErrorMessage(to));
throw new Error(getDuplicatePropertySignatureTransformationErrorMessage(to));
}

@@ -1637,3 +1637,3 @@ toKeys[to] = true;

}
throw new Error(errors_.getAPIErrorMessage("NumberIndexedAccess", `unsupported schema (${ast})`));
throw new Error(errors_.getErrorMessage("getNumberIndexedAccess", `unsupported schema (${ast})`));
};

@@ -1653,3 +1653,3 @@ /** @internal */

{
const ops = Array.findFirst(ast.propertySignatures, ps => ps.name === name);
const ops = Arr.findFirst(ast.propertySignatures, ps => ps.name === name);
if (Option.isSome(ops)) {

@@ -1666,3 +1666,3 @@ return ops.value;

if (regex.test(name)) {
return new PropertySignature(name, is.type, false, false);
return new PropertySignature(name, is.type, false, true);
}

@@ -1672,3 +1672,3 @@ break;

case "StringKeyword":
return new PropertySignature(name, is.type, false, false);
return new PropertySignature(name, is.type, false, true);
}

@@ -1680,3 +1680,3 @@ }

if (isSymbolKeyword(parameterBase)) {
return new PropertySignature(name, is.type, false, false);
return new PropertySignature(name, is.type, false, true);
}

@@ -1710,3 +1710,3 @@ }

case "Union":
return ast.types.slice(1).reduce((out, ast) => Array.intersection(out, getPropertyKeys(ast)), getPropertyKeys(ast.types[0]));
return ast.types.slice(1).reduce((out, ast) => Arr.intersection(out, getPropertyKeys(ast)), getPropertyKeys(ast.types[0]));
case "Transformation":

@@ -1735,5 +1735,12 @@ return getPropertyKeys(ast.to);

} else {
throw new Error(errors_.getAPIErrorMessage("Record", `unsupported literal (${util_.formatUnknown(key.literal)})`));
throw new Error(errors_.getErrorMessage("record", `unsupported literal (${util_.formatUnknown(key.literal)})`));
}
break;
case "Enums":
{
for (const [_, name] of key.enums) {
propertySignatures.push(new PropertySignature(name, value, false, true));
}
break;
}
case "UniqueSymbol":

@@ -1746,3 +1753,3 @@ propertySignatures.push(new PropertySignature(key.symbol, value, false, true));

default:
throw new Error(errors_.getAPIErrorMessage("Record", `unsupported key schema (${key})`));
throw new Error(errors_.getErrorMessage("record", `unsupported key schema (${key})`));
}

@@ -1779,3 +1786,3 @@ };

}
return new Transformation(pick(ast.from, fromKeys), pick(ast.to, keys), Array.isNonEmptyReadonlyArray(ts) ? new TypeLiteralTransformation(ts) : composeTransformation);
return Arr.isNonEmptyReadonlyArray(ts) ? new Transformation(pick(ast.from, fromKeys), pick(ast.to, keys), new TypeLiteralTransformation(ts)) : pick(ast.from, fromKeys);
}

@@ -1788,3 +1795,3 @@ case "FinalTransformation":

}
throw new Error(errors_.getAPIErrorMessage("Pick", "cannot handle this kind of transformation"));
throw new Error(errors_.getErrorMessage("pick", "cannot handle this kind of transformation"));
}

@@ -1812,3 +1819,3 @@ }

case "TupleType":
return new TupleType(ast.elements.map(e => new Element(exact ? e.type : orUndefined(e.type), true)), Array.match(ast.rest, {
return new TupleType(ast.elements.map(e => new Element(exact ? e.type : orUndefined(e.type), true)), Arr.match(ast.rest, {
onEmpty: () => ast.rest,

@@ -1824,7 +1831,12 @@ onNonEmpty: rest => [Union.make([...rest, undefinedKeyword])]

case "Declaration":
throw new Error(errors_.getAPIErrorMessage("Partial", "cannot handle declarations"));
throw new Error(errors_.getErrorMessage("partial", "cannot handle declarations"));
case "Refinement":
throw new Error(errors_.getAPIErrorMessage("Partial", "cannot handle refinements"));
throw new Error(errors_.getErrorMessage("partial", "cannot handle refinements"));
case "Transformation":
throw new Error(errors_.getAPIErrorMessage("Partial", "cannot handle transformations"));
{
if (isTypeLiteralTransformation(ast.transformation) && ast.transformation.propertySignatureTransformations.every(isRenamingPropertySignatureTransformation)) {
return new Transformation(partial(ast.from, options), partial(ast.to, options), ast.transformation);
}
throw new Error(errors_.getErrorMessage("partial", "cannot handle transformations"));
}
}

@@ -1849,7 +1861,12 @@ return ast;

case "Declaration":
throw new Error(errors_.getAPIErrorMessage("Required", "cannot handle declarations"));
throw new Error(errors_.getErrorMessage("required", "cannot handle declarations"));
case "Refinement":
throw new Error(errors_.getAPIErrorMessage("Required", "cannot handle refinements"));
throw new Error(errors_.getErrorMessage("required", "cannot handle refinements"));
case "Transformation":
throw new Error(errors_.getAPIErrorMessage("Required", "cannot handle transformations"));
{
if (isTypeLiteralTransformation(ast.transformation) && ast.transformation.propertySignatureTransformations.every(isRenamingPropertySignatureTransformation)) {
return new Transformation(required(ast.from), required(ast.to), ast.transformation);
}
throw new Error(errors_.getErrorMessage("required", "cannot handle transformations"));
}
}

@@ -1900,9 +1917,5 @@ return ast;

export const getCompiler = match => {
const compile = ast => match[ast._tag](ast, compile);
const compile = (ast, path) => match[ast._tag](ast, compile, path);
return compile;
};
/** @internal */
export const getToPropertySignatures = ps => ps.map(p => new PropertySignature(p.name, typeAST(p.type), p.isOptional, p.isReadonly, p.annotations));
/** @internal */
export const getToIndexSignatures = ps => ps.map(is => new IndexSignature(is.parameter, typeAST(is.type), is.isReadonly));
/**

@@ -1966,3 +1979,3 @@ * @since 1.0.0

let changed = false;
const out = Array.allocate(as.length);
const out = Arr.allocate(as.length);
for (let i = 0; i < as.length; i++) {

@@ -2029,6 +2042,2 @@ const a = as[i];

};
/**
* @since 1.0.0
*/
export const hash = ast => Hash.string(JSON.stringify(ast, null, 2));
/** @internal */

@@ -2060,4 +2069,4 @@ export const getCardinality = ast => {

};
const sortPropertySignatures = /*#__PURE__*/Array.sort( /*#__PURE__*/Order.mapInput(Number.Order, ps => getCardinality(ps.type)));
const sortIndexSignatures = /*#__PURE__*/Array.sort( /*#__PURE__*/Order.mapInput(Number.Order, is => {
const sortPropertySignatures = /*#__PURE__*/Arr.sort( /*#__PURE__*/Order.mapInput(Number.Order, ps => getCardinality(ps.type)));
const sortIndexSignatures = /*#__PURE__*/Arr.sort( /*#__PURE__*/Order.mapInput(Number.Order, is => {
switch (getParameterBase(is.parameter)._tag) {

@@ -2129,4 +2138,4 @@ case "StringKeyword":

};
const equalsTemplateLiteralSpan = /*#__PURE__*/Array.getEquivalence((self, that) => self.type._tag === that.type._tag && self.literal === that.literal);
const equalsEnums = /*#__PURE__*/Array.getEquivalence((self, that) => that[0] === self[0] && that[1] === self[1]);
const equalsTemplateLiteralSpan = /*#__PURE__*/Arr.getEquivalence((self, that) => self.type._tag === that.type._tag && self.literal === that.literal);
const equalsEnums = /*#__PURE__*/Arr.getEquivalence((self, that) => that[0] === self[0] && that[1] === self[1]);
const equals = (self, that) => {

@@ -2164,3 +2173,3 @@ switch (self._tag) {

};
const intersection = /*#__PURE__*/Array.intersectionWith(equals);
const intersection = /*#__PURE__*/Arr.intersectionWith(equals);
const _keyof = ast => {

@@ -2185,3 +2194,3 @@ switch (ast._tag) {

}
throw new Error(errors_.getAPIErrorMessage("KeyOf", `unsupported schema (${ast})`));
throw new Error(errors_.getErrorMessage("keyof", `unsupported schema (${ast})`));
};

@@ -2232,2 +2241,6 @@ /** @internal */

};
const getDuplicateIndexSignatureErrorMessage = name => `Duplicate index signature for type \`${name}\``;
const getIndexSignatureParameterErrorMessage = "An index signature parameter type must be `string`, `symbol`, a template literal type or a refinement of the previous types";
const getRequiredElementFollowinAnOptionalElementErrorMessage = "A required element cannot follow an optional element. ts(1257)";
const getDuplicatePropertySignatureTransformationErrorMessage = name => `Duplicate property signature transformation ${util_.formatUnknown(name)}`;
//# sourceMappingURL=AST.js.map
/**
* @since 1.0.0
*/
import * as Array from "effect/Array";
import * as Arr from "effect/Array";
import * as Equal from "effect/Equal";

@@ -29,5 +29,6 @@ import * as Equivalence from "effect/Equivalence";

*/
export const make = schema => go(schema.ast);
export const make = schema => go(schema.ast, []);
const getHook = /*#__PURE__*/AST.getAnnotation(EquivalenceHookId);
const go = ast => {
const getEquivalenceErrorMessage = (message, path) => errors_.getErrorMessageWithPath(`cannot build an Equivalence for ${message}`, path);
const go = (ast, path) => {
const hook = getHook(ast);

@@ -37,5 +38,5 @@ if (Option.isSome(hook)) {

case "Declaration":
return hook.value(...ast.typeParameters.map(go));
return hook.value(...ast.typeParameters.map(tp => go(tp, path)));
case "Refinement":
return hook.value(go(ast.from));
return hook.value(go(ast.from, path));
default:

@@ -47,5 +48,5 @@ return hook.value();

case "NeverKeyword":
throw new Error(errors_.getEquivalenceErrorMessage("`never`"));
throw new Error(getEquivalenceErrorMessage("`never`", path));
case "Transformation":
return go(ast.to);
return go(ast.to, path);
case "Declaration":

@@ -68,6 +69,6 @@ case "Literal":

case "Refinement":
return go(ast.from);
return go(ast.from, path);
case "Suspend":
{
const get = util_.memoizeThunk(() => go(ast.f()));
const get = util_.memoizeThunk(() => go(ast.f(), path));
return (a, b) => get()(a, b);

@@ -77,4 +78,4 @@ }

{
const elements = ast.elements.map(element => go(element.type));
const rest = ast.rest.map(go);
const elements = ast.elements.map((element, i) => go(element.type, path.concat(i)));
const rest = ast.rest.map(ast => go(ast, path));
return Equivalence.make((a, b) => {

@@ -97,3 +98,3 @@ const len = a.length;

// ---------------------------------------------
if (Array.isNonEmptyReadonlyArray(rest)) {
if (Arr.isNonEmptyReadonlyArray(rest)) {
const [head, ...tail] = rest;

@@ -123,4 +124,4 @@ for (; i < len - tail.length; i++) {

}
const propertySignatures = ast.propertySignatures.map(ps => go(ps.type));
const indexSignatures = ast.indexSignatures.map(is => go(is.type));
const propertySignatures = ast.propertySignatures.map(ps => go(ps.type, path.concat(ps.name)));
const indexSignatures = ast.indexSignatures.map(is => go(is.type, path));
return Equivalence.make((a, b) => {

@@ -199,3 +200,3 @@ const aStringKeys = Object.keys(a);

}
const tuples = candidates.map(ast => [go(ast), ParseResult.is({
const tuples = candidates.map(ast => [go(ast, path), ParseResult.is({
ast

@@ -202,0 +203,0 @@ })]);

@@ -5,17 +5,11 @@ import * as util_ from "./util.js";

/** @internal */
export const getDuplicateIndexSignatureErrorMessage = name => `Duplicate index signature for type \`${name}\``;
export const getErrorMessage = (api, message) => `${api}: ${message}`;
/** @internal */
export const getIndexSignatureParameterErrorMessage = "An index signature parameter type must be `string`, `symbol`, a template literal type or a refinement of the previous types";
/** @internal */
export const getRequiredElementFollowinAnOptionalElementErrorMessage = "A required element cannot follow an optional element. ts(1257)";
/** @internal */
export const getDuplicatePropertySignatureTransformationErrorMessage = name => `Duplicate property signature transformation ${util_.formatUnknown(name)}`;
/** @internal */
export const getArbitraryErrorMessage = message => `cannot build an Arbitrary for ${message}`;
/** @internal */
export const getPrettyErrorMessage = message => `cannot build a Pretty for ${message}`;
/** @internal */
export const getEquivalenceErrorMessage = message => `cannot build an Equivalence for ${message}`;
/** @internal */
export const getAPIErrorMessage = (api, message) => `${api}: ${message}`;
export const getErrorMessageWithPath = (message, path) => {
let out = message;
if (path.length > 0) {
out += ` (path [${path.map(util_.formatPropertyKey).join(", ")}])`;
}
return out;
};
//# sourceMappingURL=errors.js.map

@@ -51,2 +51,4 @@ import * as Predicate from "effect/Predicate";

};
/** @internal */
export const formatPropertyKey = name => typeof name === "string" ? JSON.stringify(name) : String(name);
//# sourceMappingURL=util.js.map

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

import * as AST from "./AST.js";
import * as errors_ from "./internal/errors.js";
/**

@@ -15,3 +16,3 @@ * @category encoding

const $defs = {};
const jsonSchema = go(schema.ast, $defs);
const jsonSchema = go(schema.ast, $defs, true, []);
const out = {

@@ -55,3 +56,3 @@ $schema,

const $schema = "http://json-schema.org/draft-07/schema#";
const getMeta = annotated => Record.getSomes({
const getJsonSchemaAnnotations = annotated => Record.getSomes({
description: AST.getDescriptionAnnotation(annotated),

@@ -69,36 +70,49 @@ title: AST.getTitleAnnotation(annotated),

};
const getMissingAnnotationError = name => {
const out = new Error(`cannot build a JSON Schema for ${name} without a JSON Schema annotation`);
out.name = "MissingAnnotation";
return out;
};
const getUnsupportedIndexSignatureParameterErrorMessage = parameter => `Unsupported index signature parameter (${parameter})`;
const getMissingAnnotationErrorMessage = (name, path) => errors_.getErrorMessageWithPath(`cannot build a JSON Schema for ${name} without a JSON Schema annotation`, path);
const getUnsupportedIndexSignatureParameterErrorMessage = (parameter, path) => errors_.getErrorMessageWithPath(`unsupported index signature parameter (${parameter})`, path);
/** @internal */
export const DEFINITION_PREFIX = "#/$defs/";
const get$ref = id => `${DEFINITION_PREFIX}${id}`;
const go = (ast, $defs, handleIdentifier = true) => {
const hasTransformation = ast => {
switch (ast.from._tag) {
case "Transformation":
return true;
case "Refinement":
return hasTransformation(ast.from);
case "Suspend":
{
const from = ast.from.f();
if (AST.isRefinement(from)) {
return hasTransformation(from);
}
}
break;
}
return false;
};
const go = (ast, $defs, handleIdentifier, path) => {
const hook = AST.getJSONSchemaAnnotation(ast);
if (Option.isSome(hook)) {
const handler = hook.value;
switch (ast._tag) {
case "Refinement":
try {
return {
...go(ast.from, $defs),
...getMeta(ast),
...handler
};
} catch (e) {
if (e instanceof Error && e.name === "MissingAnnotation") {
return {
...getMeta(ast),
...handler
};
}
throw e;
}
if (AST.isRefinement(ast) && !hasTransformation(ast)) {
try {
return {
...go(ast.from, $defs, true, path),
...getJsonSchemaAnnotations(ast),
...handler
};
} catch (e) {
return {
...getJsonSchemaAnnotations(ast),
...handler
};
}
}
return handler;
}
if (handleIdentifier) {
const surrogate = AST.getSurrogateAnnotation(ast);
if (Option.isSome(surrogate)) {
return go(surrogate.value, $defs, handleIdentifier, path);
}
if (handleIdentifier && !AST.isTransformation(ast)) {
const identifier = AST.getJSONIdentifier(ast);

@@ -112,3 +126,3 @@ if (Option.isSome(identifier)) {

$defs[id] = out;
$defs[id] = go(ast, $defs, false);
$defs[id] = go(ast, $defs, false, path);
}

@@ -120,3 +134,3 @@ return out;

case "Declaration":
throw getMissingAnnotationError("a declaration");
throw new Error(getMissingAnnotationErrorMessage("a declaration", path));
case "Literal":

@@ -128,3 +142,3 @@ {

const: null,
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -134,3 +148,3 @@ } else if (Predicate.isString(literal)) {

const: literal,
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -140,3 +154,3 @@ } else if (Predicate.isNumber(literal)) {

const: literal,
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -146,19 +160,19 @@ } else if (Predicate.isBoolean(literal)) {

const: literal,
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};
}
throw getMissingAnnotationError("a bigint literal");
throw new Error(getMissingAnnotationErrorMessage("a bigint literal", path));
}
case "UniqueSymbol":
throw getMissingAnnotationError("a unique symbol");
throw new Error(getMissingAnnotationErrorMessage("a unique symbol", path));
case "UndefinedKeyword":
throw getMissingAnnotationError("`undefined`");
throw new Error(getMissingAnnotationErrorMessage("`undefined`", path));
case "VoidKeyword":
throw getMissingAnnotationError("`void`");
throw new Error(getMissingAnnotationErrorMessage("`void`", path));
case "NeverKeyword":
throw getMissingAnnotationError("`never`");
throw new Error(getMissingAnnotationErrorMessage("`never`", path));
case "UnknownKeyword":
return {
...unknownJsonSchema,
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -168,3 +182,3 @@ case "AnyKeyword":

...anyJsonSchema,
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -174,3 +188,3 @@ case "ObjectKeyword":

...objectJsonSchema,
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -180,3 +194,3 @@ case "StringKeyword":

type: "string",
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -186,3 +200,3 @@ case "NumberKeyword":

type: "number",
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -192,12 +206,13 @@ case "BooleanKeyword":

type: "boolean",
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};
case "BigIntKeyword":
throw getMissingAnnotationError("`bigint`");
throw new Error(getMissingAnnotationErrorMessage("`bigint`", path));
case "SymbolKeyword":
throw getMissingAnnotationError("`symbol`");
throw new Error(getMissingAnnotationErrorMessage("`symbol`", path));
case "TupleType":
{
const elements = ast.elements.map(e => go(e.type, $defs));
const rest = ast.rest.map(ast => go(ast, $defs));
const len = ast.elements.length;
const elements = ast.elements.map((e, i) => go(e.type, $defs, true, path.concat(i)));
const rest = ast.rest.map(ast => go(ast, $defs, true, path));
const output = {

@@ -209,3 +224,2 @@ type: "array"

// ---------------------------------------------
const len = elements.length;
if (len > 0) {

@@ -229,3 +243,3 @@ output.minItems = len - ast.elements.filter(element => element.isOptional).length;

if (rest.length > 1) {
throw new Error("Generating a JSON Schema for post-rest elements is not currently supported. You're welcome to contribute by submitting a Pull Request.");
throw new Error(errors_.getErrorMessageWithPath("Generating a JSON Schema for post-rest elements is not currently supported. You're welcome to contribute by submitting a Pull Request.", path));
}

@@ -241,3 +255,3 @@ } else {

...output,
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -250,3 +264,3 @@ }

...empty(),
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -261,3 +275,3 @@ }

{
additionalProperties = go(is.type, $defs);
additionalProperties = go(is.type, $defs, true, path);
break;

@@ -268,3 +282,3 @@ }

patternProperties = {
[AST.getTemplateLiteralRegExp(parameter).source]: go(is.type, $defs)
[AST.getTemplateLiteralRegExp(parameter).source]: go(is.type, $defs, true, path)
};

@@ -278,10 +292,10 @@ break;

patternProperties = {
[hook.value.pattern]: go(is.type, $defs)
[hook.value.pattern]: go(is.type, $defs, true, path)
};
break;
}
throw new Error(getUnsupportedIndexSignatureParameterErrorMessage(parameter));
throw new Error(getUnsupportedIndexSignatureParameterErrorMessage(parameter, path));
}
case "SymbolKeyword":
throw new Error(getUnsupportedIndexSignatureParameterErrorMessage(parameter));
throw new Error(getUnsupportedIndexSignatureParameterErrorMessage(parameter, path));
}

@@ -291,4 +305,4 @@ }

return {
...go(pruneUndefinedKeyword(ps), $defs),
...getMeta(ps)
...go(pruneUndefinedKeyword(ps), $defs, true, path.concat(ps.name)),
...getJsonSchemaAnnotations(ps)
};

@@ -316,3 +330,3 @@ });

} else {
throw new Error(`cannot encode ${String(name)} key to JSON Schema`);
throw new Error(errors_.getErrorMessageWithPath(`cannot encode ${String(name)} key to JSON Schema`, path));
}

@@ -331,3 +345,3 @@ }

...output,
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -340,3 +354,3 @@ }

for (const type of ast.types) {
const schema = go(type, $defs);
const schema = go(type, $defs, true, path);
if ("const" in schema) {

@@ -356,3 +370,3 @@ if (Object.keys(schema).length > 1) {

const: enums[0],
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -362,3 +376,3 @@ } else {

enum: enums,
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -378,3 +392,3 @@ }

anyOf,
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -391,3 +405,3 @@ }

})),
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -397,3 +411,3 @@ }

{
throw new Error("cannot build a JSON Schema for a refinement without a JSON Schema annotation");
throw new Error(errors_.getErrorMessageWithPath("cannot build a JSON Schema for a refinement without a JSON Schema annotation", path));
}

@@ -407,3 +421,3 @@ case "TemplateLiteral":

pattern: regex.source,
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
};

@@ -415,10 +429,10 @@ }

if (Option.isNone(identifier)) {
throw new Error("Generating a JSON Schema for suspended schemas requires an identifier annotation");
throw new Error(errors_.getErrorMessageWithPath("Generating a JSON Schema for suspended schemas requires an identifier annotation", path));
}
return go(ast.f(), $defs);
return go(ast.f(), $defs, true, path);
}
case "Transformation":
return go(ast.to, $defs);
return go(ast.from, $defs, true, path);
}
};
//# sourceMappingURL=JSONSchema.js.map
/**
* @since 1.0.0
*/
import * as Array from "effect/Array";
import * as Arr from "effect/Array";
import { TaggedError } from "effect/Data";

@@ -417,12 +417,12 @@ import * as Effect from "effect/Effect";

/** @internal */
export const mergeParseOptions = (a, b) => {
if (a === undefined) {
return b;
export const mergeParseOptions = (options, overrideOptions) => {
if (overrideOptions === undefined || Predicate.isNumber(overrideOptions)) {
return options;
}
if (b === undefined) {
return a;
if (options === undefined) {
return overrideOptions;
}
const out = {};
out.errors = b.errors ?? a.errors;
out.onExcessProperty = b.onExcessProperty ?? a.onExcessProperty;
out.errors = overrideOptions.errors ?? options.errors;
out.onExcessProperty = overrideOptions.onExcessProperty ?? options.onExcessProperty;
return out;

@@ -436,3 +436,5 @@ };

const parser = getEither(ast, isDecoding, options);
return (input, overrideOptions) => Either.getOrThrowWith(parser(input, overrideOptions), e => new Error(TreeFormatter.formatIssueSync(e)));
return (input, overrideOptions) => Either.getOrThrowWith(parser(input, overrideOptions), issue => new Error(TreeFormatter.formatIssueSync(issue), {
cause: issue
}));
};

@@ -582,3 +584,5 @@ const getOption = (ast, isDecoding, options) => {

if (Either.isLeft(result)) {
throw new Error(TreeFormatter.formatIssueSync(result.left));
throw new Error(TreeFormatter.formatIssueSync(result.left), {
cause: result.left
});
}

@@ -698,3 +702,3 @@ };

return (input, options) => {
if (!Array.isArray(input)) {
if (!Arr.isArray(input)) {
return Either.left(new Type(ast, input));

@@ -789,3 +793,3 @@ }

// ---------------------------------------------
if (Array.isNonEmptyReadonlyArray(rest)) {
if (Arr.isNonEmptyReadonlyArray(rest)) {
const [head, ...tail] = rest;

@@ -887,3 +891,3 @@ for (; i < len - tail.length; i++) {

output
}) => Array.isNonEmptyArray(es) ? Either.left(new TupleType(ast, input, sortByIndex(es), sortByIndex(output))) : Either.right(sortByIndex(output));
}) => Arr.isNonEmptyArray(es) ? Either.left(new TupleType(ast, input, sortByIndex(es), sortByIndex(output))) : Either.right(sortByIndex(output));
if (queue && queue.length > 0) {

@@ -893,4 +897,4 @@ const cqueue = queue;

const state = {
es: Array.copy(es),
output: Array.copy(output)
es: Arr.copy(es),
output: Arr.copy(output)
};

@@ -1084,3 +1088,3 @@ return Effect.flatMap(Effect.forEach(cqueue, f => f(state), {

output
}) => Array.isNonEmptyArray(es) ? Either.left(new TypeLiteral(ast, input, sortByIndex(es), output)) : Either.right(output);
}) => Arr.isNonEmptyArray(es) ? Either.left(new TypeLiteral(ast, input, sortByIndex(es), output)) : Either.right(output);
if (queue && queue.length > 0) {

@@ -1090,3 +1094,3 @@ const cqueue = queue;

const state = {
es: Array.copy(es),
es: Arr.copy(es),
output: Object.assign({}, output)

@@ -1189,3 +1193,3 @@ };

// ---------------------------------------------
const computeResult = es => Array.isNonEmptyArray(es) ? es.length === 1 && es[0][1]._tag === "Type" ? Either.left(es[0][1]) : Either.left(new Union(ast, input, sortByIndex(es))) :
const computeResult = es => Arr.isNonEmptyArray(es) ? es.length === 1 && es[0][1]._tag === "Type" ? Either.left(es[0][1]) : Either.left(new Union(ast, input, sortByIndex(es))) :
// this should never happen

@@ -1197,3 +1201,3 @@ Either.left(new Type(AST.neverKeyword, input));

const state = {
es: Array.copy(es)
es: Arr.copy(es)
};

@@ -1200,0 +1204,0 @@ return Effect.flatMap(Effect.forEach(cqueue, f => f(state), {

/**
* @since 1.0.0
*/
import * as Array from "effect/Array";
import * as Arr from "effect/Array";
import * as Option from "effect/Option";

@@ -26,3 +26,3 @@ import * as AST from "./AST.js";

*/
export const make = schema => compile(schema.ast);
export const make = schema => compile(schema.ast, []);
const getHook = /*#__PURE__*/AST.getAnnotation(PrettyHookId);

@@ -36,2 +36,3 @@ const getMatcher = defaultPretty => ast => Option.match(getHook(ast), {

const formatUnknown = /*#__PURE__*/getMatcher(util_.formatUnknown);
const getPrettyErrorMessage = (message, path) => errors_.getErrorMessageWithPath(`cannot build a Pretty for ${message}`, path);
/**

@@ -41,8 +42,8 @@ * @since 1.0.0

export const match = {
"Declaration": (ast, go) => {
"Declaration": (ast, go, path) => {
const hook = getHook(ast);
if (Option.isSome(hook)) {
return hook.value(...ast.typeParameters.map(go));
return hook.value(...ast.typeParameters.map(tp => go(tp, path)));
}
throw new Error(errors_.getPrettyErrorMessage(`a declaration without annotations (${ast})`));
throw new Error(getPrettyErrorMessage(`a declaration without annotations (${ast})`, path));
},

@@ -66,3 +67,3 @@ "VoidKeyword": /*#__PURE__*/getMatcher(() => "void(0)"),

"Enums": stringify,
"TupleType": (ast, go) => {
"TupleType": (ast, go, path) => {
const hook = getHook(ast);

@@ -72,4 +73,4 @@ if (Option.isSome(hook)) {

}
const elements = ast.elements.map(e => go(e.type));
const rest = ast.rest.map(go);
const elements = ast.elements.map((e, i) => go(e.type, path.concat(i)));
const rest = ast.rest.map(ast => go(ast, path));
return input => {

@@ -93,3 +94,3 @@ const output = [];

// ---------------------------------------------
if (Array.isNonEmptyReadonlyArray(rest)) {
if (Arr.isNonEmptyReadonlyArray(rest)) {
const [head, ...tail] = rest;

@@ -110,3 +111,3 @@ for (; i < input.length - tail.length; i++) {

},
"TypeLiteral": (ast, go) => {
"TypeLiteral": (ast, go, path) => {
const hook = getHook(ast);

@@ -116,4 +117,4 @@ if (Option.isSome(hook)) {

}
const propertySignaturesTypes = ast.propertySignatures.map(f => go(f.type));
const indexSignatureTypes = ast.indexSignatures.map(is => go(is.type));
const propertySignaturesTypes = ast.propertySignatures.map(ps => go(ps.type, path.concat(ps.name)));
const indexSignatureTypes = ast.indexSignatures.map(is => go(is.type, path));
const expectedKeys = {};

@@ -134,3 +135,3 @@ for (let i = 0; i < propertySignaturesTypes.length; i++) {

}
output.push(`${getPrettyPropertyKey(name)}: ${propertySignaturesTypes[i](input[name])}`);
output.push(`${util_.formatPropertyKey(name)}: ${propertySignaturesTypes[i](input[name])}`);
}

@@ -148,10 +149,10 @@ // ---------------------------------------------

}
output.push(`${getPrettyPropertyKey(key)}: ${type(input[key])}`);
output.push(`${util_.formatPropertyKey(key)}: ${type(input[key])}`);
}
}
}
return Array.isNonEmptyReadonlyArray(output) ? "{ " + output.join(", ") + " }" : "{}";
return Arr.isNonEmptyReadonlyArray(output) ? "{ " + output.join(", ") + " }" : "{}";
};
},
"Union": (ast, go) => {
"Union": (ast, go, path) => {
const hook = getHook(ast);

@@ -163,3 +164,3 @@ if (Option.isSome(hook)) {

ast
}), go(ast)]);
}), go(ast, path)]);
return a => {

@@ -170,6 +171,6 @@ const index = types.findIndex(([is]) => is(a));

},
"Suspend": (ast, go) => {
"Suspend": (ast, go, path) => {
return Option.match(getHook(ast), {
onNone: () => {
const get = util_.memoizeThunk(() => go(ast.f()));
const get = util_.memoizeThunk(() => go(ast.f(), path));
return a => get()(a);

@@ -180,11 +181,11 @@ },

},
"Refinement": (ast, go) => {
"Refinement": (ast, go, path) => {
return Option.match(getHook(ast), {
onNone: () => go(ast.from),
onNone: () => go(ast.from, path),
onSome: handler => handler()
});
},
"Transformation": (ast, go) => {
"Transformation": (ast, go, path) => {
return Option.match(getHook(ast), {
onNone: () => go(ast.to),
onNone: () => go(ast.to, path),
onSome: handler => handler()

@@ -195,3 +196,2 @@ });

const compile = /*#__PURE__*/AST.getCompiler(match);
const getPrettyPropertyKey = name => typeof name === "string" ? JSON.stringify(name) : String(name);
//# sourceMappingURL=Pretty.js.map

@@ -64,3 +64,3 @@ /**

};
const getPrevMessage = issue => {
const getInnerMessage = issue => {
switch (issue._tag) {

@@ -75,3 +75,5 @@ case "Refinement":

case "Transformation":
return getMessage(issue.error);
{
return getMessage(issue.error);
}
}

@@ -82,6 +84,26 @@ return Option.none();

const out = annotation(issue);
return Predicate.isString(out) ? Effect.succeed(out) : out;
return Predicate.isString(out) ? Effect.succeed({
message: out,
override: false
}) : Effect.isEffect(out) ? Effect.map(out, message => ({
message,
override: false
})) : Predicate.isString(out.message) ? Effect.succeed({
message: out.message,
override: out.override
}) : Effect.map(out.message, message => ({
message,
override: out.override
}));
}));
/** @internal */
export const getMessage = issue => Effect.catchAll(getPrevMessage(issue), () => getCurrentMessage(issue));
export const getMessage = issue => {
const current = getCurrentMessage(issue);
return getInnerMessage(issue).pipe(Effect.flatMap(inner => Effect.map(current, current => current.override ? current.message : inner)), Effect.catchAll(() => Effect.flatMap(current, current => {
if (!current.override && (issue._tag === "Refinement" && issue.kind !== "Predicate" || issue._tag === "Transformation" && issue.kind !== "Transformation")) {
return Option.none();
}
return Effect.succeed(current.message);
})));
};
const getParseIssueTitleAnnotation = issue => Option.filterMap(AST.getParseIssueTitleAnnotation(issue.ast), annotation => Option.fromNullable(annotation(issue)));

@@ -117,5 +139,5 @@ /** @internal */

case "TupleType":
return getTree(e, () => Effect.map(Effect.forEach(e.errors, index => Effect.map(go(index.error), tree => make(`[${index.index}]`, [tree]))), forest => make(getParseIssueTitle(e), forest)));
return getTree(e, () => Effect.map(Effect.forEach(e.errors, index => Effect.map(go(index.error), tree => make(`[${util_.formatPropertyKey(index.index)}]`, [tree]))), forest => make(getParseIssueTitle(e), forest)));
case "TypeLiteral":
return getTree(e, () => Effect.map(Effect.forEach(e.errors, key => Effect.map(go(key.error), tree => make(`[${util_.formatUnknown(key.key)}]`, [tree]))), forest => make(getParseIssueTitle(e), forest)));
return getTree(e, () => Effect.map(Effect.forEach(e.errors, key => Effect.map(go(key.error), tree => make(`[${util_.formatPropertyKey(key.key)}]`, [tree]))), forest => make(getParseIssueTitle(e), forest)));
case "Transformation":

@@ -122,0 +144,0 @@ return getTree(e, () => Effect.map(go(e.error), tree => make(getParseIssueTitle(e), [make(formatTransformationKind(e.kind), [tree])])));

{
"name": "@effect/schema",
"version": "0.0.0-snapshot-78b767c2b1625186e17131761a0edbac25d21850",
"version": "0.0.0-snapshot-79dc882eafd6ddb60780764e2f663a6087b52622",
"description": "Modeling the schema of data structures as first-class values",

@@ -8,10 +8,15 @@ "license": "MIT",

"type": "git",
"url": "https://github.com/effect-ts/effect.git",
"url": "https://github.com/Effect-TS/effect.git",
"directory": "packages/schema"
},
"sideEffects": [],
"dependencies": {
"fast-check": "^3.17.2"
},
"peerDependencies": {
"fast-check": "^3.13.2",
"effect": "^0.0.0-snapshot-78b767c2b1625186e17131761a0edbac25d21850"
"effect": "^0.0.0-snapshot-79dc882eafd6ddb60780764e2f663a6087b52622"
},
"publishConfig": {
"provenance": true
},
"main": "./dist/cjs/index.js",

@@ -18,0 +23,0 @@ "module": "./dist/esm/index.js",

@@ -5,3 +5,3 @@ /**

import * as Array from "effect/Array"
import * as Arr from "effect/Array"
import * as Option from "effect/Option"

@@ -50,3 +50,3 @@ import * as Predicate from "effect/Predicate"

*/
export const makeLazy = <A, I, R>(schema: Schema.Schema<A, I, R>): LazyArbitrary<A> => go(schema.ast, {})
export const makeLazy = <A, I, R>(schema: Schema.Schema<A, I, R>): LazyArbitrary<A> => go(schema.ast, {}, [])

@@ -93,8 +93,11 @@ /**

const getRefinementFromArbitrary = (ast: AST.Refinement, options: Options) => {
const getRefinementFromArbitrary = (ast: AST.Refinement, options: Options, path: ReadonlyArray<PropertyKey>) => {
const constraints = combineConstraints(options.constraints, getConstraints(ast))
return go(ast.from, constraints ? { ...options, constraints } : options)
return go(ast.from, constraints ? { ...options, constraints } : options, path)
}
const go = (ast: AST.AST, options: Options): LazyArbitrary<any> => {
const getArbitraryErrorMessage = (message: string, path: ReadonlyArray<PropertyKey>) =>
errors_.getErrorMessageWithPath(`cannot build an Arbitrary for ${message}`, path)
const go = (ast: AST.AST, options: Options, path: ReadonlyArray<PropertyKey>): LazyArbitrary<any> => {
const hook = getHook(ast)

@@ -104,5 +107,5 @@ if (Option.isSome(hook)) {

case "Declaration":
return hook.value(...ast.typeParameters.map((p) => go(p, options)))
return hook.value(...ast.typeParameters.map((p) => go(p, options, path)))
case "Refinement":
return hook.value(getRefinementFromArbitrary(ast, options))
return hook.value(getRefinementFromArbitrary(ast, options, path))
default:

@@ -114,3 +117,3 @@ return hook.value()

case "Declaration": {
throw new Error(errors_.getArbitraryErrorMessage(`a declaration without annotations (${ast})`))
throw new Error(getArbitraryErrorMessage(`a declaration without annotations (${ast})`, path))
}

@@ -126,3 +129,3 @@ case "Literal":

return () => {
throw new Error(errors_.getArbitraryErrorMessage("`never`"))
throw new Error(getArbitraryErrorMessage("`never`", path))
}

@@ -189,4 +192,5 @@ case "UnknownKeyword":

let hasOptionals = false
let i = 0
for (const element of ast.elements) {
elements.push(go(element.type, options))
elements.push(go(element.type, options, path.concat(i++)))
if (element.isOptional) {

@@ -196,3 +200,3 @@ hasOptionals = true

}
const rest = ast.rest.map((e) => go(e, options))
const rest = ast.rest.map((e) => go(e, options, path))
return (fc) => {

@@ -222,3 +226,3 @@ // ---------------------------------------------

// ---------------------------------------------
if (Array.isNonEmptyReadonlyArray(rest)) {
if (Arr.isNonEmptyReadonlyArray(rest)) {
const [head, ...tail] = rest

@@ -252,5 +256,5 @@ const arb = head(fc)

case "TypeLiteral": {
const propertySignaturesTypes = ast.propertySignatures.map((f) => go(f.type, options))
const propertySignaturesTypes = ast.propertySignatures.map((ps) => go(ps.type, options, path.concat(ps.name)))
const indexSignatures = ast.indexSignatures.map((is) =>
[go(is.parameter, options), go(is.type, options)] as const
[go(is.parameter, options, path), go(is.type, options, path)] as const
)

@@ -287,3 +291,3 @@ return (fc) => {

case "Union": {
const types = ast.types.map((t) => go(t, options))
const types = ast.types.map((t) => go(t, options, path))
return (fc) => fc.oneof({ depthSize }, ...types.map((arb) => arb(fc)))

@@ -293,3 +297,3 @@ }

if (ast.enums.length === 0) {
throw new Error(errors_.getArbitraryErrorMessage("an empty enum"))
throw new Error(getArbitraryErrorMessage("an empty enum", path))
}

@@ -299,11 +303,11 @@ return (fc) => fc.oneof(...ast.enums.map(([_, value]) => fc.constant(value)))

case "Refinement": {
const from = getRefinementFromArbitrary(ast, options)
const from = getRefinementFromArbitrary(ast, options, path)
return (fc) => from(fc).filter((a) => Option.isNone(ast.filter(a, AST.defaultParseOption, ast)))
}
case "Suspend": {
const get = util_.memoizeThunk(() => go(ast.f(), { ...options, isSuspend: true }))
const get = util_.memoizeThunk(() => go(ast.f(), { ...options, isSuspend: true }, path))
return (fc) => fc.constant(null).chain(() => get()(fc))
}
case "Transformation":
return go(ast.to, options)
return go(ast.to, options, path)
}

@@ -310,0 +314,0 @@ }

@@ -5,3 +5,3 @@ /**

import * as Array from "effect/Array"
import * as Arr from "effect/Array"
import * as Effect from "effect/Effect"

@@ -16,3 +16,13 @@ import type * as ParseResult from "./ParseResult.js"

export interface Issue {
readonly _tag: ParseResult.ParseIssue["_tag"] | ParseResult.Missing["_tag"] | ParseResult.Unexpected["_tag"]
readonly _tag:
| "Transformation"
| "Type"
| "Declaration"
| "Refinement"
| "TupleType"
| "TypeLiteral"
| "Union"
| "Forbidden"
| "Missing"
| "Unexpected"
readonly path: ReadonlyArray<PropertyKey>

@@ -46,2 +56,4 @@ readonly message: string

const succeed = (issue: Issue) => Effect.succeed([issue])
const getArray = (

@@ -54,5 +66,7 @@ issue: ParseResult.ParseIssue,

onFailure,
onSuccess: (message) => Effect.succeed<Array<Issue>>([{ _tag: issue._tag, path, message }])
onSuccess: (message) => succeed({ _tag: issue._tag, path, message })
})
const flatten = (eff: Effect.Effect<Array<Array<Issue>>>): Effect.Effect<Array<Issue>> => Effect.map(eff, Arr.flatten)
const go = (

@@ -67,10 +81,10 @@ e: ParseResult.ParseIssue | ParseResult.Missing | ParseResult.Unexpected,

case "Forbidden":
return Effect.succeed([{ _tag, path, message: TreeFormatter.formatForbiddenMessage(e) }])
return succeed({ _tag, path, message: TreeFormatter.formatForbiddenMessage(e) })
case "Unexpected":
return Effect.succeed([{ _tag, path, message: `is unexpected, expected ${e.ast.toString(true)}` }])
return succeed({ _tag, path, message: `is unexpected, expected ${e.ast.toString(true)}` })
case "Missing":
return Effect.succeed([{ _tag, path, message: "is missing" }])
return succeed({ _tag, path, message: "is missing" })
case "Union":
return getArray(e, path, () =>
Effect.map(
flatten(
Effect.forEach(e.errors, (e) => {

@@ -83,22 +97,21 @@ switch (e._tag) {

}
}),
Array.flatten
})
))
case "TupleType":
return getArray(e, path, () =>
Effect.map(
Effect.forEach(e.errors, (index) => go(index.error, [...path, index.index])),
Array.flatten
))
return getArray(
e,
path,
() => flatten(Effect.forEach(e.errors, (index) => go(index.error, path.concat(index.index))))
)
case "TypeLiteral":
return getArray(e, path, () =>
Effect.map(
Effect.forEach(e.errors, (key) => go(key.error, [...path, key.key])),
Array.flatten
))
return getArray(
e,
path,
() => flatten(Effect.forEach(e.errors, (key) => go(key.error, path.concat(key.key))))
)
case "Declaration":
case "Refinement":
case "Transformation":
case "Refinement":
case "Declaration":
return getArray(e, path, () => go(e.error, path))
}
}

@@ -5,3 +5,3 @@ /**

import * as Array from "effect/Array"
import * as Arr from "effect/Array"
import * as Equal from "effect/Equal"

@@ -41,3 +41,3 @@ import * as Equivalence from "effect/Equivalence"

*/
export const make = <A, I, R>(schema: Schema.Schema<A, I, R>): Equivalence.Equivalence<A> => go(schema.ast)
export const make = <A, I, R>(schema: Schema.Schema<A, I, R>): Equivalence.Equivalence<A> => go(schema.ast, [])

@@ -50,3 +50,6 @@ const getHook = AST.getAnnotation<

const go = (ast: AST.AST): Equivalence.Equivalence<any> => {
const getEquivalenceErrorMessage = (message: string, path: ReadonlyArray<PropertyKey>) =>
errors_.getErrorMessageWithPath(`cannot build an Equivalence for ${message}`, path)
const go = (ast: AST.AST, path: ReadonlyArray<PropertyKey>): Equivalence.Equivalence<any> => {
const hook = getHook(ast)

@@ -56,5 +59,5 @@ if (Option.isSome(hook)) {

case "Declaration":
return hook.value(...ast.typeParameters.map(go))
return hook.value(...ast.typeParameters.map((tp) => go(tp, path)))
case "Refinement":
return hook.value(go(ast.from))
return hook.value(go(ast.from, path))
default:

@@ -66,5 +69,5 @@ return hook.value()

case "NeverKeyword":
throw new Error(errors_.getEquivalenceErrorMessage("`never`"))
throw new Error(getEquivalenceErrorMessage("`never`", path))
case "Transformation":
return go(ast.to)
return go(ast.to, path)
case "Declaration":

@@ -87,10 +90,10 @@ case "Literal":

case "Refinement":
return go(ast.from)
return go(ast.from, path)
case "Suspend": {
const get = util_.memoizeThunk(() => go(ast.f()))
const get = util_.memoizeThunk(() => go(ast.f(), path))
return (a, b) => get()(a, b)
}
case "TupleType": {
const elements = ast.elements.map((element) => go(element.type))
const rest = ast.rest.map(go)
const elements = ast.elements.map((element, i) => go(element.type, path.concat(i)))
const rest = ast.rest.map((ast) => go(ast, path))
return Equivalence.make((a, b) => {

@@ -113,3 +116,3 @@ const len = a.length

// ---------------------------------------------
if (Array.isNonEmptyReadonlyArray(rest)) {
if (Arr.isNonEmptyReadonlyArray(rest)) {
const [head, ...tail] = rest

@@ -138,4 +141,4 @@ for (; i < len - tail.length; i++) {

}
const propertySignatures = ast.propertySignatures.map((ps) => go(ps.type))
const indexSignatures = ast.indexSignatures.map((is) => go(is.type))
const propertySignatures = ast.propertySignatures.map((ps) => go(ps.type, path.concat(ps.name)))
const indexSignatures = ast.indexSignatures.map((is) => go(is.type, path))
return Equivalence.make((a, b) => {

@@ -215,3 +218,3 @@ const aStringKeys = Object.keys(a)

}
const tuples = candidates.map((ast) => [go(ast), ParseResult.is({ ast } as any)] as const)
const tuples = candidates.map((ast) => [go(ast, path), ParseResult.is({ ast } as any)] as const)
for (let i = 0; i < tuples.length; i++) {

@@ -218,0 +221,0 @@ const [equivalence, is] = tuples[i]

@@ -8,27 +8,11 @@ import * as util_ from "./util.js"

/** @internal */
export const getDuplicateIndexSignatureErrorMessage = (name: "string" | "symbol"): string =>
`Duplicate index signature for type \`${name}\``
export const getErrorMessage = (api: string, message: string) => `${api}: ${message}`
/** @internal */
export const getIndexSignatureParameterErrorMessage =
"An index signature parameter type must be `string`, `symbol`, a template literal type or a refinement of the previous types"
/** @internal */
export const getRequiredElementFollowinAnOptionalElementErrorMessage =
"A required element cannot follow an optional element. ts(1257)"
/** @internal */
export const getDuplicatePropertySignatureTransformationErrorMessage = (name: PropertyKey): string =>
`Duplicate property signature transformation ${util_.formatUnknown(name)}`
/** @internal */
export const getArbitraryErrorMessage = (message: string) => `cannot build an Arbitrary for ${message}`
/** @internal */
export const getPrettyErrorMessage = (message: string) => `cannot build a Pretty for ${message}`
/** @internal */
export const getEquivalenceErrorMessage = (message: string) => `cannot build an Equivalence for ${message}`
/** @internal */
export const getAPIErrorMessage = (api: string, message: string) => `${api}: ${message}`
export const getErrorMessageWithPath = (message: string, path: ReadonlyArray<PropertyKey>) => {
let out = message
if (path.length > 0) {
out += ` (path [${path.map(util_.formatPropertyKey).join(", ")}])`
}
return out
}

@@ -75,1 +75,5 @@ import * as Predicate from "effect/Predicate"

}
/** @internal */
export const formatPropertyKey = (name: PropertyKey): string =>
typeof name === "string" ? JSON.stringify(name) : String(name)

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

import * as AST from "./AST.js"
import * as errors_ from "./internal/errors.js"
import type * as Schema from "./Schema.js"

@@ -16,3 +17,14 @@

*/
export interface JsonSchema7Any {
export interface JsonSchemaAnnotations {
title?: string
description?: string
default?: unknown
examples?: Array<unknown>
}
/**
* @category model
* @since 1.0.0
*/
export interface JsonSchema7Any extends JsonSchemaAnnotations {
$id: "/schemas/any"

@@ -25,3 +37,3 @@ }

*/
export interface JsonSchema7Unknown {
export interface JsonSchema7Unknown extends JsonSchemaAnnotations {
$id: "/schemas/unknown"

@@ -34,3 +46,3 @@ }

*/
export interface JsonSchema7object {
export interface JsonSchema7object extends JsonSchemaAnnotations {
$id: "/schemas/object"

@@ -47,3 +59,3 @@ oneOf: [

*/
export interface JsonSchema7empty {
export interface JsonSchema7empty extends JsonSchemaAnnotations {
$id: "/schemas/{}"

@@ -60,3 +72,3 @@ oneOf: [

*/
export interface JsonSchema7Ref {
export interface JsonSchema7Ref extends JsonSchemaAnnotations {
$ref: string

@@ -69,3 +81,3 @@ }

*/
export interface JsonSchema7Const {
export interface JsonSchema7Const extends JsonSchemaAnnotations {
const: AST.LiteralValue

@@ -78,3 +90,3 @@ }

*/
export interface JsonSchema7String {
export interface JsonSchema7String extends JsonSchemaAnnotations {
type: "string"

@@ -84,3 +96,2 @@ minLength?: number

pattern?: string
description?: string
}

@@ -92,3 +103,3 @@

*/
export interface JsonSchema7Numeric {
export interface JsonSchema7Numeric extends JsonSchemaAnnotations {
minimum?: number

@@ -120,3 +131,3 @@ exclusiveMinimum?: number

*/
export interface JsonSchema7Boolean {
export interface JsonSchema7Boolean extends JsonSchemaAnnotations {
type: "boolean"

@@ -129,3 +140,3 @@ }

*/
export interface JsonSchema7Array {
export interface JsonSchema7Array extends JsonSchemaAnnotations {
type: "array"

@@ -142,3 +153,3 @@ items?: JsonSchema7 | Array<JsonSchema7>

*/
export interface JsonSchema7OneOf {
export interface JsonSchema7OneOf extends JsonSchemaAnnotations {
oneOf: Array<JsonSchema7>

@@ -151,3 +162,3 @@ }

*/
export interface JsonSchema7Enum {
export interface JsonSchema7Enum extends JsonSchemaAnnotations {
enum: Array<AST.LiteralValue>

@@ -160,3 +171,3 @@ }

*/
export interface JsonSchema7Enums {
export interface JsonSchema7Enums extends JsonSchemaAnnotations {
$comment: "/schemas/enums"

@@ -173,3 +184,3 @@ oneOf: Array<{

*/
export interface JsonSchema7AnyOf {
export interface JsonSchema7AnyOf extends JsonSchemaAnnotations {
anyOf: Array<JsonSchema7>

@@ -182,3 +193,3 @@ }

*/
export interface JsonSchema7Object {
export interface JsonSchema7Object extends JsonSchemaAnnotations {
type: "object"

@@ -228,3 +239,3 @@ required: Array<string>

const $defs: Record<string, any> = {}
const jsonSchema = go(schema.ast, $defs)
const jsonSchema = go(schema.ast, $defs, true, [])
const out: JsonSchema7Root = {

@@ -268,3 +279,3 @@ $schema,

const getMeta = (annotated: AST.Annotated) =>
const getJsonSchemaAnnotations = (annotated: AST.Annotated): JsonSchemaAnnotations =>
Record.getSomes({

@@ -285,10 +296,9 @@ description: AST.getDescriptionAnnotation(annotated),

const getMissingAnnotationError = (name: string) => {
const out = new Error(`cannot build a JSON Schema for ${name} without a JSON Schema annotation`)
out.name = "MissingAnnotation"
return out
}
const getMissingAnnotationErrorMessage = (name: string, path: ReadonlyArray<PropertyKey>): string =>
errors_.getErrorMessageWithPath(`cannot build a JSON Schema for ${name} without a JSON Schema annotation`, path)
const getUnsupportedIndexSignatureParameterErrorMessage = (parameter: AST.AST): string =>
`Unsupported index signature parameter (${parameter})`
const getUnsupportedIndexSignatureParameterErrorMessage = (
parameter: AST.AST,
path: ReadonlyArray<PropertyKey>
): string => errors_.getErrorMessageWithPath(`unsupported index signature parameter (${parameter})`, path)

@@ -300,20 +310,43 @@ /** @internal */

const go = (ast: AST.AST, $defs: Record<string, JsonSchema7>, handleIdentifier: boolean = true): JsonSchema7 => {
const hasTransformation = (ast: AST.Refinement): boolean => {
switch (ast.from._tag) {
case "Transformation":
return true
case "Refinement":
return hasTransformation(ast.from)
case "Suspend":
{
const from = ast.from.f()
if (AST.isRefinement(from)) {
return hasTransformation(from)
}
}
break
}
return false
}
const go = (
ast: AST.AST,
$defs: Record<string, JsonSchema7>,
handleIdentifier: boolean,
path: ReadonlyArray<PropertyKey>
): JsonSchema7 => {
const hook = AST.getJSONSchemaAnnotation(ast)
if (Option.isSome(hook)) {
const handler = hook.value as JsonSchema7
switch (ast._tag) {
case "Refinement":
try {
return { ...go(ast.from, $defs), ...getMeta(ast), ...handler }
} catch (e) {
if (e instanceof Error && e.name === "MissingAnnotation") {
return { ...getMeta(ast), ...handler }
}
throw e
}
if (AST.isRefinement(ast) && !hasTransformation(ast)) {
try {
return { ...go(ast.from, $defs, true, path), ...getJsonSchemaAnnotations(ast), ...handler }
} catch (e) {
return { ...getJsonSchemaAnnotations(ast), ...handler }
}
}
return handler
}
if (handleIdentifier) {
const surrogate = AST.getSurrogateAnnotation(ast)
if (Option.isSome(surrogate)) {
return go(surrogate.value, $defs, handleIdentifier, path)
}
if (handleIdentifier && !AST.isTransformation(ast)) {
const identifier = AST.getJSONIdentifier(ast)

@@ -325,3 +358,3 @@ if (Option.isSome(identifier)) {

$defs[id] = out
$defs[id] = go(ast, $defs, false)
$defs[id] = go(ast, $defs, false, path)
}

@@ -333,43 +366,44 @@ return out

case "Declaration":
throw getMissingAnnotationError("a declaration")
throw new Error(getMissingAnnotationErrorMessage("a declaration", path))
case "Literal": {
const literal = ast.literal
if (literal === null) {
return { const: null, ...getMeta(ast) }
return { const: null, ...getJsonSchemaAnnotations(ast) }
} else if (Predicate.isString(literal)) {
return { const: literal, ...getMeta(ast) }
return { const: literal, ...getJsonSchemaAnnotations(ast) }
} else if (Predicate.isNumber(literal)) {
return { const: literal, ...getMeta(ast) }
return { const: literal, ...getJsonSchemaAnnotations(ast) }
} else if (Predicate.isBoolean(literal)) {
return { const: literal, ...getMeta(ast) }
return { const: literal, ...getJsonSchemaAnnotations(ast) }
}
throw getMissingAnnotationError("a bigint literal")
throw new Error(getMissingAnnotationErrorMessage("a bigint literal", path))
}
case "UniqueSymbol":
throw getMissingAnnotationError("a unique symbol")
throw new Error(getMissingAnnotationErrorMessage("a unique symbol", path))
case "UndefinedKeyword":
throw getMissingAnnotationError("`undefined`")
throw new Error(getMissingAnnotationErrorMessage("`undefined`", path))
case "VoidKeyword":
throw getMissingAnnotationError("`void`")
throw new Error(getMissingAnnotationErrorMessage("`void`", path))
case "NeverKeyword":
throw getMissingAnnotationError("`never`")
throw new Error(getMissingAnnotationErrorMessage("`never`", path))
case "UnknownKeyword":
return { ...unknownJsonSchema, ...getMeta(ast) }
return { ...unknownJsonSchema, ...getJsonSchemaAnnotations(ast) }
case "AnyKeyword":
return { ...anyJsonSchema, ...getMeta(ast) }
return { ...anyJsonSchema, ...getJsonSchemaAnnotations(ast) }
case "ObjectKeyword":
return { ...objectJsonSchema, ...getMeta(ast) }
return { ...objectJsonSchema, ...getJsonSchemaAnnotations(ast) }
case "StringKeyword":
return { type: "string", ...getMeta(ast) }
return { type: "string", ...getJsonSchemaAnnotations(ast) }
case "NumberKeyword":
return { type: "number", ...getMeta(ast) }
return { type: "number", ...getJsonSchemaAnnotations(ast) }
case "BooleanKeyword":
return { type: "boolean", ...getMeta(ast) }
return { type: "boolean", ...getJsonSchemaAnnotations(ast) }
case "BigIntKeyword":
throw getMissingAnnotationError("`bigint`")
throw new Error(getMissingAnnotationErrorMessage("`bigint`", path))
case "SymbolKeyword":
throw getMissingAnnotationError("`symbol`")
throw new Error(getMissingAnnotationErrorMessage("`symbol`", path))
case "TupleType": {
const elements = ast.elements.map((e) => go(e.type, $defs))
const rest = ast.rest.map((ast) => go(ast, $defs))
const len = ast.elements.length
const elements = ast.elements.map((e, i) => go(e.type, $defs, true, path.concat(i)))
const rest = ast.rest.map((ast) => go(ast, $defs, true, path))
const output: JsonSchema7Array = { type: "array" }

@@ -379,3 +413,2 @@ // ---------------------------------------------

// ---------------------------------------------
const len = elements.length
if (len > 0) {

@@ -401,3 +434,6 @@ output.minItems = len - ast.elements.filter((element) => element.isOptional).length

throw new Error(
"Generating a JSON Schema for post-rest elements is not currently supported. You're welcome to contribute by submitting a Pull Request."
errors_.getErrorMessageWithPath(
"Generating a JSON Schema for post-rest elements is not currently supported. You're welcome to contribute by submitting a Pull Request.",
path
)
)

@@ -413,7 +449,7 @@ }

return { ...output, ...getMeta(ast) }
return { ...output, ...getJsonSchemaAnnotations(ast) }
}
case "TypeLiteral": {
if (ast.propertySignatures.length === 0 && ast.indexSignatures.length === 0) {
return { ...empty(), ...getMeta(ast) }
return { ...empty(), ...getJsonSchemaAnnotations(ast) }
}

@@ -426,3 +462,3 @@ let additionalProperties: JsonSchema7 | undefined = undefined

case "StringKeyword": {
additionalProperties = go(is.type, $defs)
additionalProperties = go(is.type, $defs, true, path)
break

@@ -432,6 +468,3 @@ }

patternProperties = {
[AST.getTemplateLiteralRegExp(parameter).source]: go(
is.type,
$defs
)
[AST.getTemplateLiteralRegExp(parameter).source]: go(is.type, $defs, true, path)
}

@@ -447,17 +480,17 @@ break

patternProperties = {
[hook.value.pattern]: go(
is.type,
$defs
)
[hook.value.pattern]: go(is.type, $defs, true, path)
}
break
}
throw new Error(getUnsupportedIndexSignatureParameterErrorMessage(parameter))
throw new Error(getUnsupportedIndexSignatureParameterErrorMessage(parameter, path))
}
case "SymbolKeyword":
throw new Error(getUnsupportedIndexSignatureParameterErrorMessage(parameter))
throw new Error(getUnsupportedIndexSignatureParameterErrorMessage(parameter, path))
}
}
const propertySignatures = ast.propertySignatures.map((ps) => {
return { ...go(pruneUndefinedKeyword(ps), $defs), ...getMeta(ps) }
return {
...go(pruneUndefinedKeyword(ps), $defs, true, path.concat(ps.name)),
...getJsonSchemaAnnotations(ps)
}
})

@@ -484,3 +517,3 @@ const output: JsonSchema7Object = {

} else {
throw new Error(`cannot encode ${String(name)} key to JSON Schema`)
throw new Error(errors_.getErrorMessageWithPath(`cannot encode ${String(name)} key to JSON Schema`, path))
}

@@ -498,3 +531,3 @@ }

return { ...output, ...getMeta(ast) }
return { ...output, ...getJsonSchemaAnnotations(ast) }
}

@@ -505,3 +538,3 @@ case "Union": {

for (const type of ast.types) {
const schema = go(type, $defs)
const schema = go(type, $defs, true, path)
if ("const" in schema) {

@@ -519,5 +552,5 @@ if (Object.keys(schema).length > 1) {

if (enums.length === 1) {
return { const: enums[0], ...getMeta(ast) }
return { const: enums[0], ...getJsonSchemaAnnotations(ast) }
} else {
return { enum: enums, ...getMeta(ast) }
return { enum: enums, ...getJsonSchemaAnnotations(ast) }
}

@@ -530,3 +563,3 @@ } else {

}
return { anyOf, ...getMeta(ast) }
return { anyOf, ...getJsonSchemaAnnotations(ast) }
}

@@ -538,7 +571,12 @@ }

oneOf: ast.enums.map((e) => ({ title: e[0], const: e[1] })),
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
}
}
case "Refinement": {
throw new Error("cannot build a JSON Schema for a refinement without a JSON Schema annotation")
throw new Error(
errors_.getErrorMessageWithPath(
"cannot build a JSON Schema for a refinement without a JSON Schema annotation",
path
)
)
}

@@ -551,3 +589,3 @@ case "TemplateLiteral": {

pattern: regex.source,
...getMeta(ast)
...getJsonSchemaAnnotations(ast)
}

@@ -559,10 +597,13 @@ }

throw new Error(
"Generating a JSON Schema for suspended schemas requires an identifier annotation"
errors_.getErrorMessageWithPath(
"Generating a JSON Schema for suspended schemas requires an identifier annotation",
path
)
)
}
return go(ast.f(), $defs)
return go(ast.f(), $defs, true, path)
}
case "Transformation":
return go(ast.to, $defs)
return go(ast.from, $defs, true, path)
}
}

@@ -5,3 +5,3 @@ /**

import * as Array from "effect/Array"
import * as Arr from "effect/Array"
import { TaggedError } from "effect/Data"

@@ -85,3 +85,3 @@ import * as Effect from "effect/Effect"

readonly actual: unknown,
readonly errors: Array.NonEmptyReadonlyArray<Index>,
readonly errors: Arr.NonEmptyReadonlyArray<Index>,
readonly output: ReadonlyArray<unknown> = []

@@ -119,3 +119,3 @@ ) {}

readonly actual: unknown,
readonly errors: Array.NonEmptyReadonlyArray<Key>,
readonly errors: Arr.NonEmptyReadonlyArray<Key>,
readonly output: { readonly [x: string]: unknown } = {}

@@ -260,3 +260,3 @@ ) {}

readonly actual: unknown,
readonly errors: Array.NonEmptyReadonlyArray<Type | TypeLiteral | Member>
readonly errors: Arr.NonEmptyReadonlyArray<Type | TypeLiteral | Member>
) {}

@@ -478,14 +478,14 @@ }

export const mergeParseOptions = (
a: AST.ParseOptions | undefined,
b: AST.ParseOptions | undefined
options: AST.ParseOptions | undefined,
overrideOptions: AST.ParseOptions | number | undefined
): AST.ParseOptions | undefined => {
if (a === undefined) {
return b
if (overrideOptions === undefined || Predicate.isNumber(overrideOptions)) {
return options
}
if (b === undefined) {
return a
if (options === undefined) {
return overrideOptions
}
const out: Mutable<AST.ParseOptions> = {}
out.errors = b.errors ?? a.errors
out.onExcessProperty = b.onExcessProperty ?? a.onExcessProperty
out.errors = overrideOptions.errors ?? options.errors
out.onExcessProperty = overrideOptions.onExcessProperty ?? options.onExcessProperty
return out

@@ -503,3 +503,6 @@ }

return (input: unknown, overrideOptions?: AST.ParseOptions) =>
Either.getOrThrowWith(parser(input, overrideOptions), (e) => new Error(TreeFormatter.formatIssueSync(e)))
Either.getOrThrowWith(
parser(input, overrideOptions),
(issue) => new Error(TreeFormatter.formatIssueSync(issue), { cause: issue })
)
}

@@ -721,3 +724,3 @@

const parser = goMemo(AST.typeAST(schema.ast), true)
return (u: unknown, overrideOptions?: AST.ParseOptions): u is A =>
return (u: unknown, overrideOptions?: AST.ParseOptions | number): u is A =>
Either.isRight(parser(u, { ...mergeParseOptions(options, overrideOptions), isExact: true }) as any)

@@ -738,3 +741,3 @@ }

if (Either.isLeft(result)) {
throw new Error(TreeFormatter.formatIssueSync(result.left))
throw new Error(TreeFormatter.formatIssueSync(result.left), { cause: result.left })
}

@@ -936,3 +939,3 @@ }

return (input: unknown, options) => {
if (!Array.isArray(input)) {
if (!Arr.isArray(input)) {
return Either.left(new Type(ast, input))

@@ -1035,3 +1038,3 @@ }

// ---------------------------------------------
if (Array.isNonEmptyReadonlyArray(rest)) {
if (Arr.isNonEmptyReadonlyArray(rest)) {
const [head, ...tail] = rest

@@ -1132,3 +1135,3 @@ for (; i < len - tail.length; i++) {

const computeResult = ({ es, output }: State) =>
Array.isNonEmptyArray(es) ?
Arr.isNonEmptyArray(es) ?
Either.left(new TupleType(ast, input, sortByIndex(es), sortByIndex(output))) :

@@ -1140,4 +1143,4 @@ Either.right(sortByIndex(output))

const state: State = {
es: Array.copy(es),
output: Array.copy(output)
es: Arr.copy(es),
output: Arr.copy(output)
}

@@ -1354,3 +1357,3 @@ return Effect.flatMap(

const computeResult = ({ es, output }: State) =>
Array.isNonEmptyArray(es) ?
Arr.isNonEmptyArray(es) ?
Either.left(new TypeLiteral(ast, input, sortByIndex(es), output)) :

@@ -1362,3 +1365,3 @@ Either.right(output)

const state: State = {
es: Array.copy(es),
es: Arr.copy(es),
output: Object.assign({}, output)

@@ -1488,3 +1491,3 @@ }

const computeResult = (es: State["es"]) =>
Array.isNonEmptyArray(es) ?
Arr.isNonEmptyArray(es) ?
es.length === 1 && es[0][1]._tag === "Type" ?

@@ -1499,3 +1502,3 @@ Either.left(es[0][1]) :

return Effect.suspend(() => {
const state: State = { es: Array.copy(es) }
const state: State = { es: Arr.copy(es) }
return Effect.flatMap(

@@ -1649,4 +1652,4 @@ Effect.forEach(cqueue, (f) => f(state), { concurrency, batching, discard: true }),

function sortByIndex<T>(
es: Array.NonEmptyArray<[number, T]>
): Array.NonEmptyArray<T>
es: Arr.NonEmptyArray<[number, T]>
): Arr.NonEmptyArray<T>
function sortByIndex<T>(es: Array<[number, T]>): Array<T>

@@ -1653,0 +1656,0 @@ function sortByIndex(es: Array<[number, any]>): any {

/**
* @since 1.0.0
*/
import * as Array from "effect/Array"
import * as Arr from "effect/Array"
import * as Option from "effect/Option"

@@ -44,3 +44,3 @@ import * as AST from "./AST.js"

*/
export const make = <A, I, R>(schema: Schema.Schema<A, I, R>): (a: A) => string => compile(schema.ast)
export const make = <A, I, R>(schema: Schema.Schema<A, I, R>): (a: A) => string => compile(schema.ast, [])

@@ -63,2 +63,5 @@ const getHook = AST.getAnnotation<(...args: ReadonlyArray<Pretty<any>>) => Pretty<any>>(

const getPrettyErrorMessage = (message: string, path: ReadonlyArray<PropertyKey>) =>
errors_.getErrorMessageWithPath(`cannot build a Pretty for ${message}`, path)
/**

@@ -68,8 +71,8 @@ * @since 1.0.0

export const match: AST.Match<Pretty<any>> = {
"Declaration": (ast, go) => {
"Declaration": (ast, go, path) => {
const hook = getHook(ast)
if (Option.isSome(hook)) {
return hook.value(...ast.typeParameters.map(go))
return hook.value(...ast.typeParameters.map((tp) => go(tp, path)))
}
throw new Error(errors_.getPrettyErrorMessage(`a declaration without annotations (${ast})`))
throw new Error(getPrettyErrorMessage(`a declaration without annotations (${ast})`, path))
},

@@ -97,3 +100,3 @@ "VoidKeyword": getMatcher(() => "void(0)"),

"Enums": stringify,
"TupleType": (ast, go) => {
"TupleType": (ast, go, path) => {
const hook = getHook(ast)

@@ -103,4 +106,4 @@ if (Option.isSome(hook)) {

}
const elements = ast.elements.map((e) => go(e.type))
const rest = ast.rest.map(go)
const elements = ast.elements.map((e, i) => go(e.type, path.concat(i)))
const rest = ast.rest.map((ast) => go(ast, path))
return (input: ReadonlyArray<unknown>) => {

@@ -124,3 +127,3 @@ const output: Array<string> = []

// ---------------------------------------------
if (Array.isNonEmptyReadonlyArray(rest)) {
if (Arr.isNonEmptyReadonlyArray(rest)) {
const [head, ...tail] = rest

@@ -142,3 +145,3 @@ for (; i < input.length - tail.length; i++) {

},
"TypeLiteral": (ast, go) => {
"TypeLiteral": (ast, go, path) => {
const hook = getHook(ast)

@@ -148,4 +151,4 @@ if (Option.isSome(hook)) {

}
const propertySignaturesTypes = ast.propertySignatures.map((f) => go(f.type))
const indexSignatureTypes = ast.indexSignatures.map((is) => go(is.type))
const propertySignaturesTypes = ast.propertySignatures.map((ps) => go(ps.type, path.concat(ps.name)))
const indexSignatureTypes = ast.indexSignatures.map((is) => go(is.type, path))
const expectedKeys: any = {}

@@ -167,3 +170,3 @@ for (let i = 0; i < propertySignaturesTypes.length; i++) {

output.push(
`${getPrettyPropertyKey(name)}: ${propertySignaturesTypes[i](input[name])}`
`${util_.formatPropertyKey(name)}: ${propertySignaturesTypes[i](input[name])}`
)

@@ -182,3 +185,3 @@ }

}
output.push(`${getPrettyPropertyKey(key)}: ${type(input[key])}`)
output.push(`${util_.formatPropertyKey(key)}: ${type(input[key])}`)
}

@@ -188,6 +191,6 @@ }

return Array.isNonEmptyReadonlyArray(output) ? "{ " + output.join(", ") + " }" : "{}"
return Arr.isNonEmptyReadonlyArray(output) ? "{ " + output.join(", ") + " }" : "{}"
}
},
"Union": (ast, go) => {
"Union": (ast, go, path) => {
const hook = getHook(ast)

@@ -197,3 +200,3 @@ if (Option.isSome(hook)) {

}
const types = ast.types.map((ast) => [ParseResult.is({ ast } as any), go(ast)] as const)
const types = ast.types.map((ast) => [ParseResult.is({ ast } as any), go(ast, path)] as const)
return (a) => {

@@ -204,6 +207,6 @@ const index = types.findIndex(([is]) => is(a))

},
"Suspend": (ast, go) => {
"Suspend": (ast, go, path) => {
return Option.match(getHook(ast), {
onNone: () => {
const get = util_.memoizeThunk(() => go(ast.f()))
const get = util_.memoizeThunk(() => go(ast.f(), path))
return (a) => get()(a)

@@ -214,11 +217,11 @@ },

},
"Refinement": (ast, go) => {
"Refinement": (ast, go, path) => {
return Option.match(getHook(ast), {
onNone: () => go(ast.from),
onNone: () => go(ast.from, path),
onSome: (handler) => handler()
})
},
"Transformation": (ast, go) => {
"Transformation": (ast, go, path) => {
return Option.match(getHook(ast), {
onNone: () => go(ast.to),
onNone: () => go(ast.to, path),
onSome: (handler) => handler()

@@ -230,4 +233,1 @@ })

const compile = AST.getCompiler(match)
const getPrettyPropertyKey = (name: PropertyKey): string =>
typeof name === "string" ? JSON.stringify(name) : String(name)

@@ -55,6 +55,6 @@ /**

*/
export interface WithResult<A, I, E, EI, R> {
export interface WithResult<SuccessA, SuccessI, FailureA, FailureI, SuccessAndFailureR> {
readonly [symbolResult]: {
readonly Success: Schema.Schema<A, I, R>
readonly Failure: Schema.Schema<E, EI, R>
readonly Success: Schema.Schema<SuccessA, SuccessI, SuccessAndFailureR>
readonly Failure: Schema.Schema<FailureA, FailureI, SuccessAndFailureR>
}

@@ -118,4 +118,14 @@ }

*/
export interface SerializableWithResult<S, SI, SR, A, AI, E, EI, RR>
extends Serializable<S, SI, SR>, WithResult<A, AI, E, EI, RR>
export interface SerializableWithResult<
Self,
FieldsI,
FieldsR,
SuccessA,
SuccessI,
FailureA,
FailureI,
SuccessAndFailureR
> extends
Serializable<Self, FieldsI, FieldsR>,
WithResult<SuccessA, SuccessI, FailureA, FailureI, SuccessAndFailureR>
{}

@@ -122,0 +132,0 @@

@@ -85,3 +85,3 @@ /**

const getPrevMessage = (
const getInnerMessage = (
issue: ParseResult.ParseIssue

@@ -96,4 +96,5 @@ ): Effect.Effect<string, Cause.NoSuchElementException> => {

}
case "Transformation":
case "Transformation": {
return getMessage(issue.error)
}
}

@@ -105,6 +106,14 @@ return Option.none()

issue: ParseResult.ParseIssue
) => Effect.Effect<string, Cause.NoSuchElementException> = (issue: ParseResult.ParseIssue) =>
) => Effect.Effect<{ message: string; override: boolean }, Cause.NoSuchElementException> = (
issue: ParseResult.ParseIssue
) =>
AST.getMessageAnnotation(issue.ast).pipe(Effect.flatMap((annotation) => {
const out = annotation(issue)
return Predicate.isString(out) ? Effect.succeed(out) : out
return Predicate.isString(out)
? Effect.succeed({ message: out, override: false })
: Effect.isEffect(out)
? Effect.map(out, (message) => ({ message, override: false }))
: Predicate.isString(out.message)
? Effect.succeed({ message: out.message, override: out.override })
: Effect.map(out.message, (message) => ({ message, override: out.override }))
}))

@@ -115,4 +124,21 @@

issue: ParseResult.ParseIssue
) => Effect.Effect<string, Cause.NoSuchElementException> = (issue: ParseResult.ParseIssue) =>
Effect.catchAll(getPrevMessage(issue), () => getCurrentMessage(issue))
) => Effect.Effect<string, Cause.NoSuchElementException> = (issue: ParseResult.ParseIssue) => {
const current = getCurrentMessage(issue)
return getInnerMessage(issue).pipe(
Effect.flatMap((inner) => Effect.map(current, (current) => current.override ? current.message : inner)),
Effect.catchAll(() =>
Effect.flatMap(current, (current) => {
if (
!current.override && (
(issue._tag === "Refinement" && issue.kind !== "Predicate") ||
(issue._tag === "Transformation" && issue.kind !== "Transformation")
)
) {
return Option.none()
}
return Effect.succeed(current.message)
})
)
)
}

@@ -174,3 +200,3 @@ const getParseIssueTitleAnnotation = (issue: ParseResult.ParseIssue): Option.Option<string> =>

e.errors,
(index) => Effect.map(go(index.error), (tree) => make(`[${index.index}]`, [tree]))
(index) => Effect.map(go(index.error), (tree) => make(`[${util_.formatPropertyKey(index.index)}]`, [tree]))
),

@@ -183,3 +209,3 @@ (forest) => make(getParseIssueTitle(e), forest)

Effect.forEach(e.errors, (key) =>
Effect.map(go(key.error), (tree) => make(`[${util_.formatUnknown(key.key)}]`, [tree]))),
Effect.map(go(key.error), (tree) => make(`[${util_.formatPropertyKey(key.key)}]`, [tree]))),
(forest) =>

@@ -186,0 +212,0 @@ make(getParseIssueTitle(e), forest)

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 too big to display

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 too big to display

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 too big to display

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 too big to display

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 too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

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