UNPKG

container.ts

Version:
239 lines 9.66 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var 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 function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); Object.defineProperty(exports, "__esModule", { value: true }); var error_1 = require("../error"); var Field_1 = require("./Field"); /** Schema error class. */ var SchemaError = /** @class */ (function (_super) { __extends(SchemaError, _super); function SchemaError(keys, cause) { return _super.call(this, { name: "SchemaError", value: keys }, cause) || this; } return SchemaError; }(error_1.ErrorChain)); exports.SchemaError = SchemaError; /** Build schema class from input map. */ function buildSchema(schema) { if (schema === void 0) { schema = {}; } var NewSchema = /** @class */ (function (_super) { __extends(NewSchema, _super); function NewSchema() { return _super !== null && _super.apply(this, arguments) || this; } NewSchema.SCHEMA = schema; return NewSchema; }(Schema)); return NewSchema; } exports.buildSchema = buildSchema; var Schema = /** @class */ (function () { function Schema() { } /** * Returns true if value is a Schema class object. * Used to test for child schemas during validation/formatting. */ Schema.isSchema = function (value) { var isFunction = (typeof value === "function"); var hasSchemaProperty = (value.SCHEMA != null); return (isFunction && hasSchemaProperty); }; /** * Helper for iterating over schema fields. */ Schema.map = function (inp, out, schema, mask, dataKeys, keyRoot, handlers) { if (mask === void 0) { mask = null; } if (dataKeys === void 0) { dataKeys = []; } if (keyRoot === void 0) { keyRoot = ""; } if (handlers === void 0) { handlers = {}; } if (Array.isArray(schema)) { var schemaArray_1 = schema; if (schemaArray_1[0] === "*") { // Wildcard asterisk, map all data indexes to field. dataKeys.map(function (key) { Schema.mapHandler(inp, out, mask, keyRoot, handlers, schemaArray_1[1], key); }); } else { // Else for each value in schema array. schemaArray_1.map(function (value, index) { Schema.mapHandler(inp, out, mask, keyRoot, handlers, value, index); }); } } else { var schemaMap_1 = schema; if (schemaMap_1["*"] != null) { // If wildcard asterisk is present, map all data keys to field. dataKeys.map(function (key) { Schema.mapHandler(inp, out, mask, keyRoot, handlers, schemaMap_1["*"], key); }); } else { // Else for each key in schema map. Object.keys(schemaMap_1).map(function (key) { Schema.mapHandler(inp, out, mask, keyRoot, handlers, schemaMap_1[key], key); }); } } }; /** * Validate input data, transform strings to typed values. * All static validation rules are applied, undefined data validation * callbacks must provide a default value, null or throw an error. * @param data Input data. */ Schema.validate = function (data, mask, keyRoot, schema) { if (keyRoot === void 0) { keyRoot = ""; } if (schema === void 0) { schema = this.SCHEMA; } var validated = Array.isArray(schema) ? [] : {}; Schema.map(data, validated, schema, mask, Object.keys(data || {}), keyRoot, Schema.validateMapHandlers); return validated; }; /** * Format input data, transform typed values to object of strings for serialisation. * Classes static format rules are applied where data is available. * @param data Input data. */ Schema.format = function (data, mask, keyRoot, schema) { if (keyRoot === void 0) { keyRoot = ""; } if (schema === void 0) { schema = this.SCHEMA; } var formatted = Array.isArray(schema) ? [] : {}; Schema.map(data, formatted, schema, mask, Object.keys(data || {}), keyRoot, Schema.formatMapHandlers); return formatted; }; /** Internal schema map handler. */ Schema.mapHandler = function (inp, out, mask, keyRoot, handlers, value, key) { // Expand key root. var subkeyRoot = keyRoot + "." + key; // Handle masked fields if defined. var submask; if (mask != null) { if (!mask[key]) { // Field(s) are masked. return; } else if (typeof mask[key] === "object") { // Subfield mask argument. submask = mask[key]; } } try { if (Schema.isSchema(value) && (!!handlers.isSchema)) { // Value is child schema. var childSchema = value; handlers.isSchema(inp, out, childSchema, key, submask, subkeyRoot); } else if ((value instanceof Field_1.Field) && (!!handlers.isField)) { // Value is field class instance. var field = value; handlers.isField(inp, out, field, key); } else if (Array.isArray(value) && (!!handlers.isSchemaArray)) { // Value is a schema array object. var schemaArray = value; handlers.isSchemaArray(inp, out, schemaArray, key, submask, subkeyRoot); } else if ((typeof value === "object") && (!!handlers.isSchemaMap)) { // Value is schema map object. var schemaMap = value; handlers.isSchemaMap(inp, out, schemaMap, key, submask, subkeyRoot); } else if ((typeof value === "string") && (value === "*")) { // Wildcard asterisk, accept all data. out[key] = inp[key]; } else { // Unknown schema field value. throw new SchemaError(subkeyRoot, value); } } catch (error) { // Schema error wrapper. if (error instanceof SchemaError) { throw error; } else { throw new SchemaError(subkeyRoot, error); } } }; /** Schema array or map, override in child classes. */ Schema.SCHEMA = {}; Schema.validateMapHandlers = { isSchemaArray: function (inp, out, array, key, submask, keyRoot) { // Make recursive call for internal data arrays. // Only assign output if array has length. var output = Schema.validate(inp[key], submask, keyRoot, array); if (output.length > 0) { out[key] = output; } }, isSchemaMap: function (inp, out, map, key, submask, keyRoot) { // Make recursive call for internal data maps. // Only assign output if at least one field validated. var output = Schema.validate(inp[key], submask, keyRoot, map); if (Object.keys(output).length > 0) { out[key] = output; } }, isSchema: function (inp, out, schema, key, submask, keyRoot) { // Call static method of child schema. // Only assign output if at least one field validated. var output = schema.validate(inp[key], submask, keyRoot); if (Object.keys(output).length > 0) { out[key] = output; } }, isField: function (inp, out, field, key) { // Call validate method of field. // Only assign output if defined. var output = field.validate(inp[key]); if (output != null) { out[key] = output; } }, }; Schema.formatMapHandlers = { isSchemaArray: function (inp, out, array, key, submask, keyRoot) { // Make recursive call for internal data arrays. var output = Schema.format(inp[key], submask, keyRoot, array); if (output.length > 0) { out[key] = output; } }, isSchemaMap: function (inp, out, map, key, submask, keyRoot) { // Make recursive call for internal data maps. var output = Schema.format(inp[key], submask, keyRoot, map); if (Object.keys(output).length > 0) { out[key] = output; } }, isSchema: function (inp, out, schema, key, submask, keyRoot) { // Call static method if child schema. var output = schema.format(inp[key], submask, keyRoot); if (Object.keys(output).length > 0) { out[key] = output; } }, isField: function (inp, out, field, key) { // Call format method of field. var output = field.format(inp[key]); if (output != null) { out[key] = output; } }, }; return Schema; }()); exports.Schema = Schema; //# sourceMappingURL=Schema.js.map