schemas/libraries/decoders/download_compiled/index/unminified.js
var MAX_ERRORS = 3;
function qty(n, unit) {
return n === 1 ? `${n} ${unit}` : `${n} ${unit}s`;
}
function isNumber(value) {
return typeof value === "number";
}
function isString(value) {
return typeof value === "string";
}
function isDate(value) {
return !!value && Object.prototype.toString.call(value) === "[object Date]" && !isNaN(value);
}
function isPromiseLike(value) {
return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
}
function isPlainObject(value) {
return value !== null && typeof value === "object" && Object.prototype.toString.call(value) === "[object Object]";
}
function assertNever(_value, msg = "Unhandled case") {
throw new Error(msg);
}
var kAnnotationRegistry = Symbol.for("decoders.kAnnotationRegistry");
var _stamped = globalThis[kAnnotationRegistry] ??= new WeakSet();
function stamp(ann) {
_stamped.add(ann);
return ann;
}
function makeObjectAnn(getFields, text) {
let fields;
return stamp({
type: "object",
get fields() {
return fields ??= getFields();
},
text
});
}
function makeArrayAnn(getItems, text) {
let items;
return stamp({
type: "array",
get items() {
return items ??= getItems();
},
text
});
}
function makeOpaqueAnn(value, text) {
return stamp({
type: "opaque",
value,
text
});
}
function makeScalarAnn(value, text) {
return stamp({
type: "scalar",
value,
text
});
}
function updateText(annotation, text) {
if (text === void 0) return annotation;
switch (annotation.type) {
case "object": return makeObjectAnn(() => annotation.fields, text);
case "array": return makeArrayAnn(() => annotation.items, text);
case "scalar": return makeScalarAnn(annotation.value, text);
case "opaque": return makeOpaqueAnn(annotation.value, text);
default: return assertNever(annotation, "Unknown annotation type");
}
}
function merge(objAnnotation, fields) {
return makeObjectAnn(() => new Map([...objAnnotation.fields, ...fields]), objAnnotation.text);
}
function isAnnotation(thing) {
return _stamped.has(thing);
}
function annotateArray(arr, text, seen) {
seen.add(arr);
return makeArrayAnn(() => Array.from(arr, (value) => __annotate(value, void 0, seen)), text);
}
function annotateObject(obj, text, seen) {
seen.add(obj);
return makeObjectAnn(() => {
const fields = new Map();
for (const key of Object.keys(obj)) {
const value = obj[key];
fields.set(key, __annotate(value, void 0, seen));
}
return fields;
}, text);
}
function __annotate(value, text, seen) {
if (value === null || value === void 0 || typeof value === "string" || typeof value === "number" || typeof value === "boolean" || typeof value === "symbol" || typeof value === "bigint" || typeof value.getMonth === "function") return makeScalarAnn(value, text);
if (isAnnotation(value)) return updateText(value, text);
if (Array.isArray(value)) {
if (seen.has(value)) return makeOpaqueAnn("<circular ref>", text);
else return annotateArray(value, text, seen);
}
if ( isPlainObject(value)) {
if (seen.has(value)) return makeOpaqueAnn("<circular ref>", text);
else return annotateObject(value, text, seen);
}
if (typeof value === "function") return makeOpaqueAnn("<function>", text);
if ( isPromiseLike(value)) return makeOpaqueAnn("<Promise>", text);
if (value?.constructor?.name) return makeOpaqueAnn(`<${value.constructor.name}>`, text);
else return makeOpaqueAnn("???", text);
}
function public_annotate(value, text) {
return __annotate(value, text, new WeakSet());
}
function public_annotateObject(obj, text) {
return annotateObject(obj, text, new WeakSet());
}
var INDENT = " ";
function isMultiline(s) {
return s.includes("\n");
}
function indent(s, prefix = INDENT) {
if ( isMultiline(s)) return s.split("\n").map((line) => `${prefix}${line}`).join("\n");
else return `${prefix}${s}`;
}
var quotePattern = /'/g;
function quote(value) {
return typeof value === "string" ? "'" + value.replace(quotePattern, "\\'") + "'" : value === void 0 ? "undefined" : JSON.stringify(value);
}
function summarize(ann, keypath = []) {
const result = [];
if (ann.type === "array") {
const items = ann.items;
let index = 0;
for (const ann2 of items) for (const item of summarize(ann2, [...keypath, index++])) result.push(item);
} else if (ann.type === "object") {
const fields = ann.fields;
for (const [key, value] of fields) for (const item of summarize(value, [...keypath, key])) result.push(item);
}
const text = ann.text;
if (!text) return result;
let prefix;
if (keypath.length === 0) prefix = "";
else if (keypath.length === 1) prefix = typeof keypath[0] === "number" ? `Value at index ${keypath[0]}: ` : `Value at key ${/* @__PURE__ */ quote(keypath[0])}: `;
else prefix = `Value at keypath ${/* @__PURE__ */ quote(keypath.map(String).join("."))}: `;
return [...result, `${prefix}${text}`];
}
function serializeString(s, width = 80) {
let ser = JSON.stringify(s);
if (ser.length <= width) return ser;
const truncated = `${s.substring(0, width - 15)}...`;
ser = `${JSON.stringify(truncated)} [truncated]`;
return ser;
}
function serializeArray(annotation, prefix) {
const { items } = annotation;
if (items.length === 0) return "[]";
const result = [];
for (let i = 0; i < items.length; ++i) {
const [ser, ann] = serializeAnnotation(items[i], `${prefix}${INDENT}`, `(at index ${i})`);
result.push(`${prefix}${INDENT}${ser},`);
if (ann !== void 0) result.push( indent(ann, `${prefix}${INDENT}`));
}
return [
"[",
...result,
`${prefix}]`
].join("\n");
}
function serializeObject(annotation, prefix) {
const { fields } = annotation;
if (fields.size === 0) return "{}";
const result = [];
for (const [key, valueAnnotation] of fields) {
const kser = serializeValue(key);
const valPrefix = `${prefix}${INDENT}${" ".repeat(kser.length + 2)}`;
const [vser, vann] = serializeAnnotation(valueAnnotation, `${prefix}${INDENT}`);
result.push(`${prefix}${INDENT}${kser}: ${vser},`);
if (vann !== void 0) result.push( indent(vann, valPrefix));
}
return [
"{",
...result,
`${prefix}}`
].join("\n");
}
function serializeValue(value) {
if (typeof value === "string") return serializeString(value);
else if (typeof value === "number" || typeof value === "boolean" || typeof value === "symbol") return value.toString();
else if (value === null) return "null";
else if (value === void 0) return "undefined";
else if (typeof value === "bigint") return `${value.toString()}n`;
else if ( isDate(value)) return `new Date(${/* @__PURE__ */ quote(value.toISOString())})`;
else if (value instanceof Date) return "(Invalid Date)";
else return "(unserializable)";
}
function serializeAnnotation(ann, prefix = "", location) {
let serialized;
if (ann.type === "array") serialized = serializeArray(ann, prefix);
else if (ann.type === "object") serialized = serializeObject(ann, prefix);
else if (ann.type === "scalar") serialized = serializeValue(ann.value);
else serialized = ann.value;
const text = ann.text;
if (text !== void 0) {
const sep = "^".repeat( isMultiline(serialized) ? 1 : serialized.length);
const annotation = isMultiline(text) ? [location ? `${sep} ${location}` : sep, text].join("\n") : [
sep,
text,
location
].filter(Boolean).join(" ");
return [serialized, annotation];
} else return [serialized, void 0];
}
function formatInline(ann) {
const [serialized, annotation] = serializeAnnotation(ann);
if (annotation !== void 0) return `${serialized}
${annotation}`;
else return serialized;
}
function* iterAnnotation(ann, stack) {
if (ann.text) {
if (stack.length > 0) yield {
message: ann.text,
path: [...stack]
};
else yield { message: ann.text };
}
switch (ann.type) {
case "array": {
let index = 0;
for (const item of ann.items) {
stack.push(index++);
yield* iterAnnotation(item, stack);
stack.pop();
}
break;
}
case "object":
for (const [key, value] of ann.fields) {
stack.push(key);
yield* iterAnnotation(value, stack);
stack.pop();
}
break;
case "scalar":
case "opaque": break;
default: assertNever(ann, "Unknown annotation type");
}
}
function formatAsIssues(ann) {
return Array.from(iterAnnotation(ann, []));
}
function ok(value) {
return {
ok: true,
value,
error: void 0
};
}
function err(error) {
return {
ok: false,
value: void 0,
error
};
}
function noThrow(fn) {
return (t) => {
try {
return ok(fn(t));
} catch (e) {
return err(public_annotate(t, e instanceof Error ? e.message : String(e)));
}
};
}
function format(err2, formatter) {
const formatted = formatter(err2);
if (typeof formatted === "string") {
const err3 = new Error(`
${formatted}`);
err3.name = "Decoding error";
return err3;
} else return formatted;
}
var DecoderImpl = class {
decode;
verify;
value;
#standard;
constructor(fn) {
const decode = (blob) => {
const makeFlexErr = (msg) => err(isAnnotation(msg) ? msg : public_annotate(blob, msg));
return fn(blob, ok, makeFlexErr);
};
const verify = (blob, formatter = formatInline) => {
const result = decode(blob);
if (result.ok) return result.value;
else throw format(result.error, formatter);
};
const value = (blob) => decode(blob).value;
this.decode = decode;
this.verify = verify;
this.value = value;
}
transform(transformFn) {
return this.chain(noThrow(transformFn));
}
refine(predicateFn, errmsg) {
return this.reject((value) => predicateFn(value) ? null : errmsg);
}
refineType() {
return this;
}
chain(next) {
const decode = this.decode;
return define((blob, ok2, err2) => {
const r1 = decode(blob);
if (!r1.ok) return r1;
const r2 = isDecoder(next) ? next : next(r1.value, ok2, err2);
return isDecoder(r2) ? r2.decode(r1.value) : r2;
});
}
pipe(next) {
return this.chain(next);
}
reject(rejectFn) {
return this.chain((blob, ok2, err2) => {
const errmsg = rejectFn(blob);
return errmsg === null ? ok2(blob) : err2(typeof errmsg === "string" ? public_annotate(blob, errmsg) : errmsg);
});
}
describe(message) {
const decode = this.decode;
return define((blob, _, err2) => {
const result = decode(blob);
if (result.ok) return result;
else return err2(public_annotate(result.error, message));
});
}
get "~standard"() {
const decode = this.decode;
return this.#standard ??= {
version: 1,
vendor: "decoders",
validate: (blob) => {
const result = decode(blob);
if (result.ok) return { value: result.value };
else return { issues: formatAsIssues(result.error) };
}
};
}
};
Object.defineProperty(DecoderImpl, "name", { value: "Decoder" });
function define(fn) {
return stamp2(new DecoderImpl(fn));
}
var kDecoderRegistry = Symbol.for("decoders.kDecoderRegistry");
var _stamped2 = globalThis[kDecoderRegistry] ??= new WeakSet();
function stamp2(decoder) {
_stamped2.add(decoder);
return decoder;
}
function isDecoder(value) {
return _stamped2.has(value);
}
function bySizeOptions(options) {
const size = options.size;
const min2 = size ?? options.min;
const max2 = size ?? options.max;
const atLeast = min2 === max2 ? "" : "at least ";
const atMost = min2 === max2 ? "" : "at most ";
return (value) => {
const len = value.length ?? value.size;
if (typeof value === "string") {
if (min2 !== void 0 && len < min2) return `Too short, must be ${atLeast}${/* @__PURE__ */ qty(min2, "char")}`;
if (max2 !== void 0 && len > max2) return `Too long, must be ${atMost}${/* @__PURE__ */ qty(max2, "char")}`;
} else {
if (min2 !== void 0 && len < min2) return `Must have ${atLeast}${/* @__PURE__ */ qty(min2, "item")}`;
if (max2 !== void 0 && len > max2) return `Must have ${atMost}${/* @__PURE__ */ qty(max2, "item")}`;
}
return null;
};
}
function sized(decoder, options) {
return decoder.reject( bySizeOptions(options));
}
var poja = define((blob, ok2, err2) => {
if (!Array.isArray(blob)) return err2("Must be an array");
return ok2(blob);
});
function array(decoder, options) {
const decodeFn = decoder.decode;
return (options !== void 0 ? sized(poja, options) : poja).chain((inputs, ok2, err2) => {
const results = [];
let clone = null;
let errorCount = 0;
for (let i = 0; i < inputs.length; ++i) {
const blob = inputs[i];
const result = decodeFn(blob);
if (result.ok) {
if (clone === null) results.push(result.value);
} else {
results.length = 0;
clone ??= inputs.slice();
clone[i] = result.error;
if (++errorCount >= MAX_ERRORS) break;
}
}
return clone !== null ? err2(public_annotate(clone)) : ok2(results);
});
}
var pojo = define((blob, ok2, err2) => isPlainObject(blob) ? ok2(blob) : err2("Must be an object"));
function buildObject(decoders) {
const knownKeys = Object.keys(decoders);
return pojo.chain((plainObj, ok2, err2) => {
const record2 = {};
let errors = null;
let missingKeys = null;
for (const key of knownKeys) {
const decoder = decoders[key];
const rawValue = plainObj[key];
const result = decoder.decode(rawValue);
if (result.ok) {
const value = result.value;
if (value !== void 0) record2[key] = value;
} else {
const ann = result.error;
if (rawValue === void 0) (missingKeys ??= []).push(key);
else (errors ??= new Map()).set(key, ann);
}
}
if (errors || missingKeys) {
let objAnn = public_annotateObject(plainObj);
if (errors) objAnn = merge(objAnn, errors);
if (missingKeys) {
const errMsg = missingKeys.map(quote).join(", ");
const pluralized = missingKeys.length > 1 ? "keys" : "key";
objAnn = updateText(objAnn, `Missing ${pluralized}: ${errMsg}`);
}
return err2(objAnn);
}
return ok2(record2);
});
}
function object(decoders) {
return buildObject(decoders);
}
var EITHER_PREFIX = "Either:\n";
function itemize(s) {
return `-${( indent(s)).substring(1)}`;
}
function nest(errText) {
return errText.startsWith(EITHER_PREFIX) ? errText.substring(EITHER_PREFIX.length) : itemize(errText);
}
function either(...decoders) {
if (decoders.length === 0) throw new Error("Pass at least one decoder to either()");
return define((blob, _, err2) => {
const errors = [];
for (const decoder of decoders) {
const result = decoder.decode(blob);
if (result.ok) return result;
else errors.push(result.error);
}
return err2(EITHER_PREFIX + errors.map((err3) => nest(( summarize(err3)).join("\n"))).join("\n"));
});
}
function oneOf(constants) {
return define((blob, ok2, err2) => {
const index = constants.indexOf(blob);
if (index !== -1) return ok2(constants[index]);
return err2(`Must be one of ${constants.map((value) => quote(value)).join(", ")}`);
});
}
function lazyval(value) {
return typeof value === "function" ? value() : value;
}
var null_ = constant(null);
function nullable(decoder, defaultValue) {
const rv = either(null_, decoder);
return arguments.length >= 2 ? rv.transform((value) => value ?? lazyval(defaultValue)) : rv;
}
function constant(value) {
return define((blob, ok2, err2) => blob === value ? ok2(value) : err2(`Must be ${typeof value === "symbol" ? String(value) : quote(value)}`));
}
var url_re = /^[A-Za-z]{2,12}(?:[+][A-Za-z]{2,12})?:\/\/(?:[^@]*@)?[A-Za-z0-9.-]+(?::[0-9]{2,5})?(?:\/[-+~%/.,!$&'()*:;=@\w]*(?:\?[-+~%/.,!$&'()*:;=@?\w]*)?)?(?:#[^\s#]*)?$/;
var string = define((blob, ok2, err2) => isString(blob) ? ok2(blob) : err2("Must be string"));
function regex(regex2, msg) {
return string.refine((s) => regex2.test(s), msg);
}
var urlString = regex(url_re, "Must be URL");
var date = define((blob, ok2, err2) => {
return isDate(blob) ? ok2(blob) : err2("Must be a Date");
});
var number = ( define((blob, ok2, err2) => isNumber(blob) ? ok2(blob) : err2("Must be number"))).refine((n) => Number.isFinite(n), "Number must be finite");
function between(min2, max2, decoder = number) {
return decoder.reject((value) => value < min2 ? `Too low, must be between ${min2} and ${max2}` : value > max2 ? `Too high, must be between ${min2} and ${max2}` : null);
}
const imageDecoder = object({
id: number,
created: date,
title: sized(string, {
min: 1,
max: 100
}),
type: oneOf(["jpg", "png"]),
size: number,
url: urlString
});
( object({
id: number,
created: date,
title: sized(string, {
min: 1,
max: 100
}),
brand: sized(string, {
min: 1,
max: 30
}),
description: sized(string, {
min: 1,
max: 500
}),
price: between(1, 1e4),
discount: nullable( between(1, 100)),
quantity: between(0, 10),
tags: array( sized(string, {
min: 1,
max: 30
})),
images: array(imageDecoder),
ratings: array( object({
id: number,
stars: between(1, 5),
title: sized(string, {
min: 1,
max: 100
}),
text: sized(string, {
min: 1,
max: 1e3
}),
images: array(imageDecoder)
}))
})).verify({});