alinea
Version:
Headless git-based CMS
169 lines (167 loc) • 4.41 kB
JavaScript
// node_modules/cito/dist/index.js
var { assign, entries, keys, values, setPrototypeOf } = Object;
var { stringify } = JSON;
var Context = class {
value = void 0;
path = [];
expected = "";
at(name) {
this.path.push(this.path.length > 0 ? `.${name}` : name);
}
index(index) {
this.path.push(`[${index}]`);
}
back() {
this.path.pop();
}
expect(e, v) {
this.expected = e;
this.value = v;
}
err(errorMessage) {
let at = this.path.length ? `@ ${this.path.join("")} ` : "";
let value = this.value;
let type2 = typeof value;
let got = type2 === "undefined" ? type2 : type2 === "object" ? value === null ? "null" : `${type2}: ${value.constructor.name}` : type2 === "function" ? `function: ${value.name}` : `${type2}: ${value}`;
let prefix = errorMessage ? `${errorMessage} \u2014 expected` : "Expected";
return `${prefix} ${this.expected} ${at}(got ${got})`;
}
};
var arg = "v";
var ctx = new Context();
var Type = class {
narrow() {
return this;
}
new(value) {
return value;
}
check(input) {
ctx = new Context();
return this.validate(input, ctx);
}
assert(input, errorMessage) {
if (!this.check(input))
throw new TypeError(ctx.err(errorMessage));
}
and(that) {
return type(
(value) => this.validate(value, ctx) && that.validate(value, ctx),
(path) => `${this.gen(path)} && ${that.gen(path)}`
);
}
or(that) {
return type(
(value) => this.validate(value, ctx) || that.validate(value, ctx),
(path) => `(${this.gen(path)} || ${that.gen(path)})`
);
}
get nullable() {
return nullable(this);
}
get optional() {
return optional(this);
}
};
var noGen = () => {
throw new Error(`This type cannot be generated`);
};
var type = (validate, gen = noGen) => {
const inst = assign(
setPrototypeOf((value, errorMessage) => {
inst.assert(value, errorMessage);
return value;
}, Type.prototype),
{ validate, gen }
);
return inst;
};
var literal = (literal2) => type(
(value) => (ctx.expect(stringify(literal2), value), literal2 === value),
(path) => `${path} === ${stringify(literal2)}`
);
var nullable = (inner) => literal(null).or(inner);
var optional = (inner) => literal(void 0).or(inner);
var primitive = (primitive2) => type(
(value) => (ctx.expect(primitive2, value), typeof value === primitive2),
(path) => `typeof ${path} === '${primitive2}'`
);
var instance = (constructor) => type(
(value, ctx2) => (ctx2.expect(constructor.name, value), value instanceof constructor),
(path) => `${path} instanceof ${constructor.name}`
);
var string = primitive("string");
var number = primitive("number").and(
type(
(value) => !isNaN(value),
(path) => `!isNaN(${path})`
)
);
var bigint = primitive("bigint");
var boolean = primitive("boolean");
var symbol = primitive("symbol");
var any = type(
(value) => true,
() => `!0`
);
var date = instance(Date).and(
type(
(value) => !isNaN(value.getTime()),
(path) => `!isNaN(${path}.getTime())`
)
);
var isFunction = (f) => typeof f === "function";
var isObject = type(
(value) => (ctx.expect("object", value), typeof value === "object" && value != null),
(path) => `typeof ${path} === 'object' && ${path} !== null`
);
var isArray = type(
(value) => (ctx.expect("array", value), Array.isArray(value)),
(path) => `Array.isArray(${path})`
);
var object = (definition) => {
let inst = definition;
return isObject.and(
type(
(value) => {
if (isFunction(inst))
inst = new inst();
for (let key in inst) {
ctx.at(key);
if (!inst[key].validate(value[key], ctx))
return false;
ctx.back();
}
return true;
},
(path) => {
if (isFunction(inst))
inst = new inst();
const types = keys(inst).map((key) => [key, inst[key]]);
return types.map(([key, inner]) => inner.gen(`${path}.${key}`)).join(" && ");
}
)
);
};
var array = (inner) => isArray.and(
type(
(value, ctx2) => {
for (let i = 0; i < value.length; i++) {
ctx2.index(i);
if (!inner.validate(value[i], ctx2))
return false;
ctx2.back();
}
return true;
},
(path) => `${path}.every(${arg} => ${inner.gen(arg)})`
)
);
export {
type,
string,
boolean,
any,
object,
array
};