@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.
3 lines (2 loc) • 18.7 kB
JavaScript
/*! AIML Parser SDK v2.0.1 - Updated to match UI validator exactly - github.com/meta-aiml-org/SDK */
(((root,factory)=> {if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=factory()}else if(typeof define==="function"&&define.amd){define([],factory)}else{root.AIMLParser=factory()}})(typeof self!=="undefined"?self:this,()=> {const AIML_CONTEXT="https://schemas.meta-aiml.org/v2.0.1/context.jsonld",AIML_VERSION="2.0.1",BASE_CATEGORIES=["organization","product_offering","service","creative_work","community","financial_product"],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"]},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"]},SUBCATEGORY_VALIDATION_RULES={professional_services:{allowedCategories:["service"],description:"Professional and business services"},event_platform:{allowedCategories:["creative_work","service"],description:"Event organization and management platforms"},physical_product:{allowedCategories:["product_offering"],description:"Physical goods and products"},website_services:{allowedCategories:["service"],description:"Website development and maintenance services"},gaming_platform:{allowedCategories:["creative_work"],description:"Gaming and interactive entertainment platforms"}},AVAILABLE_MODULES=["auth","compliance","location","logistics","multilingual","notification","payments","recommendations","search","security","streaming","subscription","user-management","warranty"],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"],dating_platform:["auth","user-management"]};class AIMLParser{constructor(e={}){this.config={debug:e.debug||!1,strict:e.strict||!1,version:e.version||AIML_VERSION},this.errors=[],this.warnings=[],this.suggestions=[]}validate(e){if(this.errors=[],this.warnings=[],this.suggestions=[],null===e)return this._addError("input","Input data is null","structure","Provide a valid AIML schema object or JSON string"),this._buildResult(!1,null);if(void 0===e)return this._addError("input","Input data is undefined","structure","Provide a valid AIML schema object or JSON string"),this._buildResult(!1,null);if(""===e||"string"==typeof e&&""===e.trim())return this._addError("input","Input data is empty","structure","Provide a valid AIML schema object or JSON string"),this._buildResult(!1,null);let t;try{t="string"==typeof e?JSON.parse(e):e}catch(e){return this._addError("JSON","Invalid JSON syntax","structure","Please check for missing commas, brackets, or quotes"),this._buildResult(!1,null)}this._validateRequiredFields(t),this._validateContext(t),this._validateVersioning(t),this._validateEntityStructure(t),this._validateNames(t),this._validateModules(t),this._validateEntityCapabilities(t),this._validateSiteCapabilities(t),this._validateBestPractices(t);const s=this._extractEntityInfo(t),i=0===this.errors.length;return this._buildResult(i,s,t)}isValid(e){return this.validate(e).isValid}getEntityInfo(e){return this.validate(e).entityInfo}_validateRequiredFields(e){["@context","@id","@type","schemaVersion","entityType","entityCategory","name","description"].forEach(t=>{e[t]||this._addError(t,`Critical required field '${t}' is missing`,"structure",`Add the ${t} field to your schema (required for v2.0.1 compliance)`)}),["url","shortDescription"].forEach(t=>{e[t]||this._addWarning(t,`Strongly recommended field '${t}' is missing`,"best_practice",`Add ${t} for better schema completeness and usability`)}),["entityCapabilities","siteCapabilities"].forEach(t=>{e[t]||this._addWarning(t,`NEW v2.0.1 field '${t}' is missing`,"semantic",`Add ${t} - new requirement in v2.0.1 for comprehensive entity description`)}),e.entityCategory&&("organization"===e.entityCategory?e.foundingDate||this._addWarning("foundingDate","foundingDate is required for organization entities","schema","Add foundingDate in ISO 8601 format (YYYY-MM-DD)"):"product_offering"===e.entityCategory?e.properties||this._addWarning("properties","properties object is required for product_offering entities","schema","Add properties object with product/offering characteristics"):"service"===e.entityCategory?e.serviceType||this._addSuggestion("serviceType","serviceType is recommended for service entities","schema","Add serviceType to specify the type of service provided"):"creative_work"===e.entityCategory&&(e.properties||this._addSuggestion("properties","properties object is recommended for creative_work entities","schema","Add properties object with content characteristics")))}_validateContext(e){e["@context"]?e["@context"]!==AIML_CONTEXT&&this._addError("@context","Invalid @context value - must be exact","structure",`Use exactly "${AIML_CONTEXT}" for AIML v2.0.1 schemas`):this._addError("@context","@context is required for JSON-LD compliance","structure",`Add "@context": "${AIML_CONTEXT}"`)}_validateVersioning(e){e.schemaVersion?e.schemaVersion!==AIML_VERSION&&this._addError("schemaVersion",`Invalid schema version: ${e.schemaVersion}`,"schema",`Must be exactly "${AIML_VERSION}" for current META-AIML compliance`):this._addError("schemaVersion","schemaVersion is required for v2.0.1 compliance","structure",`Add "schemaVersion": "${AIML_VERSION}"`)}_validateEntityStructure(e){if(e.entityCategory&&!BASE_CATEGORIES.includes(e.entityCategory)&&this._addError("entityCategory",`Invalid entity category: ${e.entityCategory}`,"schema",`Use one of: ${BASE_CATEGORIES.join(", ")}`),e.entityType&&e.entityCategory){const t=ENTITY_TYPES[e.entityCategory]||[];t.length>0&&!t.includes(e.entityType)&&this._addError("entityType",`Entity type '${e.entityType}' is not valid for category '${e.entityCategory}'`,"schema",`Valid types for ${e.entityCategory}: ${t.join(", ")}`)}if(e.subcategory){const t=Object.keys(SUBCATEGORIES);if(t.includes(e.subcategory)||this._addWarning("subcategory",`Subcategory '${e.subcategory}' might not be standard`,"schema",`Common subcategories: ${t.join(", ")}`),e.entityCategory&&SUBCATEGORY_VALIDATION_RULES[e.subcategory]){const t=SUBCATEGORY_VALIDATION_RULES[e.subcategory];t.allowedCategories.includes(e.entityCategory)||this._addError("subcategory",`Subcategory '${e.subcategory}' is not valid for category '${e.entityCategory}'`,"schema",`Valid categories for ${e.subcategory}: ${t.allowedCategories.join(", ")}`)}if(e.entityType&&SUBCATEGORIES[e.subcategory]){const t=SUBCATEGORIES[e.subcategory];t.includes(e.entityType)||this._addError("entityType",`Entity type '${e.entityType}' is not valid for subcategory '${e.subcategory}'`,"schema",`Valid types for ${e.subcategory}: ${t.join(", ")}`)}}}_validateNames(e){if(e.name)if("string"==typeof e.name)this._addError("name","name must be a multilingual object in v2.0.1","structure",'Convert to object format: {"en": "Your Name", "es": "Tu Nombre"}');else if("object"==typeof e.name){e.name.en||this._addError("name","English name (en) is required in multilingual names","structure",'Add "en" field - English is required for international compatibility'),Object.keys(e.name).forEach(t=>{/^[a-z]{2}(-[A-Z]{2})?$/.test(t)||this._addWarning("name",`Language code '${t}' might not be valid ISO 639-1 format`,"best_practice",'Use ISO 639-1 language codes (e.g., "en", "es", "fr", "en-US")'),e.name[t]&&""!==e.name[t].trim()||this._addWarning("name",`Empty name value for language '${t}'`,"structure","Provide meaningful names for all declared languages")})}if(e.description)if("string"==typeof e.description)this._addError("description","description must be a multilingual object in v2.0.1","structure",'Convert to object format: {"en": "Your Description"}');else if("object"==typeof e.description){e.description.en||this._addError("description","English description (en) is required","structure",'Add "en" field - English description is mandatory'),e.description.en&&e.description.en.length<50&&this._addWarning("description","English description should be at least 50 characters","best_practice","Provide detailed description for better understanding and SEO"),Object.keys(e.description).forEach(t=>{e.description[t]&&""!==e.description[t].trim()||this._addWarning("description",`Empty description value for language '${t}'`,"structure","Provide meaningful descriptions for all declared languages")})}}_validateModules(e){if(e.entityType&&REQUIRED_MODULES[e.entityType]){const t=REQUIRED_MODULES[e.entityType],s=e.modules?Object.keys(e.modules):[];t.forEach(i=>{s.includes(i)||this._addError("modules",`Required module '${i}' is missing for ${e.entityType}`,"schema",`${e.entityType} entities must include: ${t.join(", ")}`)})}e.modules?Object.keys(e.modules).forEach(t=>{AVAILABLE_MODULES.includes(t)||this._addWarning("modules",`Module '${t}' is not a standard AIML module`,"schema",`Standard modules: ${AVAILABLE_MODULES.join(", ")}`);const s=e.modules[t];s&&"object"==typeof s&&(s.version||this._addWarning(`modules.${t}`,"Module should include version field","best_practice",'Add version "2.0.1" for compatibility tracking'),void 0===s.enabled&&this._addSuggestion(`modules.${t}`,"Consider adding enabled field to module","best_practice",'Add "enabled": true/false for better module management'),s.version&&"2.0.1"!==s.version&&this._addWarning(`modules.${t}`,`Module version ${s.version} might not be current`,"schema",'Consider using version "2.0.1" for latest features'))}):e.entityType&&REQUIRED_MODULES[e.entityType]&&this._addError("modules",`Missing modules section - ${e.entityType} requires modules`,"schema",`Add modules section with required modules: ${REQUIRED_MODULES[e.entityType].join(", ")}`)}_validateEntityCapabilities(e){if(e.entityCapabilities){const t=e.entityCapabilities;if(t.functionalFeatures){Object.entries(t.functionalFeatures).forEach(([e,t])=>{"boolean"!=typeof t&&this._addError("entityCapabilities",`functionalFeatures.${e} should be boolean, got ${typeof t}`,"semantic","Use true/false values for objective, verifiable business features")});Object.keys(t.functionalFeatures).length<3&&this._addSuggestion("entityCapabilities","Consider adding more functionalFeatures for comprehensive business description","semantic","Add more objective capabilities like acceptsReservations, hasDelivery, acceptsCreditCards, etc.")}else this._addWarning("entityCapabilities","Missing functionalFeatures - these define objective business capabilities","semantic","Add functionalFeatures object with boolean values for entity capabilities (NEW in v2.0.1)");t.contentTypes&&Array.isArray(t.contentTypes)?0===t.contentTypes.length&&this._addWarning("entityCapabilities","contentTypes array is empty - add available content types","semantic"):this._addWarning("entityCapabilities","Missing contentTypes array - define what content types are available","semantic",'Add contentTypes array (e.g., ["menu", "photos", "reviews", "support"])'),t.businessModel||this._addSuggestion("entityCapabilities","Consider adding businessModel for better business categorization","semantic",'Add businessModel (e.g., "restaurant", "marketplace", "subscription")'),!0===t.functionalFeatures?.supportsOnlinePayments&&(t.paymentMethods&&Array.isArray(t.paymentMethods)||this._addSuggestion("entityCapabilities","Since online payments are supported, add paymentMethods array","semantic",'Add paymentMethods array (e.g., ["credit_card", "paypal", "digital_wallet"])'))}else this._addWarning("entityCapabilities","Missing entityCapabilities - required in v2.0.1 for objective business features","semantic","Add entityCapabilities with functionalFeatures, contentTypes, and businessModel (NEW in v2.0.1)")}_validateSiteCapabilities(e){if(e.siteCapabilities){const t=e.siteCapabilities;t.availableActions&&Array.isArray(t.availableActions)?0===t.availableActions.length&&this._addWarning("siteCapabilities","availableActions array is empty - add user interaction possibilities","semantic"):this._addWarning("siteCapabilities","Missing availableActions array - define what users can do on the site","semantic",'Add availableActions array (e.g., ["view_menu", "make_reservation", "order_delivery"]) - NEW in v2.0.1'),t.interactionMethods&&Array.isArray(t.interactionMethods)||this._addWarning("siteCapabilities","Missing interactionMethods - define how users interact with business","semantic",'Add interactionMethods array (e.g., ["online_form", "phone_call", "email"])'),t.contentAccess&&Array.isArray(t.contentAccess)||this._addSuggestion("siteCapabilities","Add contentAccess array for content accessibility levels","semantic",'Add contentAccess (e.g., ["public", "members_only"])'),t.supportedDevices&&Array.isArray(t.supportedDevices)||this._addWarning("siteCapabilities","Missing supportedDevices - important for accessibility information","semantic",'Add supportedDevices array (e.g., ["desktop", "mobile", "tablet"])'),t.languages&&Array.isArray(t.languages)||this._addWarning("siteCapabilities","Missing languages array - define interface languages","semantic",'Add languages array for internationalization (e.g., ["en", "es"])'),t.realTimeFeatures||this._addSuggestion("siteCapabilities","Consider adding realTimeFeatures if site has real-time functionality","semantic",'Add realTimeFeatures array if applicable (e.g., ["real_time_availability", "instant_booking"])')}else this._addWarning("siteCapabilities","Missing siteCapabilities - required in v2.0.1 for website interaction features","semantic","Add siteCapabilities with availableActions, interactionMethods, and supportedDevices (NEW in v2.0.1)")}_validateBestPractices(e){e.url&&!/^https?:\/\/.+/.test(e.url)&&this._addWarning("url","URL should start with http:// or https://","best_practice");if(e.description){const t="string"==typeof e.description?e.description:e.description.en;t&&t.length<50&&this._addSuggestion("description","Description is quite short, consider adding more detail","best_practice","Aim for at least 50-100 characters for better SEO and understanding")}}_extractEntityInfo(e){if(!e.entityType||!e.entityCategory)return null;const t=e.modules?Object.keys(e.modules):[];return{entityType:e.entityType,entityCategory:e.entityCategory,subcategory:e.subcategory,baseSchema:e.entityCategory,modules:t,hasEntityCapabilities:!!e.entityCapabilities,hasSiteCapabilities:!!e.siteCapabilities}}_buildResult(e,t,s){return{isValid:e,errors:this.errors,warnings:this.warnings,suggestions:this.suggestions,entityInfo:t,score:this._calculateScore(s),completeness:this._calculateCompleteness(s),performance:this._calculatePerformance(s)}}_calculateScore(e){const t=30*this.errors.length+10*this.warnings.length+5*this.suggestions.length,s=Math.max(0,100-t);if(0===this.warnings.length){const t=this._calculateCompleteness(e);return Math.min(100,Math.max(90,90+.1*t))}return this.errors.length>0?this.errors.length>3?Math.max(25,s):Math.max(50,s):Math.max(50,s)}_calculateCompleteness(e){if(!e)return 0;const t=["@context","@id","@type","schemaVersion","entityType","entityCategory","subcategory","name","description"],s=["url","shortDescription","logo"],i=["entityCapabilities","siteCapabilities"],a=["properties","modules","foundingDate","lastModified"];let r=0,n=0;const o=50;r+=o;let l=0;t.forEach(t=>{if(void 0!==e[t])if("name"===t||"description"===t){if("object"==typeof e[t]&&null!==e[t]){const s=e[t];s.en&&s.en.length>0&&("description"===t&&s.en.length>=50||"name"===t)&&l++}}else l++}),n+=l/t.length*o;const d=25;r+=d;let c=0;s.forEach(t=>{void 0!==e[t]&&("url"===t?e[t]&&(e[t].startsWith("http://")||e[t].startsWith("https://"))&&c++:c++)}),n+=c/s.length*d;const u=15;r+=u;let g=0;i.forEach(t=>{if(void 0!==e[t]){const s=e[t];s&&Object.keys(s).length>0&&g++}}),n+=g/i.length*u;const _=10;r+=_;let h=0;return a.forEach(t=>{if(void 0!==e[t])if("modules"===t){const t=e.modules;t&&Object.keys(t).length>0&&h++}else h++}),n+=h/a.length*_,Math.round(n/r*100)}_calculatePerformance(e){if(!e)return{schemaSize:0,complexity:"low",moduleCount:0};const t=JSON.stringify(e).length,s=e.modules?Object.keys(e.modules).length:0;let i="low";return s>5||t>5e3?i="high":(s>2||t>2e3)&&(i="medium"),{schemaSize:t,complexity:i,moduleCount:s}}_addError(e,t,s,i){this.errors.push({field:e,message:t,severity:"error",category:s,suggestion:i})}_addWarning(e,t,s,i){this.warnings.push({field:e,message:t,severity:"warning",category:s,suggestion:i})}_addSuggestion(e,t,s,i){this.suggestions.push({field:e,message:t,severity:"info",category:s,suggestion:i})}}AIMLParser.validate=(e,t={})=>new AIMLParser(t).validate(e),AIMLParser.createProduction=()=>new AIMLParser({debug:!1,strict:!0}),AIMLParser.createDevelopment=()=>new AIMLParser({debug:!0,strict:!1}),AIMLParser.getVersion=()=>AIML_VERSION,AIMLParser.getEntityTypes=()=>{const e=[];return Object.values(ENTITY_TYPES).forEach(t=>{e.push(...t)}),e.sort()},AIMLParser.getEntityCategories=()=>BASE_CATEGORIES,AIMLParser.getModules=()=>AVAILABLE_MODULES,AIMLParser.getSubcategories=()=>Object.keys(SUBCATEGORIES),AIMLParser.getRequiredModules=e=>e&&"string"==typeof e?REQUIRED_MODULES[e]||[]:[],AIMLParser.validateConfig=e=>e&&"object"==typeof e;return AIMLParser}));