$counts, 'by_category' => $by_category, 'ai_nodes' => $ai_nodes, 'has_ai' => ! empty( $ai_nodes ), 'total' => count( $nodes ), ); } /** * Determines the category for a node slug. * * @since 1.0.0 * @param string $slug Node type slug. * @return string Category name. */ private static function get_category( string $slug ): string { $slug_lower = strtolower( $slug ); // AI check first. foreach ( self::AI_KEYWORDS as $keyword ) { if ( str_contains( $slug_lower, $keyword ) ) { return 'ai'; } } $trigger_slugs = array( 'scheduletrigger', 'webhook', 'manualtrigger', 'formtrigger', 'emailreadimap', 'rssfeadread' ); foreach ( $trigger_slugs as $t ) { if ( str_contains( $slug_lower, 'trigger' ) || str_contains( $slug_lower, 'webhook' ) ) { return 'trigger'; } } $logic_slugs = array( 'if', 'switch', 'filter', 'merge', 'splitinbatches', 'splitout', 'sort', 'limit', 'removeduplicates', 'aggregate', 'comparedatasets', ); foreach ( $logic_slugs as $l ) { if ( $slug_lower === $l ) { return 'logic'; } } $code_slugs = array( 'code', 'function', 'executeworkflow', 'set', 'editfields', 'html', 'xml', 'markdown', 'crypto', 'tofile', 'converttofile', 'extractfromfile', ); foreach ( $code_slugs as $c ) { if ( $slug_lower === $c ) { return 'transform'; } } $db_slugs = array( 'mysql', 'postgres', 'redis', 'mongodb', 'sqlite', 'microsoftsql', 'supabase' ); foreach ( $db_slugs as $d ) { if ( $slug_lower === $d ) { return 'database'; } } return 'action'; } }