UNPKG

container.ts

Version:
249 lines 10.6 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __spreadArrays = (this && this.__spreadArrays) || function () { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; }; Object.defineProperty(exports, "__esModule", { value: true }); var lodash_1 = require("lodash"); var error_1 = require("../error"); var field_1 = require("./field"); /** Schema error codes. */ var ESchemaError; (function (ESchemaError) { ESchemaError["Field"] = "SchemaError.Field"; ESchemaError["Value"] = "SchemaError.Value"; })(ESchemaError = exports.ESchemaError || (exports.ESchemaError = {})); /** Schema error class. */ var SchemaError = /** @class */ (function (_super) { __extends(SchemaError, _super); function SchemaError(code, cause, context) { var _this = _super.call(this, { name: "SchemaError", value: __assign({ code: code }, context) }, cause) || this; _this.isSchemaError = true; return _this; } return SchemaError; }(error_1.ErrorChain)); exports.SchemaError = SchemaError; var Schema = /** @class */ (function () { function Schema(schema) { this.schema = schema; /** Used for isSchema static method. */ this.isSchema = true; } /** Returns true if input instance of Schema. */ Schema.isSchema = function (schema) { var instanceOf = schema instanceof Schema; var hasProperty = !!schema.isSchema; return instanceOf || hasProperty; }; /** Returns true if input instance of SchemaError. */ Schema.isSchemaError = function (error) { var instanceOf = error instanceof SchemaError; var hasProperty = !!error.isSchemaError; return instanceOf || hasProperty; }; /** * Construct new schema by merging existing schemas. * Accepts schema definition objects or existing Schema class instances. */ Schema.extend = function () { var schemas = []; for (var _i = 0; _i < arguments.length; _i++) { schemas[_i] = arguments[_i]; } var schemaDefinitions = schemas.map(function (s) { return Schema.isSchema(s) ? s.schema : s; }); return new Schema(lodash_1.assign.apply(void 0, __spreadArrays([{}], schemaDefinitions))); }; /** * Construct new schema using this as a base. * Accepts schema definition objects or existing Schema class instances. */ Schema.prototype.extend = function () { var schemas = []; for (var _i = 0; _i < arguments.length; _i++) { schemas[_i] = arguments[_i]; } return Schema.extend.apply(Schema, __spreadArrays([this.schema], schemas)); }; /** Validate input data, transform strings to typed values. */ Schema.prototype.validate = function (data, mask, parentKey, schema) { if (parentKey === void 0) { parentKey = ""; } if (schema === void 0) { schema = this.schema; } var validated = lodash_1.isArray(schema) ? [] : {}; this.map(data, validated, schema, Schema.mapValidateHandlers, mask, parentKey); return validated; }; /** Format input data, transform typed values to object of strings for serialisation. */ Schema.prototype.format = function (data, mask, parentKey, schema) { if (parentKey === void 0) { parentKey = ""; } if (schema === void 0) { schema = this.schema; } var formatted = lodash_1.isArray(schema) ? [] : {}; this.map(data, formatted, schema, Schema.mapFormatHandlers, mask, parentKey); return formatted; }; /** Helper for iterating over schema fields. */ Schema.prototype.map = function (input, output, schema, handlers, mask, parentKey) { var _this = this; if (parentKey === void 0) { parentKey = ""; } if (lodash_1.isArray(schema)) { var schemaArray_1 = schema; if (schemaArray_1[0] === "*") { // Wildcard asterisk, map all data indexes to field. lodash_1.keys(input).map(function (key) { return _this.mapHandler(input, output, mask, parentKey, handlers, schemaArray_1[1], key); }); } else { // Else for each value in schema array. schemaArray_1.map(function (value, index) { return _this.mapHandler(input, output, mask, parentKey, handlers, value, index); }); } } else { var schemaMap_1 = schema; if (schemaMap_1["*"] != null) { // If wildcard asterisk is present, map all data keys to field. lodash_1.keys(input).map(function (key) { return _this.mapHandler(input, output, mask, parentKey, handlers, schemaMap_1["*"], key); }); } else { // Else for each key in schema map. lodash_1.keys(schemaMap_1).map(function (key) { return _this.mapHandler(input, output, mask, parentKey, handlers, schemaMap_1[key], key); }); } } }; Schema.prototype.mapHandler = function (input, output, mask, parentKey, handlers, value, key) { // Key path construction for error messages. var path = parentKey + "." + key; // Handle masked fields if defined. var mapMask; if (mask != null) { if (!lodash_1.get(mask, key, false)) { // Field(s) are masked. return; } else if (lodash_1.isObject(mask[key])) { // Map mask argument. mapMask = mask[key]; } } try { if (value instanceof field_1.Field) { // Value is field class instance. var field = value; handlers.isField(input, output, field, key, mapMask, path); } else if (lodash_1.isArray(value)) { // Value is a schema array object. var schemaArray = value; handlers.isSchemaArray(input, output, this, schemaArray, key, mapMask, path); } else if (lodash_1.isObject(value)) { // Value is schema map object. var schemaMap = value; handlers.isSchemaMap(input, output, this, schemaMap, key, mapMask, path); } else if (value === "*") { // Wildcard asterisk, accept all data. output[key] = input[key]; } else { // Invalid schema field value. throw new SchemaError(ESchemaError.Value, value, { path: path }); } } catch (error) { // Schema error wrapper. if (Schema.isSchemaError(error)) { throw error; } else { throw new SchemaError(ESchemaError.Field, error, { path: path }); } } }; Schema.mapValidateHandlers = { isSchemaArray: function (input, output, schema, array, key, mask, parentKey) { // Make recursive call for internal data arrays. output[key] = schema.validate(input[key], mask, parentKey, array); }, isSchemaMap: function (input, output, schema, map, key, mask, parentKey) { // Make recursive call for internal data maps. output[key] = schema.validate(input[key], mask, parentKey, map); }, isField: function (input, output, field, key, mask, parentKey) { // Call validate method of field, only assign output if defined. var validated = field.validate(input[key], { mask: mask, parentKey: parentKey }); if (validated != null) { output[key] = validated; } } }; Schema.mapFormatHandlers = { isSchemaArray: function (input, output, schema, array, key, mask, parentKey) { // Make recursive call for internal data arrays. output[key] = schema.format(input[key], mask, parentKey, array); }, isSchemaMap: function (input, output, schema, map, key, mask, parentKey) { // Make recursive call for internal data maps. output[key] = schema.format(input[key], mask, parentKey, map); }, isField: function (input, output, field, key, mask, keyRoot) { // Call format method of field. var formatted = field.format(input[key], { mask: mask, keyRoot: keyRoot }); if (formatted != null) { output[key] = formatted; } } }; return Schema; }()); exports.Schema = Schema; var SchemaField = /** @class */ (function (_super) { __extends(SchemaField, _super); function SchemaField(instanceOrSchema) { var _this = _super.call(this) || this; if (Schema.isSchema(instanceOrSchema)) { _this.schema = instanceOrSchema; } else { _this.schema = new Schema(instanceOrSchema); } return _this; } SchemaField.prototype.validate = function (value, context) { if (context === void 0) { context = {}; } return this.schema.validate(value, context.mask, context.parentKey); }; SchemaField.prototype.format = function (value, context) { return this.schema.format(value, context.mask, context.parentKey); }; return SchemaField; }(field_1.Field)); exports.SchemaField = SchemaField; //# sourceMappingURL=schema.js.map