UNPKG

@hotmeshio/hotmesh

Version:

Permanent-Memory Workflows & AI Agents

148 lines (147 loc) 5.38 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Validator = void 0; const pipe_1 = require("../pipe"); class Validator { constructor(manifest) { this.manifest = null; this.activityIds = []; this.mappingStatements = {}; this.store = null; this.manifest = manifest; } /** * validate the manifest file */ async validate(store) { this.store = store; this.getMappingStatements(); this.validateActivityIds(); this.validateReferencedActivityIds(); this.validateMappingStatements(); this.validateTransitions(); this.validateTransitionConditions(); this.validateStats(); this.validateSchemas(); this.validateUniqueHandledTopics(); this.validateGraphPublishSubscribe(); this.validateHooks(); this.validateConditionalStatements(); } // 1.1) Validate the manifest file activity ids are unique (no duplicates) validateActivityIds() { const activityIdsSet = new Set(); this.manifest.app.graphs.forEach((graph) => { const ids = Object.keys(graph.activities); // Check for duplicates and add ids to the set ids.forEach((id) => { if (activityIdsSet.has(id)) { throw new Error(`Duplicate activity id found: ${id}`); } else { activityIdsSet.add(id); } }); }); this.activityIds = Array.from(activityIdsSet); } isMappingStatement(value) { return (typeof value === 'string' && value.startsWith('{') && value.endsWith('}')); } extractMappingStatements(obj, result, currentActivityId) { for (const key in obj) { if (typeof obj[key] === 'object' && obj[key] !== null) { this.extractMappingStatements(obj[key], result, currentActivityId); } else if (this.isMappingStatement(obj[key])) { if (!result[currentActivityId]) { result[currentActivityId] = []; } result[currentActivityId].push(obj[key]); } } } getMappingStatements() { const mappingStatements = {}; this.manifest.app.graphs.forEach((graph) => { const activities = graph.activities; for (const activityId in activities) { const activity = activities[activityId]; this.extractMappingStatements(activity, mappingStatements, activityId); } }); this.mappingStatements = mappingStatements; } // 1.2) Validate no activity ids are referenced that don't exist validateReferencedActivityIds() { // get list of all mapping statements and validate const mappingStatements = this.mappingStatements; const activityIds = this.activityIds; for (const activity in mappingStatements) { const statements = mappingStatements[activity]; statements.forEach((statement) => { if (statement.startsWith('{') && statement.endsWith('}')) { const statementParts = statement.slice(1, -1).split('.'); const referencedActivityId = statementParts[0]; if (!(Validator.SYS_VARS.includes(referencedActivityId) || activityIds.includes(referencedActivityId) || this.isFunction(statement) || this.isContextVariable(statement))) { throw new Error(`Mapping statement references non-existent activity: ${statement}`); } } }); } } isFunction(value) { return value.startsWith('{@') && pipe_1.Pipe.resolveFunction(value); } isContextVariable(value) { return ['{$input}', '{$output}', '{$item}', '{$key}', '{$index}'].includes(value); } // 1.3) Validate the mapping/@pipe statements are valid validateMappingStatements() { // Implement the method content } // 1.4) Validate the transitions are valid validateTransitions() { // Implement the method content } // 1.5) Validate the transition conditions are valid validateTransitionConditions() { // Implement the method content } // 1.6) Validate the stats validateStats() { // Implement the method content } // 1.7) Validate the schemas validateSchemas() { // Implement the method content } // 1.8) Validate the topics are unique and handled validateUniqueHandledTopics() { // Implement the method content } // 1.9) Validate that every graph has publishes and subscribes validateGraphPublishSubscribe() { // Implement the method content } // 1.10) Validate hooks, including mapping statements validateHooks() { // Implement the method content } // 1.11) Validate conditional statements validateConditionalStatements() { // Implement the method content } } exports.Validator = Validator; Validator.SYS_VARS = ['$app', '$self', '$graph', '$job']; Validator.CONTEXT_VARS = [ '{$input}', '{$output}', '{$item}', '{$key}', '{$index}', ];