UNPKG

fortify-schema

Version:

TypeScript interface-like schema validation system that's easier to use than Zod

129 lines (125 loc) 4.04 kB
'use strict'; var BaseSchema = require('./BaseSchema.js'); /** * Object schema with property validation */ class ObjectSchema extends BaseSchema.BaseSchema { constructor(shape) { super(); this.shape = shape; this._strict = false; this._allowUnknown = true; } /** * Enable strict mode (no extra properties allowed) */ strict() { const cloned = this.clone(); cloned._strict = true; cloned._allowUnknown = false; return cloned; } /** * Allow unknown properties */ allowUnknown(allow = true) { const cloned = this.clone(); cloned._allowUnknown = allow; return cloned; } /** * Validate object value */ validate(value) { // Handle common validation (undefined/null) const commonResult = this.handleCommonValidation(value); if (commonResult) { return commonResult; } const result = { success: true, errors: [], warnings: [], data: undefined, }; // Type check if (typeof value !== "object" || Array.isArray(value)) { result.success = false; result.errors.push("Expected object"); return result; } const validatedObject = {}; const inputKeys = Object.keys(value); const shapeKeys = Object.keys(this.shape); // Validate each property in shape for (const [key, schema] of Object.entries(this.shape)) { const propResult = schema.validate(value[key]); if (!propResult.success) { result.success = false; result.errors.push(`Property '${key}': ${propResult.errors.join(", ")}`); } else if (propResult.data !== undefined) { validatedObject[key] = propResult.data; } // Collect warnings from properties if (propResult.warnings.length > 0) { result.warnings.push(...propResult.warnings.map((w) => `Property '${key}': ${w}`)); } } // Handle extra properties const extraKeys = inputKeys.filter((key) => !shapeKeys.includes(key)); if (extraKeys.length > 0) { if (this._strict) { result.success = false; result.errors.push(`Unexpected properties: ${extraKeys.join(", ")}`); } else if (this._allowUnknown) { // Include unknown properties in result for (const key of extraKeys) { validatedObject[key] = value[key]; } if (extraKeys.length > 0) { result.warnings.push(`Unknown properties included: ${extraKeys.join(", ")}`); } } else { result.warnings.push(`Unknown properties ignored: ${extraKeys.join(", ")}`); } } if (result.success) { result.data = validatedObject; } return result; } /** * Clone the object schema with shape */ clone() { const cloned = new ObjectSchema(this.shape); cloned._strict = this._strict; cloned._allowUnknown = this._allowUnknown; cloned._optional = this._optional; cloned._nullable = this._nullable; cloned._default = this._default; return cloned; } /** * Get schema configuration */ getConfig() { const properties = {}; for (const [key, schema] of Object.entries(this.shape)) { properties[key] = schema.getConfig(); } return { strict: this._strict, allowUnknown: this._allowUnknown, optional: this._optional, nullable: this._nullable, default: this._default, properties, }; } } exports.ObjectSchema = ObjectSchema; //# sourceMappingURL=ObjectSchema.js.map