fortify-schema
Version:
TypeScript interface-like schema validation system that's easier to use than Zod
210 lines (206 loc) • 5.14 kB
JavaScript
'use strict';
var InterfaceSchema = require('./InterfaceSchema.js');
/**
* TypeScript Interface-like Schema System
*
* The most intuitive way to define schemas - just like TypeScript interfaces!
*
* @example
* ```typescript
* import { Interface } from "fortify-schema";
*
* // Define schema like a TypeScript interface
* const UserSchema = Interface({
* id: "number",
* email: "email",
* name: "string",
* age: "number?", // Optional
* isActive: "boolean?", // Optional
* tags: "string[]?", // Optional array
* role: "admin", // Constant value
* profile: { // Nested object
* bio: "string?",
* avatar: "url?"
* }
* });
*
* // Validate data
* const result = UserSchema.safeParse(userData);
* ```
*/
/**
* Create a schema using TypeScript interface-like syntax with full type inference
*
* @param definition - Schema definition using TypeScript-like syntax
* @param options - Optional validation options
* @returns InterfaceSchema instance with inferred types
*
* @example Basic Usage
* ```typescript
* const UserSchema = Interface({
* id: "number",
* email: "email",
* name: "string",
* age: "number?",
* isActive: "boolean?",
* tags: "string[]?"
* });
*
* // result is fully typed as:
* // SchemaValidationResult<{
* // id: number;
* // email: string;
* // name: string;
* // age?: number;
* // isActive?: boolean;
* // tags?: string[];
* // }>
* const result = UserSchema.safeParse(data);
* ```
*
* @example With Constraints
* ```typescript
* const UserSchema = Interface({
* username: "string(3,20)", // 3-20 characters
* age: "number(18,120)", // 18-120 years
* tags: "string[](1,10)?", // 1-10 tags, optional
* });
* ```
*
* @example Nested Objects
* ```typescript
* const OrderSchema = Interface({
* id: "number",
* customer: {
* name: "string",
* email: "email",
* address: {
* street: "string",
* city: "string",
* zipCode: "string"
* }
* },
* items: [{
* name: "string",
* price: "number",
* quantity: "int"
* }]
* });
* ```
*/
function Interface(definition, options) {
return new InterfaceSchema.InterfaceSchema(definition, options);
}
/**
* Available field types for schema definitions
*/
const FieldTypes = {
// Basic types
STRING: "string",
STRING_OPTIONAL: "string?",
NUMBER: "number",
NUMBER_OPTIONAL: "number?",
BOOLEAN: "boolean",
BOOLEAN_OPTIONAL: "boolean?",
DATE: "date",
DATE_OPTIONAL: "date?",
ANY: "any",
ANY_OPTIONAL: "any?",
// String formats
EMAIL: "email",
EMAIL_OPTIONAL: "email?",
URL: "url",
URL_OPTIONAL: "url?",
UUID: "uuid",
UUID_OPTIONAL: "uuid?",
PHONE: "phone",
PHONE_OPTIONAL: "phone?",
SLUG: "slug",
SLUG_OPTIONAL: "slug?",
USERNAME: "username",
USERNAME_OPTIONAL: "username?",
// Number types
INT: "int",
INT_OPTIONAL: "int?",
POSITIVE: "positive",
POSITIVE_OPTIONAL: "positive?",
FLOAT: "float",
FLOAT_OPTIONAL: "float?",
// Array types
STRING_ARRAY: "string[]",
STRING_ARRAY_OPTIONAL: "string[]?",
NUMBER_ARRAY: "number[]",
NUMBER_ARRAY_OPTIONAL: "number[]?",
BOOLEAN_ARRAY: "boolean[]",
BOOLEAN_ARRAY_OPTIONAL: "boolean[]?",
INT_ARRAY: "int[]",
INT_ARRAY_OPTIONAL: "int[]?",
EMAIL_ARRAY: "email[]",
EMAIL_ARRAY_OPTIONAL: "email[]?",
URL_ARRAY: "url[]",
URL_ARRAY_OPTIONAL: "url[]?",
// Record types
RECORD_STRING_ANY: "record<string,any>",
RECORD_STRING_ANY_OPTIONAL: "record<string,any>?",
RECORD_STRING_STRING: "record<string,string>",
RECORD_STRING_STRING_OPTIONAL: "record<string,string>?",
RECORD_STRING_NUMBER: "record<string,number>",
RECORD_STRING_NUMBER_OPTIONAL: "record<string,number>?",
};
/**
* Quick schema creation helpers
*/
const QuickSchemas = {
/**
* User schema with common fields
*/
User: Interface({
id: "number",
email: "email",
name: "string",
createdAt: "date?",
updatedAt: "date?",
}),
/**
* API response schema
*/
APIResponse: Interface({
success: "boolean",
data: "any?",
errors: "string[]?",
timestamp: "date?",
}),
/**
* Pagination schema
*/
Pagination: Interface({
page: "int",
limit: "int",
total: "int",
hasNext: "boolean?",
hasPrev: "boolean?",
}),
/**
* Address schema
*/
Address: Interface({
street: "string",
city: "string",
state: "string?",
zipCode: "string",
country: "string",
}),
/**
* Contact info schema
*/
Contact: Interface({
email: "email?",
phone: "phone?",
website: "url?",
}),
};
exports.InterfaceSchema = InterfaceSchema.InterfaceSchema;
exports.FieldTypes = FieldTypes;
exports.Interface = Interface;
exports.QuickSchemas = QuickSchemas;
//# sourceMappingURL=Interface.js.map