Skip to content

Conversation

@thatblindgeye
Copy link
Collaborator

@thatblindgeye thatblindgeye commented Jan 20, 2026

Closes #172

Summary by CodeRabbit

  • New Features

    • Added three API endpoints to list token categories, fetch tokens by category (with optional case-insensitive filter), and fetch all tokens grouped by category.
    • Added server-side utilities to extract, group, and filter design tokens.
    • Improved error responses for missing or invalid parameters.
  • Tests

    • Added comprehensive test suites covering responses, status codes, filtering, ordering, and error cases.
  • Documentation

    • Updated OpenAPI spec with new token endpoints and response schemas.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 20, 2026

Walkthrough

Adds new design-token API endpoints and utilities: GET /api/{version}/tokens, GET /api/{version}/tokens/{category}, GET /api/{version}/tokens/all, plus token utilities, OpenAPI entries, and Jest tests covering success, filtering, and error cases.

Changes

Cohort / File(s) Summary
API Routes: Token Endpoints
src/pages/api/[version]/tokens.ts, src/pages/api/[version]/tokens/[category].ts, src/pages/api/[version]/tokens/all.ts
New GET handlers (export const GET) that validate version (400), verify version via fetchApiIndex (404 if missing), retrieve and optionally filter tokens, return JSON, handle errors (500), and set prerender = false.
Token Utilities
src/utils/tokens.ts
New module exporting Token and TokensByCategory and functions: getAllTokens(), getTokenCategories(), getTokensByCategory(), getTokensForCategory(), filterTokens(), filterTokensByCategory(). Implements in-memory caching and case-insensitive substring filtering.
OpenAPI Specification
src/pages/api/openapi.json.ts
Added path entries for /{version}/tokens, /{version}/tokens/{category}, and /{version}/tokens/all with parameters, response schemas, and examples for 200/404 responses.
Test Suites
src/__tests__/pages/api/__tests__/[version]/tokens.test.ts, src/__tests__/pages/api/__tests__/[version]/tokens/[category].test.ts, src/__tests__/pages/api/__tests__/[version]/tokens/all.test.ts
New Jest tests that mock API index, token utilities, and global fetch. Cover 200 responses, filtering behavior (case-insensitive), empty-filter results, 400/404 error cases, headers, and restore mocks after each test.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant APIRoute as API Route Handler
    participant ApiIndex as fetchApiIndex
    participant TokenUtil as Token Utilities
    participant PatternFly as `@patternfly/react-tokens`

    Client->>APIRoute: GET /api/v6/tokens[/all|/{category}]?filter=...
    APIRoute->>APIRoute: Validate params (version, category)
    APIRoute->>ApiIndex: fetchApiIndex(url)
    ApiIndex-->>APIRoute: API index (versions)
    APIRoute->>TokenUtil: getTokenCategories() / getTokensForCategory() / getTokensByCategory()
    TokenUtil->>PatternFly: load token module
    PatternFly-->>TokenUtil: token exports
    TokenUtil->>TokenUtil: extract, categorize, cache
    TokenUtil-->>APIRoute: Token[] or TokensByCategory
    APIRoute->>TokenUtil: filterTokens(...)? (if filter present)
    TokenUtil-->>APIRoute: Filtered results
    APIRoute-->>Client: 200 JSON or 400/404/500 error
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • dlabaj
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(API): added support for design tokens' directly and accurately summarizes the main change: adding API support for design tokens.
Linked Issues check ✅ Passed The PR implements all primary coding objectives from issue #172: three API routes with token retrieval and filtering, utility functions for token processing, comprehensive test coverage, and OpenAPI documentation.
Out of Scope Changes check ✅ Passed All changes are directly aligned with issue #172 requirements. The PR creates required API routes, utility functions, tests, and OpenAPI documentation for design token endpoints without introducing unrelated modifications.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/utils/tokens.ts`:
- Around line 129-149: Update the function comment for filterTokensByCategory to
accurately describe its behavior: it filters tokens within each category by
token name (case-insensitive) using filterTokens and returns only categories
that still have matching tokens; replace the current misleading lines about
matching the category name and ensure the docstring references TokensByCategory
and the filter parameter semantics.
🧹 Nitpick comments (3)
src/pages/api/[version]/tokens.ts (1)

