schemas/libraries/superstruct/download_compiled/index/unminified.js
schemas/libraries/superstruct/download_compiled/index/unminified.js
schemas/libraries/superstruct/download_compiled/index/unminified.js
schemas/libraries/superstruct/download_compiled/index/unminified.js
var StructError = class extends TypeError {
constructor(failure, failures) {
let cached;
const {
message,
explanation,
...rest
} = failure;
const { path } = failure;
const msg =
path.length === 0
? message
: `At path: ${path.join(".")} -- ${message}`;
super(explanation ?? msg);
if (explanation != null)
this.cause = msg;
Object.assign(this, rest);
this.name = this.constructor.name;
this.failures = () => {
return (
cached ??
(cached = [
failure,
...failures(),
])
);
};
}
};
function isIterable(x) {
return (
isObject(x) &&
typeof x[Symbol.iterator] ===
"function"
);
}
function isObject(x) {
return (
typeof x === "object" && x != null
);
}
function isNonArrayObject(x) {
return (
isObject(x) && !Array.isArray(x)
);
}
function print(value) {
if (typeof value === "symbol")
return value.toString();
return typeof value === "string"
? JSON.stringify(value)
: `${value}`;
}
function shiftIterator(input) {
const { done, value } = input.next();
return done ? void 0 : value;
}
function toFailure(
result,
context,
struct,
value,
) {
if (result === true) return;
else if (result === false)
result = {};
else if (typeof result === "string")
result = { message: result };
const { path, branch } = context;
const { type } = struct;
const {
refinement,
message = `Expected a value of type \`${type}\`${refinement ? ` with refinement \`${refinement}\`` : ""}, but received: \`${print(value)}\``,
} = result;
return {
value,
type,
refinement,
key: path[path.length - 1],
path,
branch,
...result,
message,
};
}
function* toFailures(
result,
context,
struct,
value,
) {
if (!isIterable(result))
result = [result];
for (const r of result) {
const failure = toFailure(
r,
context,
struct,
value,
);
if (failure) yield failure;
}
}
function* run(
value,
struct,
options = {},
) {
const {
path = [],
branch = [value],
coerce = false,
mask = false,
} = options;
const ctx = {
path,
branch,
mask,
};
if (coerce)
value = struct.coercer(value, ctx);
let status = "valid";
for (const failure of struct.validator(
value,
ctx,
)) {
failure.explanation =
options.message;
status = "not_valid";
yield [failure, void 0];
}
for (let [k, v, s] of struct.entries(
value,
ctx,
)) {
const ts = run(v, s, {
path:
k === void 0
? path
: [...path, k],
branch:
k === void 0
? branch
: [...branch, v],
coerce,
mask,
message: options.message,
});
for (const t of ts)
if (t[0]) {
status =
t[0].refinement != null
? "not_refined"
: "not_valid";
yield [t[0], void 0];
} else if (coerce) {
v = t[1];
if (k === void 0) value = v;
else if (value instanceof Map)
value.set(k, v);
else if (value instanceof Set)
value.add(v);
else if (isObject(value)) {
if (
v !== void 0 ||
k in value
)
value[k] = v;
}
}
}
if (status !== "not_valid")
for (const failure of struct.refiner(
value,
ctx,
)) {
failure.explanation =
options.message;
status = "not_refined";
yield [failure, void 0];
}
if (status === "valid")
yield [void 0, value];
}
var Struct = class {
constructor(props) {
const {
type,
schema,
validator,
refiner,
coercer = (value) => value,
entries = function* () {},
} = props;
this.type = type;
this.schema = schema;
this.entries = entries;
this.coercer = coercer;
if (validator)
this.validator = (
value,
context,
) => {
return toFailures(
validator(value, context),
context,
this,
value,
);
};
else this.validator = () => [];
if (refiner)
this.refiner = (
value,
context,
) => {
return toFailures(
refiner(value, context),
context,
this,
value,
);
};
else this.refiner = () => [];
}
assert(value, message) {
return assert(value, this, message);
}
create(value, message) {
return create(value, this, message);
}
is(value) {
return is(value, this);
}
mask(value, message) {
return mask(value, this, message);
}
validate(value, options = {}) {
return validate(
value,
this,
options,
);
}
};
function assert(
value,
struct,
message,
) {
const result = validate(
value,
struct,
{ message },
);
if (result[0]) throw result[0];
}
function create(
value,
struct,
message,
) {
const result = validate(
value,
struct,
{
coerce: true,
message,
},
);
if (result[0]) throw result[0];
else return result[1];
}
function mask(value, struct, message) {
const result = validate(
value,
struct,
{
coerce: true,
mask: true,
message,
},
);
if (result[0]) throw result[0];
else return result[1];
}
function is(value, struct) {
return !validate(value, struct)[0];
}
function validate(
value,
struct,
options = {},
) {
const tuples = run(
value,
struct,
options,
);
const tuple = shiftIterator(tuples);
if (tuple[0])
return [
new StructError(
tuple[0],
function* () {
for (const t of tuples)
if (t[0]) yield t[0];
},
),
void 0,
];
else return [void 0, tuple[1]];
}
function define(name, validator) {
return new Struct({
type: name,
schema: null,
validator,
});
}
function array(Element) {
return new Struct({
type: "array",
schema: Element,
*entries(value) {
if (
Element &&
Array.isArray(value)
)
for (const [
i,
v,
] of value.entries())
yield [i, v, Element];
},
coercer(value) {
return Array.isArray(value)
? value.slice()
: value;
},
validator(value) {
return (
Array.isArray(value) ||
`Expected an array value, but received: ${print(value)}`
);
},
});
}
function date() {
return define("date", (value) => {
return (
(value instanceof Date &&
!isNaN(value.getTime())) ||
`Expected a valid \`Date\` object, but received: ${print(value)}`
);
});
}
function enums(values) {
const schema = {};
const description = values
.map((v) => print(v))
.join();
for (const key of values)
schema[key] = key;
return new Struct({
type: "enums",
schema,
validator(value) {
return (
values.includes(value) ||
`Expected one of \`${description}\`, but received: ${print(value)}`
);
},
});
}
function never() {
return define("never", () => false);
}
function nullable(struct) {
return new Struct({
...struct,
validator: (value, ctx) =>
value === null ||
struct.validator(value, ctx),
refiner: (value, ctx) =>
value === null ||
struct.refiner(value, ctx),
});
}
function number() {
return define("number", (value) => {
return (
(typeof value === "number" &&
!isNaN(value)) ||
`Expected a number, but received: ${print(value)}`
);
});
}
function object(schema) {
const knowns = schema
? Object.keys(schema)
: [];
const Never = never();
return new Struct({
type: "object",
schema: schema ? schema : null,
*entries(value) {
if (schema && isObject(value)) {
const unknowns = new Set(
Object.keys(value),
);
for (const key of knowns) {
unknowns.delete(key);
yield [
key,
value[key],
schema[key],
];
}
for (const key of unknowns)
yield [
key,
value[key],
Never,
];
}
},
validator(value) {
return (
isNonArrayObject(value) ||
`Expected an object, but received: ${print(value)}`
);
},
coercer(value, ctx) {
if (!isNonArrayObject(value))
return value;
const coerced = { ...value };
if (ctx.mask && schema) {
for (const key in coerced)
if (schema[key] === void 0)
delete coerced[key];
}
return coerced;
},
});
}
function string() {
return define("string", (value) => {
return (
typeof value === "string" ||
`Expected a string, but received: ${print(value)}`
);
});
}
function max(
struct,
threshold,
options = {},
) {
const { exclusive } = options;
return refine(
struct,
"max",
(value) => {
return exclusive
? value < threshold
: value <= threshold ||
`Expected a ${struct.type} less than ${exclusive ? "" : "or equal to "}${threshold} but received \`${value}\``;
},
);
}
function min(
struct,
threshold,
options = {},
) {
const { exclusive } = options;
return refine(
struct,
"min",
(value) => {
return exclusive
? value > threshold
: value >= threshold ||
`Expected a ${struct.type} greater than ${exclusive ? "" : "or equal to "}${threshold} but received \`${value}\``;
},
);
}
function refine(struct, name, refiner) {
return new Struct({
...struct,
*refiner(value, ctx) {
yield* struct.refiner(value, ctx);
const failures = toFailures(
refiner(value, ctx),
ctx,
struct,
value,
);
for (const failure of failures)
yield {
...failure,
refinement: name,
};
},
});
}
function stringWithLength(min, max) {
return refine(
string(),
`string with length between ${min} and ${max}`,
(value) =>
value.length >= min &&
value.length <= max,
);
}
const urlSchema = refine(
string(),
"url",
(value) => URL.canParse(value),
);
const imageSchema = object({
id: number(),
created: date(),
title: stringWithLength(1, 100),
type: enums(["jpg", "png"]),
size: number(),
url: urlSchema,
});
const ratingSchema = object({
id: number(),
stars: max(min(number(), 1), 5),
title: stringWithLength(1, 100),
text: stringWithLength(1, 1e3),
images: array(imageSchema),
});
create(
{},
object({
id: number(),
created: date(),
title: stringWithLength(1, 100),
brand: stringWithLength(1, 30),
description: stringWithLength(
1,
500,
),
price: max(min(number(), 1), 1e4),
discount: nullable(
max(min(number(), 1), 100),
),
quantity: max(min(number(), 0), 10),
tags: array(
stringWithLength(1, 30),
),
images: array(imageSchema),
ratings: array(ratingSchema),
}),
);
var StructError = class extends TypeError {
constructor(failure, failures) {
let cached;
const { message, explanation, ...rest } = failure;
const { path } = failure;
const msg =
path.length === 0
? message
: `At path: ${path.join(".")} -- ${message}`;
super(explanation ?? msg);
if (explanation != null) this.cause = msg;
Object.assign(this, rest);
this.name = this.constructor.name;
this.failures = () => {
return cached ?? (cached = [failure, ...failures()]);
};
}
};
function isIterable(x) {
return (
isObject(x) && typeof x[Symbol.iterator] === "function"
);
}
function isObject(x) {
return typeof x === "object" && x != null;
}
function isNonArrayObject(x) {
return isObject(x) && !Array.isArray(x);
}
function print(value) {
if (typeof value === "symbol") return value.toString();
return typeof value === "string"
? JSON.stringify(value)
: `${value}`;
}
function shiftIterator(input) {
const { done, value } = input.next();
return done ? void 0 : value;
}
function toFailure(result, context, struct, value) {
if (result === true) return;
else if (result === false) result = {};
else if (typeof result === "string")
result = { message: result };
const { path, branch } = context;
const { type } = struct;
const {
refinement,
message = `Expected a value of type \`${type}\`${refinement ? ` with refinement \`${refinement}\`` : ""}, but received: \`${print(value)}\``,
} = result;
return {
value,
type,
refinement,
key: path[path.length - 1],
path,
branch,
...result,
message,
};
}
function* toFailures(result, context, struct, value) {
if (!isIterable(result)) result = [result];
for (const r of result) {
const failure = toFailure(r, context, struct, value);
if (failure) yield failure;
}
}
function* run(value, struct, options = {}) {
const {
path = [],
branch = [value],
coerce = false,
mask = false,
} = options;
const ctx = {
path,
branch,
mask,
};
if (coerce) value = struct.coercer(value, ctx);
let status = "valid";
for (const failure of struct.validator(value, ctx)) {
failure.explanation = options.message;
status = "not_valid";
yield [failure, void 0];
}
for (let [k, v, s] of struct.entries(value, ctx)) {
const ts = run(v, s, {
path: k === void 0 ? path : [...path, k],
branch: k === void 0 ? branch : [...branch, v],
coerce,
mask,
message: options.message,
});
for (const t of ts)
if (t[0]) {
status =
t[0].refinement != null
? "not_refined"
: "not_valid";
yield [t[0], void 0];
} else if (coerce) {
v = t[1];
if (k === void 0) value = v;
else if (value instanceof Map) value.set(k, v);
else if (value instanceof Set) value.add(v);
else if (isObject(value)) {
if (v !== void 0 || k in value) value[k] = v;
}
}
}
if (status !== "not_valid")
for (const failure of struct.refiner(value, ctx)) {
failure.explanation = options.message;
status = "not_refined";
yield [failure, void 0];
}
if (status === "valid") yield [void 0, value];
}
var Struct = class {
constructor(props) {
const {
type,
schema,
validator,
refiner,
coercer = (value) => value,
entries = function* () {},
} = props;
this.type = type;
this.schema = schema;
this.entries = entries;
this.coercer = coercer;
if (validator)
this.validator = (value, context) => {
return toFailures(
validator(value, context),
context,
this,
value,
);
};
else this.validator = () => [];
if (refiner)
this.refiner = (value, context) => {
return toFailures(
refiner(value, context),
context,
this,
value,
);
};
else this.refiner = () => [];
}
assert(value, message) {
return assert(value, this, message);
}
create(value, message) {
return create(value, this, message);
}
is(value) {
return is(value, this);
}
mask(value, message) {
return mask(value, this, message);
}
validate(value, options = {}) {
return validate(value, this, options);
}
};
function assert(value, struct, message) {
const result = validate(value, struct, { message });
if (result[0]) throw result[0];
}
function create(value, struct, message) {
const result = validate(value, struct, {
coerce: true,
message,
});
if (result[0]) throw result[0];
else return result[1];
}
function mask(value, struct, message) {
const result = validate(value, struct, {
coerce: true,
mask: true,
message,
});
if (result[0]) throw result[0];
else return result[1];
}
function is(value, struct) {
return !validate(value, struct)[0];
}
function validate(value, struct, options = {}) {
const tuples = run(value, struct, options);
const tuple = shiftIterator(tuples);
if (tuple[0])
return [
new StructError(tuple[0], function* () {
for (const t of tuples) if (t[0]) yield t[0];
}),
void 0,
];
else return [void 0, tuple[1]];
}
function define(name, validator) {
return new Struct({
type: name,
schema: null,
validator,
});
}
function array(Element) {
return new Struct({
type: "array",
schema: Element,
*entries(value) {
if (Element && Array.isArray(value))
for (const [i, v] of value.entries())
yield [i, v, Element];
},
coercer(value) {
return Array.isArray(value) ? value.slice() : value;
},
validator(value) {
return (
Array.isArray(value) ||
`Expected an array value, but received: ${print(value)}`
);
},
});
}
function date() {
return define("date", (value) => {
return (
(value instanceof Date && !isNaN(value.getTime())) ||
`Expected a valid \`Date\` object, but received: ${print(value)}`
);
});
}
function enums(values) {
const schema = {};
const description = values.map((v) => print(v)).join();
for (const key of values) schema[key] = key;
return new Struct({
type: "enums",
schema,
validator(value) {
return (
values.includes(value) ||
`Expected one of \`${description}\`, but received: ${print(value)}`
);
},
});
}
function never() {
return define("never", () => false);
}
function nullable(struct) {
return new Struct({
...struct,
validator: (value, ctx) =>
value === null || struct.validator(value, ctx),
refiner: (value, ctx) =>
value === null || struct.refiner(value, ctx),
});
}
function number() {
return define("number", (value) => {
return (
(typeof value === "number" && !isNaN(value)) ||
`Expected a number, but received: ${print(value)}`
);
});
}
function object(schema) {
const knowns = schema ? Object.keys(schema) : [];
const Never = never();
return new Struct({
type: "object",
schema: schema ? schema : null,
*entries(value) {
if (schema && isObject(value)) {
const unknowns = new Set(Object.keys(value));
for (const key of knowns) {
unknowns.delete(key);
yield [key, value[key], schema[key]];
}
for (const key of unknowns)
yield [key, value[key], Never];
}
},
validator(value) {
return (
isNonArrayObject(value) ||
`Expected an object, but received: ${print(value)}`
);
},
coercer(value, ctx) {
if (!isNonArrayObject(value)) return value;
const coerced = { ...value };
if (ctx.mask && schema) {
for (const key in coerced)
if (schema[key] === void 0) delete coerced[key];
}
return coerced;
},
});
}
function string() {
return define("string", (value) => {
return (
typeof value === "string" ||
`Expected a string, but received: ${print(value)}`
);
});
}
function max(struct, threshold, options = {}) {
const { exclusive } = options;
return refine(struct, "max", (value) => {
return exclusive
? value < threshold
: value <= threshold ||
`Expected a ${struct.type} less than ${exclusive ? "" : "or equal to "}${threshold} but received \`${value}\``;
});
}
function min(struct, threshold, options = {}) {
const { exclusive } = options;
return refine(struct, "min", (value) => {
return exclusive
? value > threshold
: value >= threshold ||
`Expected a ${struct.type} greater than ${exclusive ? "" : "or equal to "}${threshold} but received \`${value}\``;
});
}
function refine(struct, name, refiner) {
return new Struct({
...struct,
*refiner(value, ctx) {
yield* struct.refiner(value, ctx);
const failures = toFailures(
refiner(value, ctx),
ctx,
struct,
value,
);
for (const failure of failures)
yield {
...failure,
refinement: name,
};
},
});
}
function stringWithLength(min, max) {
return refine(
string(),
`string with length between ${min} and ${max}`,
(value) => value.length >= min && value.length <= max,
);
}
const urlSchema = refine(string(), "url", (value) =>
URL.canParse(value),
);
const imageSchema = object({
id: number(),
created: date(),
title: stringWithLength(1, 100),
type: enums(["jpg", "png"]),
size: number(),
url: urlSchema,
});
const ratingSchema = object({
id: number(),
stars: max(min(number(), 1), 5),
title: stringWithLength(1, 100),
text: stringWithLength(1, 1e3),
images: array(imageSchema),
});
create(
{},
object({
id: number(),
created: date(),
title: stringWithLength(1, 100),
brand: stringWithLength(1, 30),
description: stringWithLength(1, 500),
price: max(min(number(), 1), 1e4),
discount: nullable(max(min(number(), 1), 100)),
quantity: max(min(number(), 0), 10),
tags: array(stringWithLength(1, 30)),
images: array(imageSchema),
ratings: array(ratingSchema),
}),
);
var StructError = class extends TypeError {
constructor(failure, failures) {
let cached;
const { message, explanation, ...rest } = failure;
const { path } = failure;
const msg =
path.length === 0 ? message : `At path: ${path.join(".")} -- ${message}`;
super(explanation ?? msg);
if (explanation != null) this.cause = msg;
Object.assign(this, rest);
this.name = this.constructor.name;
this.failures = () => {
return cached ?? (cached = [failure, ...failures()]);
};
}
};
function isIterable(x) {
return isObject(x) && typeof x[Symbol.iterator] === "function";
}
function isObject(x) {
return typeof x === "object" && x != null;
}
function isNonArrayObject(x) {
return isObject(x) && !Array.isArray(x);
}
function print(value) {
if (typeof value === "symbol") return value.toString();
return typeof value === "string" ? JSON.stringify(value) : `${value}`;
}
function shiftIterator(input) {
const { done, value } = input.next();
return done ? void 0 : value;
}
function toFailure(result, context, struct, value) {
if (result === true) return;
else if (result === false) result = {};
else if (typeof result === "string") result = { message: result };
const { path, branch } = context;
const { type } = struct;
const {
refinement,
message = `Expected a value of type \`${type}\`${refinement ? ` with refinement \`${refinement}\`` : ""}, but received: \`${print(value)}\``,
} = result;
return {
value,
type,
refinement,
key: path[path.length - 1],
path,
branch,
...result,
message,
};
}
function* toFailures(result, context, struct, value) {
if (!isIterable(result)) result = [result];
for (const r of result) {
const failure = toFailure(r, context, struct, value);
if (failure) yield failure;
}
}
function* run(value, struct, options = {}) {
const { path = [], branch = [value], coerce = false, mask = false } = options;
const ctx = {
path,
branch,
mask,
};
if (coerce) value = struct.coercer(value, ctx);
let status = "valid";
for (const failure of struct.validator(value, ctx)) {
failure.explanation = options.message;
status = "not_valid";
yield [failure, void 0];
}
for (let [k, v, s] of struct.entries(value, ctx)) {
const ts = run(v, s, {
path: k === void 0 ? path : [...path, k],
branch: k === void 0 ? branch : [...branch, v],
coerce,
mask,
message: options.message,
});
for (const t of ts)
if (t[0]) {
status = t[0].refinement != null ? "not_refined" : "not_valid";
yield [t[0], void 0];
} else if (coerce) {
v = t[1];
if (k === void 0) value = v;
else if (value instanceof Map) value.set(k, v);
else if (value instanceof Set) value.add(v);
else if (isObject(value)) {
if (v !== void 0 || k in value) value[k] = v;
}
}
}
if (status !== "not_valid")
for (const failure of struct.refiner(value, ctx)) {
failure.explanation = options.message;
status = "not_refined";
yield [failure, void 0];
}
if (status === "valid") yield [void 0, value];
}
var Struct = class {
constructor(props) {
const {
type,
schema,
validator,
refiner,
coercer = (value) => value,
entries = function* () {},
} = props;
this.type = type;
this.schema = schema;
this.entries = entries;
this.coercer = coercer;
if (validator)
this.validator = (value, context) => {
return toFailures(validator(value, context), context, this, value);
};
else this.validator = () => [];
if (refiner)
this.refiner = (value, context) => {
return toFailures(refiner(value, context), context, this, value);
};
else this.refiner = () => [];
}
assert(value, message) {
return assert(value, this, message);
}
create(value, message) {
return create(value, this, message);
}
is(value) {
return is(value, this);
}
mask(value, message) {
return mask(value, this, message);
}
validate(value, options = {}) {
return validate(value, this, options);
}
};
function assert(value, struct, message) {
const result = validate(value, struct, { message });
if (result[0]) throw result[0];
}
function create(value, struct, message) {
const result = validate(value, struct, {
coerce: true,
message,
});
if (result[0]) throw result[0];
else return result[1];
}
function mask(value, struct, message) {
const result = validate(value, struct, {
coerce: true,
mask: true,
message,
});
if (result[0]) throw result[0];
else return result[1];
}
function is(value, struct) {
return !validate(value, struct)[0];
}
function validate(value, struct, options = {}) {
const tuples = run(value, struct, options);
const tuple = shiftIterator(tuples);
if (tuple[0])
return [
new StructError(tuple[0], function* () {
for (const t of tuples) if (t[0]) yield t[0];
}),
void 0,
];
else return [void 0, tuple[1]];
}
function define(name, validator) {
return new Struct({
type: name,
schema: null,
validator,
});
}
function array(Element) {
return new Struct({
type: "array",
schema: Element,
*entries(value) {
if (Element && Array.isArray(value))
for (const [i, v] of value.entries()) yield [i, v, Element];
},
coercer(value) {
return Array.isArray(value) ? value.slice() : value;
},
validator(value) {
return (
Array.isArray(value) ||
`Expected an array value, but received: ${print(value)}`
);
},
});
}
function date() {
return define("date", (value) => {
return (
(value instanceof Date && !isNaN(value.getTime())) ||
`Expected a valid \`Date\` object, but received: ${print(value)}`
);
});
}
function enums(values) {
const schema = {};
const description = values.map((v) => print(v)).join();
for (const key of values) schema[key] = key;
return new Struct({
type: "enums",
schema,
validator(value) {
return (
values.includes(value) ||
`Expected one of \`${description}\`, but received: ${print(value)}`
);
},
});
}
function never() {
return define("never", () => false);
}
function nullable(struct) {
return new Struct({
...struct,
validator: (value, ctx) => value === null || struct.validator(value, ctx),
refiner: (value, ctx) => value === null || struct.refiner(value, ctx),
});
}
function number() {
return define("number", (value) => {
return (
(typeof value === "number" && !isNaN(value)) ||
`Expected a number, but received: ${print(value)}`
);
});
}
function object(schema) {
const knowns = schema ? Object.keys(schema) : [];
const Never = never();
return new Struct({
type: "object",
schema: schema ? schema : null,
*entries(value) {
if (schema && isObject(value)) {
const unknowns = new Set(Object.keys(value));
for (const key of knowns) {
unknowns.delete(key);
yield [key, value[key], schema[key]];
}
for (const key of unknowns) yield [key, value[key], Never];
}
},
validator(value) {
return (
isNonArrayObject(value) ||
`Expected an object, but received: ${print(value)}`
);
},
coercer(value, ctx) {
if (!isNonArrayObject(value)) return value;
const coerced = { ...value };
if (ctx.mask && schema) {
for (const key in coerced)
if (schema[key] === void 0) delete coerced[key];
}
return coerced;
},
});
}
function string() {
return define("string", (value) => {
return (
typeof value === "string" ||
`Expected a string, but received: ${print(value)}`
);
});
}
function max(struct, threshold, options = {}) {
const { exclusive } = options;
return refine(struct, "max", (value) => {
return exclusive
? value < threshold
: value <= threshold ||
`Expected a ${struct.type} less than ${exclusive ? "" : "or equal to "}${threshold} but received \`${value}\``;
});
}
function min(struct, threshold, options = {}) {
const { exclusive } = options;
return refine(struct, "min", (value) => {
return exclusive
? value > threshold
: value >= threshold ||
`Expected a ${struct.type} greater than ${exclusive ? "" : "or equal to "}${threshold} but received \`${value}\``;
});
}
function refine(struct, name, refiner) {
return new Struct({
...struct,
*refiner(value, ctx) {
yield* struct.refiner(value, ctx);
const failures = toFailures(refiner(value, ctx), ctx, struct, value);
for (const failure of failures)
yield {
...failure,
refinement: name,
};
},
});
}
function stringWithLength(min, max) {
return refine(
string(),
`string with length between ${min} and ${max}`,
(value) => value.length >= min && value.length <= max,
);
}
const urlSchema = refine(string(), "url", (value) => URL.canParse(value));
const imageSchema = object({
id: number(),
created: date(),
title: stringWithLength(1, 100),
type: enums(["jpg", "png"]),
size: number(),
url: urlSchema,
});
const ratingSchema = object({
id: number(),
stars: max(min(number(), 1), 5),
title: stringWithLength(1, 100),
text: stringWithLength(1, 1e3),
images: array(imageSchema),
});
create(
{},
object({
id: number(),
created: date(),
title: stringWithLength(1, 100),
brand: stringWithLength(1, 30),
description: stringWithLength(1, 500),
price: max(min(number(), 1), 1e4),
discount: nullable(max(min(number(), 1), 100)),
quantity: max(min(number(), 0), 10),
tags: array(stringWithLength(1, 30)),
images: array(imageSchema),
ratings: array(ratingSchema),
}),
);
var StructError = class extends TypeError {
constructor(failure, failures) {
let cached;
const { message, explanation, ...rest } = failure;
const { path } = failure;
const msg = path.length === 0 ? message : `At path: ${path.join(".")} -- ${message}`;
super(explanation ?? msg);
if (explanation != null) this.cause = msg;
Object.assign(this, rest);
this.name = this.constructor.name;
this.failures = () => {
return cached ?? (cached = [failure, ...failures()]);
};
}
};
function isIterable(x) {
return isObject(x) && typeof x[Symbol.iterator] === "function";
}
function isObject(x) {
return typeof x === "object" && x != null;
}
function isNonArrayObject(x) {
return isObject(x) && !Array.isArray(x);
}
function print(value) {
if (typeof value === "symbol") return value.toString();
return typeof value === "string" ? JSON.stringify(value) : `${value}`;
}
function shiftIterator(input) {
const { done, value } = input.next();
return done ? void 0 : value;
}
function toFailure(result, context, struct, value) {
if (result === true) return;
else if (result === false) result = {};
else if (typeof result === "string") result = { message: result };
const { path, branch } = context;
const { type } = struct;
const {
refinement,
message = `Expected a value of type \`${type}\`${refinement ? ` with refinement \`${refinement}\`` : ""}, but received: \`${print(value)}\``,
} = result;
return {
value,
type,
refinement,
key: path[path.length - 1],
path,
branch,
...result,
message,
};
}
function* toFailures(result, context, struct, value) {
if (!isIterable(result)) result = [result];
for (const r of result) {
const failure = toFailure(r, context, struct, value);
if (failure) yield failure;
}
}
function* run(value, struct, options = {}) {
const { path = [], branch = [value], coerce = false, mask = false } = options;
const ctx = {
path,
branch,
mask,
};
if (coerce) value = struct.coercer(value, ctx);
let status = "valid";
for (const failure of struct.validator(value, ctx)) {
failure.explanation = options.message;
status = "not_valid";
yield [failure, void 0];
}
for (let [k, v, s] of struct.entries(value, ctx)) {
const ts = run(v, s, {
path: k === void 0 ? path : [...path, k],
branch: k === void 0 ? branch : [...branch, v],
coerce,
mask,
message: options.message,
});
for (const t of ts)
if (t[0]) {
status = t[0].refinement != null ? "not_refined" : "not_valid";
yield [t[0], void 0];
} else if (coerce) {
v = t[1];
if (k === void 0) value = v;
else if (value instanceof Map) value.set(k, v);
else if (value instanceof Set) value.add(v);
else if (isObject(value)) {
if (v !== void 0 || k in value) value[k] = v;
}
}
}
if (status !== "not_valid")
for (const failure of struct.refiner(value, ctx)) {
failure.explanation = options.message;
status = "not_refined";
yield [failure, void 0];
}
if (status === "valid") yield [void 0, value];
}
var Struct = class {
constructor(props) {
const {
type,
schema,
validator,
refiner,
coercer = (value) => value,
entries = function* () {},
} = props;
this.type = type;
this.schema = schema;
this.entries = entries;
this.coercer = coercer;
if (validator)
this.validator = (value, context) => {
return toFailures(validator(value, context), context, this, value);
};
else this.validator = () => [];
if (refiner)
this.refiner = (value, context) => {
return toFailures(refiner(value, context), context, this, value);
};
else this.refiner = () => [];
}
assert(value, message) {
return assert(value, this, message);
}
create(value, message) {
return create(value, this, message);
}
is(value) {
return is(value, this);
}
mask(value, message) {
return mask(value, this, message);
}
validate(value, options = {}) {
return validate(value, this, options);
}
};
function assert(value, struct, message) {
const result = validate(value, struct, { message });
if (result[0]) throw result[0];
}
function create(value, struct, message) {
const result = validate(value, struct, {
coerce: true,
message,
});
if (result[0]) throw result[0];
else return result[1];
}
function mask(value, struct, message) {
const result = validate(value, struct, {
coerce: true,
mask: true,
message,
});
if (result[0]) throw result[0];
else return result[1];
}
function is(value, struct) {
return !validate(value, struct)[0];
}
function validate(value, struct, options = {}) {
const tuples = run(value, struct, options);
const tuple = shiftIterator(tuples);
if (tuple[0])
return [
new StructError(tuple[0], function* () {
for (const t of tuples) if (t[0]) yield t[0];
}),
void 0,
];
else return [void 0, tuple[1]];
}
function define(name, validator) {
return new Struct({
type: name,
schema: null,
validator,
});
}
function array(Element) {
return new Struct({
type: "array",
schema: Element,
*entries(value) {
if (Element && Array.isArray(value))
for (const [i, v] of value.entries()) yield [i, v, Element];
},
coercer(value) {
return Array.isArray(value) ? value.slice() : value;
},
validator(value) {
return Array.isArray(value) || `Expected an array value, but received: ${print(value)}`;
},
});
}
function date() {
return define("date", (value) => {
return (
(value instanceof Date && !isNaN(value.getTime())) ||
`Expected a valid \`Date\` object, but received: ${print(value)}`
);
});
}
function enums(values) {
const schema = {};
const description = values.map((v) => print(v)).join();
for (const key of values) schema[key] = key;
return new Struct({
type: "enums",
schema,
validator(value) {
return (
values.includes(value) ||
`Expected one of \`${description}\`, but received: ${print(value)}`
);
},
});
}
function never() {
return define("never", () => false);
}
function nullable(struct) {
return new Struct({
...struct,
validator: (value, ctx) => value === null || struct.validator(value, ctx),
refiner: (value, ctx) => value === null || struct.refiner(value, ctx),
});
}
function number() {
return define("number", (value) => {
return (
(typeof value === "number" && !isNaN(value)) ||
`Expected a number, but received: ${print(value)}`
);
});
}
function object(schema) {
const knowns = schema ? Object.keys(schema) : [];
const Never = never();
return new Struct({
type: "object",
schema: schema ? schema : null,
*entries(value) {
if (schema && isObject(value)) {
const unknowns = new Set(Object.keys(value));
for (const key of knowns) {
unknowns.delete(key);
yield [key, value[key], schema[key]];
}
for (const key of unknowns) yield [key, value[key], Never];
}
},
validator(value) {
return isNonArrayObject(value) || `Expected an object, but received: ${print(value)}`;
},
coercer(value, ctx) {
if (!isNonArrayObject(value)) return value;
const coerced = { ...value };
if (ctx.mask && schema) {
for (const key in coerced) if (schema[key] === void 0) delete coerced[key];
}
return coerced;
},
});
}
function string() {
return define("string", (value) => {
return typeof value === "string" || `Expected a string, but received: ${print(value)}`;
});
}
function max(struct, threshold, options = {}) {
const { exclusive } = options;
return refine(struct, "max", (value) => {
return exclusive
? value < threshold
: value <= threshold ||
`Expected a ${struct.type} less than ${exclusive ? "" : "or equal to "}${threshold} but received \`${value}\``;
});
}
function min(struct, threshold, options = {}) {
const { exclusive } = options;
return refine(struct, "min", (value) => {
return exclusive
? value > threshold
: value >= threshold ||
`Expected a ${struct.type} greater than ${exclusive ? "" : "or equal to "}${threshold} but received \`${value}\``;
});
}
function refine(struct, name, refiner) {
return new Struct({
...struct,
*refiner(value, ctx) {
yield* struct.refiner(value, ctx);
const failures = toFailures(refiner(value, ctx), ctx, struct, value);
for (const failure of failures)
yield {
...failure,
refinement: name,
};
},
});
}
function stringWithLength(min, max) {
return refine(
string(),
`string with length between ${min} and ${max}`,
(value) => value.length >= min && value.length <= max,
);
}
const urlSchema = refine(string(), "url", (value) => URL.canParse(value));
const imageSchema = object({
id: number(),
created: date(),
title: stringWithLength(1, 100),
type: enums(["jpg", "png"]),
size: number(),
url: urlSchema,
});
const ratingSchema = object({
id: number(),
stars: max(min(number(), 1), 5),
title: stringWithLength(1, 100),
text: stringWithLength(1, 1e3),
images: array(imageSchema),
});
create(
{},
object({
id: number(),
created: date(),
title: stringWithLength(1, 100),
brand: stringWithLength(1, 30),
description: stringWithLength(1, 500),
price: max(min(number(), 1), 1e4),
discount: nullable(max(min(number(), 1), 100)),
quantity: max(min(number(), 0), 10),
tags: array(stringWithLength(1, 30)),
images: array(imageSchema),
ratings: array(ratingSchema),
}),
);