Custom permalink structure: /%custom-taxonomy%/%post-name%/ (without CPT slug)

I managed to find a solution

$args   = array(
            'labels'             => $labels,
            'public'             => true,
            'publicly_queryable' => true,
            'show_ui'            => true,
            'show_in_menu'       => true,
            'query_var'          => true,
            'rewrite'            => array ( 'slug' => 'products/%catalogs%', 'with_front' => false),
            'capability_type'    => 'post',
            'has_archive'        => 'products',
            'hierarchical'       => false,
            'menu_position'      => 4,
            'menu_icon'          => 'dashicons-cart',
            'supports'           => array( 'title', 'thumbnail' ),
            'taxonomies'         => array( 'catalogs' ),
        );
    register_post_type( 'products', $args );

    register_taxonomy( 'catalogs', 'products', array(
            'hierarchical'      => true,
            'labels'            => $labels,
            'show_ui'           => true,
            'query_var'         => true,
            'show_admin_column' => true,
            'show_tagcloud'     => false,
            'rewrite'           => array( 'slug' => 'products', 'with_front' => false ),
        ) );

    /** 
Remove taxony slug, remove CPT slug and add new rewrite rule 
*/
function remove_tax_slug_link( $link, $term, $taxonomy ) {
    if ( $taxonomy !== 'catalogs' )
        return $link;

    return str_replace( 'products/', '', $link );
}
add_filter( 'term_link', 'remove_tax_slug_link', 10, 3 );

function custom_tax_rewrite_rule() {
    $cats = get_terms(
            'catalogs', array(
            'hide_empty' => false,
        )
    );
    if( sizeof( $cats ) )
        foreach($cats as $cat)
            add_rewrite_rule( $cat->slug.'/?$', 'index.php?catalogs=".$cat->slug, "top' );
}
add_action('init', 'custom_tax_rewrite_rule');

function change_permalinks( $post_link, $post ) {
    if ( is_object( $post ) && $post->post_type == 'products' ){
        $post_link = str_replace( "https://wordpress.stackexchange.com/" . $post->post_type . "https://wordpress.stackexchange.com/", "https://wordpress.stackexchange.com/", $post_link );
        $terms = wp_get_object_terms( $post->ID, 'catalogs' );
        if( $terms ) {
            return str_replace( '%catalogs%' , $terms[0]->slug , $post_link );
        }
    }
    return $post_link;
}
add_filter( 'post_type_link', 'change_permalinks', 10, 2 );

function entry_rewrite_rules() {
    $custom_structure="/%catalogs%/%products%";
    add_rewrite_tag( '%products%', '([^/]+)', 'products=" );
    add_permastruct( "products', $custom_structure, array( 'walk_dirs' => false ) );

}
add_action( 'init', 'entry_rewrite_rules' );