15-30: Serialize error details to avoid {} responses.
JSON.stringify(Error) drops message/stack. Consider normalizing to a string for consistent debug info.

♻️ Proposed adjustment
-  } catch (error) {
-    return createJsonResponse(
-      { error: 'Failed to load tokens', details: error },
-      500,
-    )
-  }
+  } catch (error) {
+    const details = error instanceof Error ? error.message : String(error)
+    return createJsonResponse(
+      { error: 'Failed to load tokens', details },
+      500,
+    )
+  }
src/pages/api/[version]/tokens/all.ts (1)

35-38: Avoid returning raw error objects in API responses.
details: error can leak internals or serialize unpredictably; return a sanitized message instead.

🔧 Suggested adjustment
-  } catch (error) {
-    return createJsonResponse(
-      { error: 'Failed to load tokens', details: error },
-      500,
-    )
-  }
+  } catch (error) {
+    const message = error instanceof Error ? error.message : String(error)
+    return createJsonResponse(
+      { error: 'Failed to load tokens', details: message },
+      500,
+    )
+  }
src/utils/tokens.ts (1)

85-103: Optional: sort tokens within each category for deterministic output.
This can make responses stable and easier to diff/consume.

♻️ Suggested refinement
   for (const token of tokens) {
     const category = getCategoryFromTokenName(token.name)
     if (!byCategory[category]) {
       byCategory[category] = []
     }
     byCategory[category].push(token)
   }
+
+  for (const categoryTokens of Object.values(byCategory)) {
+    categoryTokens.sort((a, b) => a.name.localeCompare(b.name))
+  }

Comment on lines +129 to +149
/**
* Filters tokens by category (case-insensitive)
* Matches against the category name
*/
export function filterTokensByCategory(
byCategory: TokensByCategory,
filter: string,
): TokensByCategory {
if (!filter) {
return byCategory
}

const filtered: TokensByCategory = {}
for (const [category, tokens] of Object.entries(byCategory)) {
const filteredTokens = filterTokens(tokens, filter)
if (filteredTokens.length > 0) {
filtered[category] = filteredTokens
}
}

return filtered
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix docstring: filtering is by token name, not category name.
The comment conflicts with the implementation and could mislead readers.

📝 Suggested doc fix
- * Filters tokens by category (case-insensitive)
- * Matches against the category name
+ * Filters tokens by name across categories (case-insensitive)
+ * Matches against the token name field
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/**
* Filters tokens by category (case-insensitive)
* Matches against the category name
*/
export function filterTokensByCategory(
byCategory: TokensByCategory,
filter: string,
): TokensByCategory {
if (!filter) {
return byCategory
}
const filtered: TokensByCategory = {}
for (const [category, tokens] of Object.entries(byCategory)) {
const filteredTokens = filterTokens(tokens, filter)
if (filteredTokens.length > 0) {
filtered[category] = filteredTokens
}
}
return filtered
/**
* Filters tokens by name across categories (case-insensitive)
* Matches against the token name field
*/
export function filterTokensByCategory(
byCategory: TokensByCategory,
filter: string,
): TokensByCategory {
if (!filter) {
return byCategory
}
const filtered: TokensByCategory = {}
for (const [category, tokens] of Object.entries(byCategory)) {
const filteredTokens = filterTokens(tokens, filter)
if (filteredTokens.length > 0) {
filtered[category] = filteredTokens
}
}
return filtered
}
🤖 Prompt for AI Agents
In `@src/utils/tokens.ts` around lines 129 - 149, Update the function comment for
filterTokensByCategory to accurately describe its behavior: it filters tokens
within each category by token name (case-insensitive) using filterTokens and
returns only categories that still have matching tokens; replace the current
misleading lines about matching the category name and ensure the docstring
references TokensByCategory and the filter parameter semantics.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add API support for design tokens

1 participant