UNPKG

@axarai/axar

Version:

TypeScript-based agent framework for building agentic applications powered by LLMs

304 lines (303 loc) 9.99 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.uniqueItems = exports.maxItems = exports.minItems = exports.integer = exports.exclusiveMaximum = exports.exclusiveMinimum = exports.multipleOf = exports.maximum = exports.minimum = exports.min = exports.max = exports.ip = exports.datetime = exports.cuid = exports.uuid = exports.pattern = exports.url = exports.email = exports.zodify = void 0; exports.schema = schema; exports.property = property; exports.optional = optional; exports.enumValues = enumValues; exports.arrayItems = arrayItems; const meta_keys_1 = require("./meta-keys"); const utils_1 = require("./utils"); const generator_1 = require("./generator"); /** * Decorates a class for automatic schema generation using Zod. * When applied, it generates and stores a Zod schema based on the class properties * and their decorators. * * @param descriptionOrOptions - Either a description string or a SchemaOptions object * @returns A class decorator * * @example * ```typescript * // Using string description * @schema("User profile information") * class UserProfile { * @property("User's full name") * name: string; * } * * // Using SchemaOptions object * @schema({ * description: "User profile information" * }) * class UserProfile { * @property("User's full name") * name: string; * } * ``` */ function schema(descriptionOrOptions = {}) { return function (target) { let options; if (typeof descriptionOrOptions === 'string') { options = { description: descriptionOrOptions }; } else { options = descriptionOrOptions; } Reflect.defineMetadata(meta_keys_1.META_KEYS.SCHEMA, options, target); // Generate and store the Zod schema const zodSchema = (0, generator_1.toZodSchema)(target); Reflect.defineMetadata(meta_keys_1.META_KEYS.SCHEMA_DEF, zodSchema, target); return target; }; } /** Alias for {@link schema} decorator, use if conflicts with Zod */ exports.zodify = schema; /** * Adds metadata to a class property. This can include descriptions and examples * that will be included in the generated schema. * * @param descriptionOrOptions - Either a description string or a PropertyOptions object * @returns A property decorator * * @example * ```typescript * class User { * // Using string description * @property("User's full name") * name: string; * * // Using PropertyOptions object * @property({ * description: "User's age in years", * example: 25 * }) * age: number; * } * ``` */ function property(descriptionOrOptions) { return function (target, propertyKey) { (0, utils_1.registerProperty)(target, propertyKey); let options; if (typeof descriptionOrOptions === 'string') { options = { description: descriptionOrOptions }; } else { options = descriptionOrOptions; } Reflect.defineMetadata(meta_keys_1.META_KEYS.PROPERTY, options, target, propertyKey); }; } /** * Marks a class property as optional in the generated schema. * Optional properties can be undefined or omitted when creating instances. * * @returns A property decorator * * @example * ```typescript * class UserSettings { * @optional() * @description("Preferred theme (defaults to system)") * theme?: 'light' | 'dark'; * * @optional() * @example("en-US") * language?: string; * } * ``` */ function optional() { return function (target, propertyKey) { (0, utils_1.registerProperty)(target, propertyKey); Reflect.defineMetadata(meta_keys_1.META_KEYS.OPTIONAL, true, target, propertyKey); }; } /** * Creates a validation decorator with proper type checking * @param type - The type of validation rule * @param params - Optional parameters for the validation rule */ function createValidationDecorator(type, params) { return function (target, propertyKey) { (0, utils_1.registerProperty)(target, propertyKey); (0, utils_1.addValidationRule)(target, propertyKey, { type, params, }); }; } /** * Decorates a property with enum validation * @param values - Array of valid enum values * * @example * ```typescript * class User { * @enumValues(['admin', 'user', 'guest']) * role: string; * } * ``` */ function enumValues(values) { return function (target, propertyKey) { if (!Array.isArray(values) || values.length === 0) { throw new Error('Enum values must be a non-empty array'); } (0, utils_1.registerProperty)(target, propertyKey); Reflect.defineMetadata(meta_keys_1.META_KEYS.ENUM_VALUES, values, target, propertyKey); (0, utils_1.addValidationRule)(target, propertyKey, { type: 'enum', params: [values], }); }; } /** * Decorates an array property with item type information * @param itemType - Function returning the item type * * @example * ```typescript * class PostList { * @arrayItems(() => Post) * items: Post[]; * } * ``` */ function arrayItems(itemType) { return function (target, propertyKey) { if (typeof itemType !== 'function') { throw new Error('Item type must be a function returning a constructor'); } (0, utils_1.registerProperty)(target, propertyKey); Reflect.defineMetadata(meta_keys_1.META_KEYS.ARRAY_ITEM_TYPE, itemType, target, propertyKey); }; } /** * Validates that a string property is a valid email address. * @example * ```ts * class User { * @email() * email: string; * } * ``` */ const email = () => createValidationDecorator('email'); exports.email = email; /** * Validates that a string property is a valid URL. * @example `@url() website: string;` */ const url = () => createValidationDecorator('url'); exports.url = url; /** * Validates that a string property matches the given regular expression pattern. * @param regex - The regular expression to test against * @example `@pattern(/^[A-Z]{2}\d{3}$/) code: string;` */ const pattern = (regex) => createValidationDecorator('pattern', [regex]); exports.pattern = pattern; /** * Validates that a string property is a valid UUID. * @example `@uuid() id: string;` */ const uuid = () => createValidationDecorator('uuid'); exports.uuid = uuid; /** * Validates that a string property is a valid CUID. * @example `@cuid() id: string;` */ const cuid = () => createValidationDecorator('cuid'); exports.cuid = cuid; /** * Validates that a string property is a valid ISO datetime string. * @example `@datetime() createdAt: string;` */ const datetime = () => createValidationDecorator('datetime'); exports.datetime = datetime; /** * Validates that a string property is a valid IP address. * @example `@ip() serverAddress: string;` */ const ip = () => createValidationDecorator('ip'); exports.ip = ip; /** * Validates that a string's length is at most the specified value. * @param value - Maximum length allowed * @example `@max(100) description: string;` */ const max = (value) => createValidationDecorator('max', [value]); exports.max = max; /** * Validates that a string's length is at least the specified value. * @param value - Minimum length required * @example `@min(3) username: string;` */ const min = (value) => createValidationDecorator('min', [value]); exports.min = min; // Number validation decorators /** * Validates that a number is greater than or equal to the specified value. * @param value - Minimum value allowed (inclusive) * @example `@minimum(0) price: number;` */ const minimum = (value) => createValidationDecorator('minimum', [value]); exports.minimum = minimum; /** * Validates that a number is less than or equal to the specified value. * @param value - Maximum value allowed (inclusive) * @example `@maximum(100) percentage: number;` */ const maximum = (value) => createValidationDecorator('maximum', [value]); exports.maximum = maximum; /** * Validates that a number is a multiple of the specified value. * @param value - The number must be divisible by this value * @example `@multipleOf(5) quantity: number;` */ const multipleOf = (value) => createValidationDecorator('multipleOf', [value]); exports.multipleOf = multipleOf; /** * Validates that a number is strictly greater than the specified value. * @param value - Minimum value allowed (exclusive) * @example `@exclusiveMinimum(0) positiveNumber: number;` */ const exclusiveMinimum = (value) => createValidationDecorator('exclusiveMinimum', [value]); exports.exclusiveMinimum = exclusiveMinimum; /** * Validates that a number is strictly less than the specified value. * @param value - Maximum value allowed (exclusive) * @example `@exclusiveMaximum(100) score: number;` */ const exclusiveMaximum = (value) => createValidationDecorator('exclusiveMaximum', [value]); exports.exclusiveMaximum = exclusiveMaximum; /** * Validates that a number is an integer (no decimal places). * @example `@integer() age: number;` */ const integer = () => createValidationDecorator('integer'); exports.integer = integer; // Array validation decorators /** * Validates that an array has at least the specified number of items. * @param min - Minimum number of items required * @example `@minItems(1) tags: string[];` */ const minItems = (min) => createValidationDecorator('minItems', [min]); exports.minItems = minItems; /** * Validates that an array has at most the specified number of items. * @param max - Maximum number of items allowed * @example `@maxItems(10) selections: string[];` */ const maxItems = (max) => createValidationDecorator('maxItems', [max]); exports.maxItems = maxItems; /** * Validates that all items in an array are unique. * @example `@uniqueItems() categories: string[];` */ const uniqueItems = () => createValidationDecorator('uniqueItems'); exports.uniqueItems = uniqueItems;