| 1 | "use strict";
|
|---|
| 2 | var __spreadArrays = (this && this.__spreadArrays) || function () {
|
|---|
| 3 | for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
|
|---|
| 4 | for (var r = Array(s), k = 0, i = 0; i < il; i++)
|
|---|
| 5 | for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
|
|---|
| 6 | r[k] = a[j];
|
|---|
| 7 | return r;
|
|---|
| 8 | };
|
|---|
| 9 | Object.defineProperty(exports, "__esModule", { value: true });
|
|---|
| 10 | exports.Checker = exports.createCheckers = void 0;
|
|---|
| 11 | var types_1 = require("./types");
|
|---|
| 12 | var util_1 = require("./util");
|
|---|
| 13 | /**
|
|---|
| 14 | * Export functions used to define interfaces.
|
|---|
| 15 | */
|
|---|
| 16 | var types_2 = require("./types");
|
|---|
| 17 | Object.defineProperty(exports, "TArray", { enumerable: true, get: function () { return types_2.TArray; } });
|
|---|
| 18 | Object.defineProperty(exports, "TEnumType", { enumerable: true, get: function () { return types_2.TEnumType; } });
|
|---|
| 19 | Object.defineProperty(exports, "TEnumLiteral", { enumerable: true, get: function () { return types_2.TEnumLiteral; } });
|
|---|
| 20 | Object.defineProperty(exports, "TFunc", { enumerable: true, get: function () { return types_2.TFunc; } });
|
|---|
| 21 | Object.defineProperty(exports, "TIface", { enumerable: true, get: function () { return types_2.TIface; } });
|
|---|
| 22 | Object.defineProperty(exports, "TLiteral", { enumerable: true, get: function () { return types_2.TLiteral; } });
|
|---|
| 23 | Object.defineProperty(exports, "TName", { enumerable: true, get: function () { return types_2.TName; } });
|
|---|
| 24 | Object.defineProperty(exports, "TOptional", { enumerable: true, get: function () { return types_2.TOptional; } });
|
|---|
| 25 | Object.defineProperty(exports, "TParam", { enumerable: true, get: function () { return types_2.TParam; } });
|
|---|
| 26 | Object.defineProperty(exports, "TParamList", { enumerable: true, get: function () { return types_2.TParamList; } });
|
|---|
| 27 | Object.defineProperty(exports, "TProp", { enumerable: true, get: function () { return types_2.TProp; } });
|
|---|
| 28 | Object.defineProperty(exports, "TTuple", { enumerable: true, get: function () { return types_2.TTuple; } });
|
|---|
| 29 | Object.defineProperty(exports, "TType", { enumerable: true, get: function () { return types_2.TType; } });
|
|---|
| 30 | Object.defineProperty(exports, "TUnion", { enumerable: true, get: function () { return types_2.TUnion; } });
|
|---|
| 31 | Object.defineProperty(exports, "TIntersection", { enumerable: true, get: function () { return types_2.TIntersection; } });
|
|---|
| 32 | Object.defineProperty(exports, "array", { enumerable: true, get: function () { return types_2.array; } });
|
|---|
| 33 | Object.defineProperty(exports, "enumlit", { enumerable: true, get: function () { return types_2.enumlit; } });
|
|---|
| 34 | Object.defineProperty(exports, "enumtype", { enumerable: true, get: function () { return types_2.enumtype; } });
|
|---|
| 35 | Object.defineProperty(exports, "func", { enumerable: true, get: function () { return types_2.func; } });
|
|---|
| 36 | Object.defineProperty(exports, "iface", { enumerable: true, get: function () { return types_2.iface; } });
|
|---|
| 37 | Object.defineProperty(exports, "lit", { enumerable: true, get: function () { return types_2.lit; } });
|
|---|
| 38 | Object.defineProperty(exports, "name", { enumerable: true, get: function () { return types_2.name; } });
|
|---|
| 39 | Object.defineProperty(exports, "opt", { enumerable: true, get: function () { return types_2.opt; } });
|
|---|
| 40 | Object.defineProperty(exports, "param", { enumerable: true, get: function () { return types_2.param; } });
|
|---|
| 41 | Object.defineProperty(exports, "tuple", { enumerable: true, get: function () { return types_2.tuple; } });
|
|---|
| 42 | Object.defineProperty(exports, "union", { enumerable: true, get: function () { return types_2.union; } });
|
|---|
| 43 | Object.defineProperty(exports, "intersection", { enumerable: true, get: function () { return types_2.intersection; } });
|
|---|
| 44 | Object.defineProperty(exports, "BasicType", { enumerable: true, get: function () { return types_2.BasicType; } });
|
|---|
| 45 | var util_2 = require("./util");
|
|---|
| 46 | Object.defineProperty(exports, "VError", { enumerable: true, get: function () { return util_2.VError; } });
|
|---|
| 47 | /**
|
|---|
| 48 | * Takes one of more type suites (e.g. a module generated by `ts-interface-builder`), and combines
|
|---|
| 49 | * them into a suite of interface checkers. If a type is used by name, that name should be present
|
|---|
| 50 | * among the passed-in type suites.
|
|---|
| 51 | *
|
|---|
| 52 | * The returned object maps type names to Checker objects.
|
|---|
| 53 | */
|
|---|
| 54 | function createCheckers() {
|
|---|
| 55 | var typeSuite = [];
|
|---|
| 56 | for (var _i = 0; _i < arguments.length; _i++) {
|
|---|
| 57 | typeSuite[_i] = arguments[_i];
|
|---|
| 58 | }
|
|---|
| 59 | var fullSuite = Object.assign.apply(Object, __spreadArrays([{}, types_1.basicTypes], typeSuite));
|
|---|
| 60 | var checkers = {};
|
|---|
| 61 | for (var _a = 0, typeSuite_1 = typeSuite; _a < typeSuite_1.length; _a++) {
|
|---|
| 62 | var suite_1 = typeSuite_1[_a];
|
|---|
| 63 | for (var _b = 0, _c = Object.keys(suite_1); _b < _c.length; _b++) {
|
|---|
| 64 | var name = _c[_b];
|
|---|
| 65 | checkers[name] = new Checker(fullSuite, suite_1[name]);
|
|---|
| 66 | }
|
|---|
| 67 | }
|
|---|
| 68 | return checkers;
|
|---|
| 69 | }
|
|---|
| 70 | exports.createCheckers = createCheckers;
|
|---|
| 71 | /**
|
|---|
| 72 | * Checker implements validation of objects, and also includes accessors to validate method calls.
|
|---|
| 73 | * Checkers should be created using `createCheckers()`.
|
|---|
| 74 | */
|
|---|
| 75 | var Checker = /** @class */ (function () {
|
|---|
| 76 | // Create checkers by using `createCheckers()` function.
|
|---|
| 77 | function Checker(suite, ttype, _path) {
|
|---|
| 78 | if (_path === void 0) { _path = 'value'; }
|
|---|
| 79 | this.suite = suite;
|
|---|
| 80 | this.ttype = ttype;
|
|---|
| 81 | this._path = _path;
|
|---|
| 82 | this.props = new Map();
|
|---|
| 83 | if (ttype instanceof types_1.TIface) {
|
|---|
| 84 | for (var _i = 0, _a = ttype.props; _i < _a.length; _i++) {
|
|---|
| 85 | var p = _a[_i];
|
|---|
| 86 | this.props.set(p.name, p.ttype);
|
|---|
| 87 | }
|
|---|
| 88 | }
|
|---|
| 89 | this.checkerPlain = this.ttype.getChecker(suite, false);
|
|---|
| 90 | this.checkerStrict = this.ttype.getChecker(suite, true);
|
|---|
| 91 | }
|
|---|
| 92 | /**
|
|---|
| 93 | * Set the path to report in errors, instead of the default "value". (E.g. if the Checker is for
|
|---|
| 94 | * a "person" interface, set path to "person" to report e.g. "person.name is not a string".)
|
|---|
| 95 | */
|
|---|
| 96 | Checker.prototype.setReportedPath = function (path) {
|
|---|
| 97 | this._path = path;
|
|---|
| 98 | };
|
|---|
| 99 | /**
|
|---|
| 100 | * Check that the given value satisfies this checker's type, or throw Error.
|
|---|
| 101 | */
|
|---|
| 102 | Checker.prototype.check = function (value) { return this._doCheck(this.checkerPlain, value); };
|
|---|
| 103 | /**
|
|---|
| 104 | * A fast check for whether or not the given value satisfies this Checker's type. This returns
|
|---|
| 105 | * true or false, does not produce an error message, and is fast both on success and on failure.
|
|---|
| 106 | */
|
|---|
| 107 | Checker.prototype.test = function (value) {
|
|---|
| 108 | return this.checkerPlain(value, new util_1.NoopContext());
|
|---|
| 109 | };
|
|---|
| 110 | /**
|
|---|
| 111 | * Returns an error object describing the errors if the given value does not satisfy this
|
|---|
| 112 | * Checker's type, or null if it does.
|
|---|
| 113 | */
|
|---|
| 114 | Checker.prototype.validate = function (value) {
|
|---|
| 115 | return this._doValidate(this.checkerPlain, value);
|
|---|
| 116 | };
|
|---|
| 117 | /**
|
|---|
| 118 | * Check that the given value satisfies this checker's type strictly. This checks that objects
|
|---|
| 119 | * and tuples have no extra members. Note that this prevents backward compatibility, so usually
|
|---|
| 120 | * a plain check() is more appropriate.
|
|---|
| 121 | */
|
|---|
| 122 | Checker.prototype.strictCheck = function (value) { return this._doCheck(this.checkerStrict, value); };
|
|---|
| 123 | /**
|
|---|
| 124 | * A fast strict check for whether or not the given value satisfies this Checker's type. Returns
|
|---|
| 125 | * true or false, does not produce an error message, and is fast both on success and on failure.
|
|---|
| 126 | */
|
|---|
| 127 | Checker.prototype.strictTest = function (value) {
|
|---|
| 128 | return this.checkerStrict(value, new util_1.NoopContext());
|
|---|
| 129 | };
|
|---|
| 130 | /**
|
|---|
| 131 | * Returns an error object describing the errors if the given value does not satisfy this
|
|---|
| 132 | * Checker's type strictly, or null if it does.
|
|---|
| 133 | */
|
|---|
| 134 | Checker.prototype.strictValidate = function (value) {
|
|---|
| 135 | return this._doValidate(this.checkerStrict, value);
|
|---|
| 136 | };
|
|---|
| 137 | /**
|
|---|
| 138 | * If this checker is for an interface, returns a Checker for the type required for the given
|
|---|
| 139 | * property of this interface.
|
|---|
| 140 | */
|
|---|
| 141 | Checker.prototype.getProp = function (prop) {
|
|---|
| 142 | var ttype = this.props.get(prop);
|
|---|
| 143 | if (!ttype) {
|
|---|
| 144 | throw new Error("Type has no property " + prop);
|
|---|
| 145 | }
|
|---|
| 146 | return new Checker(this.suite, ttype, this._path + "." + prop);
|
|---|
| 147 | };
|
|---|
| 148 | /**
|
|---|
| 149 | * If this checker is for an interface, returns a Checker for the argument-list required to call
|
|---|
| 150 | * the given method of this interface. E.g. if this Checker is for the interface:
|
|---|
| 151 | * interface Foo {
|
|---|
| 152 | * find(s: string, pos?: number): number;
|
|---|
| 153 | * }
|
|---|
| 154 | * Then methodArgs("find").check(...) will succeed for ["foo"] and ["foo", 3], but not for [17].
|
|---|
| 155 | */
|
|---|
| 156 | Checker.prototype.methodArgs = function (methodName) {
|
|---|
| 157 | var tfunc = this._getMethod(methodName);
|
|---|
| 158 | return new Checker(this.suite, tfunc.paramList);
|
|---|
| 159 | };
|
|---|
| 160 | /**
|
|---|
| 161 | * If this checker is for an interface, returns a Checker for the return value of the given
|
|---|
| 162 | * method of this interface.
|
|---|
| 163 | */
|
|---|
| 164 | Checker.prototype.methodResult = function (methodName) {
|
|---|
| 165 | var tfunc = this._getMethod(methodName);
|
|---|
| 166 | return new Checker(this.suite, tfunc.result);
|
|---|
| 167 | };
|
|---|
| 168 | /**
|
|---|
| 169 | * If this checker is for a function, returns a Checker for its argument-list.
|
|---|
| 170 | */
|
|---|
| 171 | Checker.prototype.getArgs = function () {
|
|---|
| 172 | if (!(this.ttype instanceof types_1.TFunc)) {
|
|---|
| 173 | throw new Error("getArgs() applied to non-function");
|
|---|
| 174 | }
|
|---|
| 175 | return new Checker(this.suite, this.ttype.paramList);
|
|---|
| 176 | };
|
|---|
| 177 | /**
|
|---|
| 178 | * If this checker is for a function, returns a Checker for its result.
|
|---|
| 179 | */
|
|---|
| 180 | Checker.prototype.getResult = function () {
|
|---|
| 181 | if (!(this.ttype instanceof types_1.TFunc)) {
|
|---|
| 182 | throw new Error("getResult() applied to non-function");
|
|---|
| 183 | }
|
|---|
| 184 | return new Checker(this.suite, this.ttype.result);
|
|---|
| 185 | };
|
|---|
| 186 | /**
|
|---|
| 187 | * Return the type for which this is a checker.
|
|---|
| 188 | */
|
|---|
| 189 | Checker.prototype.getType = function () {
|
|---|
| 190 | return this.ttype;
|
|---|
| 191 | };
|
|---|
| 192 | /**
|
|---|
| 193 | * Actual implementation of check() and strictCheck().
|
|---|
| 194 | */
|
|---|
| 195 | Checker.prototype._doCheck = function (checkerFunc, value) {
|
|---|
| 196 | var noopCtx = new util_1.NoopContext();
|
|---|
| 197 | if (!checkerFunc(value, noopCtx)) {
|
|---|
| 198 | var detailCtx = new util_1.DetailContext();
|
|---|
| 199 | checkerFunc(value, detailCtx);
|
|---|
| 200 | throw detailCtx.getError(this._path);
|
|---|
| 201 | }
|
|---|
| 202 | };
|
|---|
| 203 | Checker.prototype._doValidate = function (checkerFunc, value) {
|
|---|
| 204 | var noopCtx = new util_1.NoopContext();
|
|---|
| 205 | if (checkerFunc(value, noopCtx)) {
|
|---|
| 206 | return null;
|
|---|
| 207 | }
|
|---|
| 208 | var detailCtx = new util_1.DetailContext();
|
|---|
| 209 | checkerFunc(value, detailCtx);
|
|---|
| 210 | return detailCtx.getErrorDetail(this._path);
|
|---|
| 211 | };
|
|---|
| 212 | Checker.prototype._getMethod = function (methodName) {
|
|---|
| 213 | var ttype = this.props.get(methodName);
|
|---|
| 214 | if (!ttype) {
|
|---|
| 215 | throw new Error("Type has no property " + methodName);
|
|---|
| 216 | }
|
|---|
| 217 | if (!(ttype instanceof types_1.TFunc)) {
|
|---|
| 218 | throw new Error("Property " + methodName + " is not a method");
|
|---|
| 219 | }
|
|---|
| 220 | return ttype;
|
|---|
| 221 | };
|
|---|
| 222 | return Checker;
|
|---|
| 223 | }());
|
|---|
| 224 | exports.Checker = Checker;
|
|---|