Skip to content

Generic category composition utility for multi-plugin configurations #1179

@hanna-skryl

Description

@hanna-skryl

User story

As a Code PushUp user, I want a single utility to compose a category from multiple plugins.

Scenarios

  1. Auto-generate: User provides category slug/title only; all groups from all plugins are included.
  2. Custom composition: User provides explicit refs; only those are included.
  3. Multi-URL transparency: Refs automatically expand for plugins with multi-URL configs; single-URL plugins work unchanged.
  4. Mixed plugins: Some plugins have multi-URL, others don't; each expands according to its own context.

Acceptance criteria

  • composeCategory utility in @code-pushup/utils
  • Includes all groups from all plugins when no refs are provided
  • When refs are provided, uses only those refs
  • Expands refs for multi-URL plugins
  • Preserves single-URL or non-URL plugin refs unchanged
  • Type-safe API
  • Works with any combination of plugins
  • Documentation with examples

Implementation details

export const composableCategoryConfigSchema = categoryConfigSchema.partial({
  refs: true,
});
export type ComposableCategoryConfig = z.infer<
  typeof composableCategoryConfigSchema
>;

export function composeCategory(
  plugins: Pick<PluginConfig, 'slug' | 'groups' | 'context'>[],
  category: ComposableCategoryConfig[],
): CategoryConfig;
import { composeCategory } from '@code-pushup/utils';
import axePlugin, { axeGroupRef } from '@code-pushup/axe-plugin';
import lighthousePlugin from '@code-pushup/lighthouse-plugin';

const axe = axePlugin(urls);
const lighthouse = lighthousePlugin(urls);

// All groups from all plugins
categories: [
  composeCategory(
    [axe, lighthouse],
    { slug: 'accessibility', title: 'Accessibility' }
  ),
]

// Cherry-picked refs with custom weights
categories: [
  composeCategory(
    [axe, lighthouse],
    {
      slug: 'accessibility',
      title: 'Accessibility',
      refs: [
        axeGroupRef('aria', 2),
        lighthouseGroupRef('accessibility'),
      ],
    }
  ),
]

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions