UNPKG

@meta-aiml/parser

Version:

AIML Parser SDK v2.0.1 - Production-ready schema validation for Meta-AIML.org entity schemas. Supports all 31 entity types with enhanced error handling, universal browser compatibility, and complete API implementation. Zero exceptions, works everywhere.

708 lines (632 loc) 22.6 kB
/** * AIML Parser SDK v2.0.1 - Updated to match UI validator logic exactly * * Complete schema validation for Meta-AIML.org entity schemas. * Supports all 31 entity types across 6 categories with comprehensive validation. * NOW WITH SAME LOGIC AS UI VALIDATOR (META-AIML Intelligent Scoring Engine) * * @version 2.0.1 * @author META-AIML.ORG - IURII IURIEV * @repository https://github.com/meta-aiml-org/SDK * @npm https://www.npmjs.com/package/@meta-aiml/parser * @date 2025-07-02 */ /** * @typedef {Object} AIMLValidationError * @property {string} field - Field with error * @property {string} message - Error message * @property {'error'|'warning'|'info'} severity - Error severity * @property {'structure'|'schema'|'semantic'|'performance'|'best_practice'} category - Error category * @property {string} [suggestion] - Fix suggestion * @property {string} [documentation] - Documentation link * @property {number} [line] - Line number * @property {number} [column] - Column number */ /** * @typedef {Object} AIMLEntityInfo * @property {string} entityType - Entity type * @property {string} entityCategory - Entity category * @property {string} [subcategory] - Subcategory * @property {string} baseSchema - Base schema * @property {string[]} modules - Active modules * @property {boolean} hasEntityCapabilities - Has entity capabilities (v2.0.1) * @property {boolean} hasSiteCapabilities - Has site capabilities (v2.0.1) */ /** * @typedef {Object} AIMLValidationResult * @property {boolean} isValid - Is schema valid * @property {AIMLValidationError[]} errors - Critical errors * @property {AIMLValidationError[]} warnings - Warnings * @property {AIMLValidationError[]} suggestions - Improvement suggestions * @property {AIMLEntityInfo} [entityInfo] - Entity information * @property {number} score - Quality score (0-100) * @property {number} completeness - Completeness score (0-100) * @property {Object} performance - Performance metrics * @property {number} performance.schemaSize - Schema size in bytes * @property {'low'|'medium'|'high'} performance.complexity - Complexity level * @property {number} performance.moduleCount - Number of modules */ /** * @typedef {Object} AIMLSchema * @property {string} [@context] - JSON-LD context * @property {string} [@id] - Unique identifier * @property {string} [@type] - Entity type * @property {string} [schemaVersion] - AIML schema version * @property {string} [entityType] - AIML entity type * @property {string} [entityCategory] - Top-level category * @property {string} [subcategory] - Subcategory * @property {Object} [name] - Multilingual name object (required in v2.0.1) * @property {Object} [description] - Multilingual description object (required in v2.0.1) * @property {string} [url] - URL * @property {string} [shortDescription] - Short description * @property {Object} [properties] - Entity properties * @property {Object} [modules] - Enabled modules * @property {Object} [entityCapabilities] - Entity capabilities (NEW in v2.0.1) * @property {Object} [siteCapabilities] - Site capabilities (NEW in v2.0.1) */ // AIML v2.0.1 specifications - Updated to match UI validator exactly const AIML_CONTEXT = "https://schemas.meta-aiml.org/v2.0.1/context.jsonld"; const AIML_VERSION = "2.0.1"; const BASE_CATEGORIES = [ "organization", "product_offering", "service", "creative_work", "community", "financial_product" ]; const ENTITY_TYPES = { organization: [ "clinic", "education_platform", "fitness_platform", "hotel", "restaurant", "store" ], product_offering: [ "ecommerce_store", "marketplace", "product", "software_product" ], service: [ "business_services", "generative_ai_platform", "real_estate_platform", "ridesharing_service", "task_management_app", "telemedicine_platform", "virtual_event_platform", "web_app", "website_services" ], creative_work: [ "blog", "event", "file_hosting", "gaming_platform", "news", "personal_website", "photo_hosting", "streaming_platform", "video_hosting" ], community: ["dating_platform", "social_network"], financial_product: ["online_banking"] }; const SUBCATEGORIES = { ecommerce_platform: ["ecommerce_store", "marketplace", "store"], hospitality: ["hotel", "restaurant"], healthcare_services: ["clinic", "fitness_platform", "telemedicine_platform"], education_services: ["education_platform"], ai_platform: ["generative_ai_platform"], professional_services: ["business_services"], ridesharing_services: ["ridesharing_service"], website_services: ["website_services"], property_services: ["real_estate_platform"], physical_product: ["product"], digital_product: ["file_hosting", "personal_website", "software_product", "task_management_app", "web_app"], media_entertainment: ["blog", "gaming_platform", "news", "photo_hosting", "streaming_platform", "video_hosting"], social_platform: ["dating_platform", "social_network"], event_platform: ["event", "virtual_event_platform"], financial_services: ["online_banking"] }; // Standard AIML modules (14 total) const STANDARD_MODULES = [ "auth", "payments", "multilingual", "search", "user-management", "location", "streaming", "subscription", "security", "compliance", "logistics", "notification", "recommendations", "warranty" ]; // Required modules by entity type (from required_fields_v2.0.1.md) const REQUIRED_MODULES = { clinic: ["auth", "security", "compliance"], education_platform: ["auth", "user-management"], hotel: ["location", "payments"], restaurant: ["location"], ecommerce_store: ["auth", "payments"], marketplace: ["auth", "payments", "user-management"], generative_ai_platform: ["auth", "security"], ridesharing_service: ["auth", "location"], social_network: ["auth", "user-management"], online_banking: ["auth", "security", "compliance"], telemedicine_platform: ["auth", "security", "compliance", "streaming"] }; // Language code validation pattern const ISO_639_1_PATTERN = /^[a-z]{2}(-[A-Z]{2})?$/; /** * Main AIML Parser class with v2.0.1 validation logic */ class AIMLParser { constructor(options = {}) { this.config = { debug: options.debug || false, strict: options.strict || false, version: options.version || AIML_VERSION, ...options }; } /** * Comprehensive schema validation - main method * @param {Object} data - Schema to validate * @returns {AIMLValidationResult} Validation result */ validate(data) { const errors = []; const warnings = []; const suggestions = []; try { if (!data || typeof data !== "object") { errors.push({ field: "root", message: "Schema must be a valid JSON object", severity: "error", category: "structure", suggestion: "Provide a valid JSON object" }); return { isValid: false, errors, warnings, suggestions, score: 0, completeness: 0, performance: { schemaSize: 0, complexity: "low", moduleCount: 0 } }; } // 1. Critical required fields validation (ERRORS) this._validateRequiredFields(data, errors); // 2. Context and version validation this._validateContextAndVersion(data, errors); // 3. Entity hierarchy validation this._validateEntityHierarchy(data, errors, warnings); // 4. Multilingual validation (v2.0.1 requirement) this._validateMultilingual(data, errors, warnings); // 5. v2.0.1 New fields validation this._validateV201Fields(data, warnings); // 6. Module validation this._validateModules(data, warnings, suggestions); // 7. URL and format validation this._validateFormats(data, warnings, suggestions); // Calculate metrics const entityInfo = this._extractEntityInfo(data); const performance = this._calculatePerformance(data); const completeness = this._calculateCompleteness(data); const score = this._calculateIntelligentScore(errors, warnings, suggestions, completeness); return { isValid: errors.length === 0, errors, warnings, suggestions, entityInfo, score, completeness, performance }; } catch (error) { errors.push({ field: "validation", message: `Validation error: ${error.message}`, severity: "error", category: "structure" }); return { isValid: false, errors, warnings, suggestions, score: 0, completeness: 0, performance: { schemaSize: 0, complexity: "low", moduleCount: 0 } }; } } /** * Validate critical required fields (ERRORS if missing) */ _validateRequiredFields(data, errors) { const requiredFields = ["@context", "@id", "@type", "schemaVersion", "entityType", "entityCategory", "name", "description"]; for (const field of requiredFields) { if (!data[field]) { errors.push({ field, message: `Critical required field '${field}' is missing`, severity: "error", category: "structure", suggestion: `Add the ${field} field to your schema (required for v2.0.1 compliance)` }); } } } /** * Validate @context and schemaVersion (exact match required) */ _validateContextAndVersion(data, errors) { if (data["@context"] && data["@context"] !== AIML_CONTEXT) { errors.push({ field: "@context", message: "Invalid @context value - must be exact", severity: "error", category: "structure", suggestion: `Use exactly "${AIML_CONTEXT}" for AIML v2.0.1 schemas` }); } if (data.schemaVersion && data.schemaVersion !== AIML_VERSION) { errors.push({ field: "schemaVersion", message: `Invalid schema version - expected ${AIML_VERSION}`, severity: "error", category: "structure", suggestion: `Set schemaVersion to "${AIML_VERSION}"` }); } if (!data.schemaVersion) { errors.push({ field: "schemaVersion", message: "schemaVersion is required for v2.0.1 compliance", severity: "error", category: "structure", suggestion: `Add "schemaVersion": "${AIML_VERSION}"` }); } } /** * Validate entity hierarchy */ _validateEntityHierarchy(data, errors, warnings) { if (data.entityCategory && !BASE_CATEGORIES.includes(data.entityCategory)) { errors.push({ field: "entityCategory", message: `Invalid entity category: ${data.entityCategory}`, severity: "error", category: "structure", suggestion: `Use one of: ${BASE_CATEGORIES.join(", ")}` }); } if (data.entityType && data.entityCategory) { const allowedTypes = ENTITY_TYPES[data.entityCategory] || []; if (!allowedTypes.includes(data.entityType)) { errors.push({ field: "entityType", message: `Invalid entity type '${data.entityType}' for category '${data.entityCategory}'`, severity: "error", category: "structure", suggestion: `Use one of: ${allowedTypes.join(", ")}` }); } } // Subcategory validation if (data.subcategory && data.entityType) { const foundSubcategory = Object.keys(SUBCATEGORIES).find(subcat => SUBCATEGORIES[subcat].includes(data.entityType) ); if (foundSubcategory && data.subcategory !== foundSubcategory) { warnings.push({ field: "subcategory", message: `Subcategory mismatch: expected '${foundSubcategory}' for entity type '${data.entityType}'`, severity: "warning", category: "structure", suggestion: `Set subcategory to "${foundSubcategory}"` }); } } } /** * Validate multilingual fields (v2.0.1 requirement) */ _validateMultilingual(data, errors, warnings) { // name must be multilingual object if (data.name) { if (typeof data.name === "string") { errors.push({ field: "name", message: "name must be a multilingual object in v2.0.1", severity: "error", category: "structure", suggestion: 'Convert to object format: {"en": "Your Name", "es": "Tu Nombre"}' }); } else if (typeof data.name === "object") { if (!data.name.en) { warnings.push({ field: "name", message: "English (en) name is recommended", severity: "warning", category: "best_practice", suggestion: 'Add English translation: "en": "English Name"' }); } this._validateLanguageCodes(data.name, "name", warnings); } } // description must be multilingual object if (data.description) { if (typeof data.description === "string") { errors.push({ field: "description", message: "description must be a multilingual object in v2.0.1", severity: "error", category: "structure", suggestion: 'Convert to object format: {"en": "Your Description", "es": "Tu Descripción"}' }); } else if (typeof data.description === "object") { if (!data.description.en) { warnings.push({ field: "description", message: "English (en) description is recommended", severity: "warning", category: "best_practice", suggestion: 'Add English translation: "en": "English Description"' }); } // Check minimum length for English description if (data.description.en && data.description.en.length < 50) { warnings.push({ field: "description", message: "English description should be at least 50 characters", severity: "warning", category: "best_practice", suggestion: "Provide a more detailed English description" }); } this._validateLanguageCodes(data.description, "description", warnings); } } } /** * Validate v2.0.1 new fields */ _validateV201Fields(data, warnings) { if (!data.entityCapabilities) { warnings.push({ field: "entityCapabilities", message: "NEW v2.0.1 field 'entityCapabilities' is missing", severity: "warning", category: "semantic", suggestion: "Add entityCapabilities object with functionalFeatures, contentTypes, businessModel, paymentMethods" }); warnings.push({ field: "entityCapabilities", message: "Missing entityCapabilities - required in v2.0.1 for objective business features", severity: "warning", category: "semantic" }); } if (!data.siteCapabilities) { warnings.push({ field: "siteCapabilities", message: "NEW v2.0.1 field 'siteCapabilities' is missing", severity: "warning", category: "semantic", suggestion: "Add siteCapabilities object with availableActions, interactionMethods, contentAccess, supportedDevices, languages, realTimeFeatures" }); warnings.push({ field: "siteCapabilities", message: "Missing siteCapabilities - required in v2.0.1 for website interaction features", severity: "warning", category: "semantic" }); } } /** * Validate language codes */ _validateLanguageCodes(multilingualObj, fieldName, warnings) { for (const [langCode, value] of Object.entries(multilingualObj)) { if (!ISO_639_1_PATTERN.test(langCode)) { warnings.push({ field: fieldName, message: `Invalid language code: ${langCode}`, severity: "warning", category: "structure", suggestion: "Use valid ISO 639-1 format (e.g., 'en', 'es', 'fr', 'en-US')" }); } if (!value || (typeof value === "string" && value.trim() === "")) { warnings.push({ field: fieldName, message: `Empty value for language '${langCode}'`, severity: "warning", category: "best_practice", suggestion: `Provide content for language '${langCode}' or remove the language` }); } } } /** * Validate modules */ _validateModules(data, warnings, suggestions) { const moduleNames = data.modules ? Object.keys(data.modules) : []; // Check for required modules (always check, even if no modules field) if (data.entityType && REQUIRED_MODULES[data.entityType]) { const required = REQUIRED_MODULES[data.entityType]; const missing = required.filter(mod => !moduleNames.includes(mod)); for (const missingModule of missing) { warnings.push({ field: "modules", message: `Required module '${missingModule}' is missing for entity type '${data.entityType}'`, severity: "warning", category: "structure", suggestion: `Add the '${missingModule}' module for ${data.entityType} entities` }); } } // Check for non-standard modules (only if modules exist) if (data.modules) { const nonStandard = moduleNames.filter(mod => !STANDARD_MODULES.includes(mod)); for (const module of nonStandard) { suggestions.push({ field: "modules", message: `Non-standard module: ${module}`, severity: "info", category: "best_practice", suggestion: `Consider using standard AIML modules: ${STANDARD_MODULES.join(", ")}` }); } } } /** * Validate formats (URLs, etc.) */ _validateFormats(data, warnings, suggestions) { // Recommended fields if (!data.url) { warnings.push({ field: "url", message: "Strongly recommended field 'url' is missing", severity: "warning", category: "best_practice" }); } else { try { new URL(data.url); } catch { warnings.push({ field: "url", message: "Invalid URL format", severity: "warning", category: "structure", suggestion: "Provide a valid HTTP/HTTPS URL" }); } } if (!data.shortDescription) { warnings.push({ field: "shortDescription", message: "Strongly recommended field 'shortDescription' is missing", severity: "warning", category: "best_practice" }); } } /** * Extract entity information */ _extractEntityInfo(data) { if (!data.entityType) return null; const modules = data.modules ? Object.keys(data.modules) : []; const baseSchema = data.entityCategory || "unknown"; return { entityType: data.entityType, entityCategory: data.entityCategory, subcategory: data.subcategory, baseSchema, modules, hasEntityCapabilities: !!data.entityCapabilities, hasSiteCapabilities: !!data.siteCapabilities }; } /** * Calculate performance metrics */ _calculatePerformance(data) { const schemaSize = JSON.stringify(data).length; const moduleCount = data.modules ? Object.keys(data.modules).length : 0; let complexity = "low"; if (moduleCount > 5 || schemaSize > 2000) complexity = "medium"; if (moduleCount > 10 || schemaSize > 5000) complexity = "high"; return { schemaSize, complexity, moduleCount }; } /** * Calculate completeness score */ _calculateCompleteness(data) { const fields = [ "@context", "@id", "@type", "schemaVersion", "entityType", "entityCategory", "subcategory", "name", "description", "url", "shortDescription", "properties", "modules", "entityCapabilities", "siteCapabilities" ]; const present = fields.filter(field => data[field] !== undefined).length; return Math.round((present / fields.length) * 100); } /** * META-AIML Intelligent Scoring Engine v2.0.1 */ _calculateIntelligentScore(errors, warnings, suggestions, completeness) { // Base calculation: 100 - (ERRORS×30 + WARNINGS×10 + SUGGESTIONS×5) let score = 100 - (errors.length * 30 + warnings.length * 10 + suggestions.length * 5); // Intelligent Scoring Engine logic: if (warnings.length === 0 && errors.length === 0) { // No WARNINGS → start from 90 + (completeness × 10%) up to 100 score = Math.max(90, 90 + (completeness * 0.1)); } else if (errors.length > 0 && errors.length <= 3) { // Has ERRORS but ≤3 → minimum 50 points (Good zone) score = Math.max(50, score); } else if (errors.length > 3) { // Many ERRORS >3 → can fall to Poor zone (floor at 25 points) score = Math.max(25, score); } return Math.round(Math.max(0, Math.min(100, score))); } /** * Quick validation method */ isValid(data) { return this.validate(data).isValid; } /** * Extract entity info only */ getEntityInfo(data) { try { return this._extractEntityInfo(data); } catch { return null; } } // Static methods static validate(data, options = {}) { const parser = new AIMLParser(options); return parser.validate(data); } static isValid(data, options = {}) { return AIMLParser.validate(data, options).isValid; } static getEntityInfo(data) { const parser = new AIMLParser(); return parser.getEntityInfo(data); } static createProduction() { return new AIMLParser({ debug: false, strict: true }); } static createDevelopment() { return new AIMLParser({ debug: true, strict: false }); } static getVersion() { return AIML_VERSION; } static getEntityTypes() { return Object.values(ENTITY_TYPES).flat(); } static getEntityCategories() { return BASE_CATEGORIES; } static getModules() { return STANDARD_MODULES; } static getRequiredModules(entityType) { return REQUIRED_MODULES[entityType] || []; } static validateConfig(config) { return config !== null && typeof config === "object"; } } // Export for both CommonJS and ES modules if (typeof module !== "undefined" && module.exports) { // eslint-disable-next-line @next/next/no-assign-module-variable module.exports = AIMLParser; } else if (typeof window !== "undefined") { window.AIMLParser = AIMLParser; }