-
Notifications
You must be signed in to change notification settings - Fork 11
feat(API): added support for design tokens #203
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat(API): added support for design tokens #203
Conversation
WalkthroughAdds design-token API endpoints and utilities: GET /api/{version}/tokens, GET /api/{version}/tokens/{category}, GET /api/{version}/tokens/all; a new tokens utility module; OpenAPI spec entries; and Jest tests covering retrieval, filtering, errors, and caching. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant APIRoute as API Route
participant ApiIndex as fetchApiIndex
participant TokenUtil as Token Utilities
participant PatternFly as `@patternfly/react-tokens`
Client->>APIRoute: GET /api/{version}/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: tokens or tokens-by-category
APIRoute->>TokenUtil: filterTokens(...)? (if filter present)
TokenUtil-->>APIRoute: filtered results
APIRoute-->>Client: 200 JSON or 400/404/500 error
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
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. Comment |
There was a problem hiding this 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: errorcan 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)) + }
src/utils/tokens.ts
Outdated
| /** | ||
| * 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| /** | |
| * 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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@src/__tests__/utils/tokens.test.ts`:
- Around line 1-41: The mocked token object in the jest.mock call uses
non-camelcase keys (e.g., c_alert_BackgroundColor, c_alert_Color,
c_button_BackgroundColor, t_global_color_100, invalidToken) which triggers the
camelcase ESLint rule; add a scoped eslint-disable-next-line or eslint-disable
comment for camelcase just above the jest.mock invocation (or wrap the object
with /* eslint-disable `@typescript-eslint/camelcase` */ and re-enable after) so
the token keys remain unchanged and the linter does not fail.
In `@src/utils/tokens.ts`:
- Around line 17-36: In getCategoryFromTokenName, replace the mutable
declaration for the category variable with an immutable one: change the
declaration of category (currently declared with let after computing parts =
tokenName.split('-')) to use const since it is never reassigned; keep the
existing early-return for the 'chart' case and return category at the end as
before.
There was a problem hiding this 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/__tests__/utils/tokens.test.ts`:
- Line 1: Replace the ineffective single-line directive with a block disable
using the base rule name (change the existing "// eslint-disable
`@typescript-eslint/camelcase`" to a block comment that disables "camelcase"
across the mock section) and then re-enable the rule after the mock block (add a
corresponding block enable for "camelcase" immediately after the mock block) so
the disable only spans the intended mock code; locate the directive at the top
of the tokens.test.ts file and the mock block that follows to apply these
changes.
Closes #172
Summary by CodeRabbit
New Features
Tests
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.