feat: render swagger endpoint list - #69
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughImplements a Swagger/OpenAPI editor page with schema parsing, validation, restore/save, Monaco editing, grouped endpoint viewing, format toggling, and localized status messages. Adds tests for the hook and components, updates translations, and wires the editor into the home page. ChangesSwagger editor workflow
Estimated code review effort: 5 (Critical) | ~120 minutes Sequence Diagram(s)sequenceDiagram
participant useSwagger
participant SwaggerEditor
participant SwaggerControl
participant SwaggerMonacoEditor
participant SwaggerViewer
useSwagger-->>SwaggerEditor: editorValue, schema, format, handlers
SwaggerEditor->>SwaggerControl: format, validity, save handler
SwaggerEditor->>SwaggerMonacoEditor: value, format, onChange
SwaggerEditor->>SwaggerViewer: apiInfo, endpoints, isValid
SwaggerControl->>useSwagger: handleFormatToggle / save schema
SwaggerMonacoEditor->>useSwagger: handleEditorChange
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
b8786e6 to
f378373
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (5)
src/utils/hooks/use-swagger.ts (1)
24-27: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueHardcoded auth stub — flagged by author's own TODO.
isAuthenticatedis a hardcoded constant, gating the entire restore-on-mount flow. Since this is explicitly called out as a TODO, worth tracking before merge to main so it isn't forgotten.Want me to open a follow-up issue to track wiring real authentication here?
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/utils/hooks/use-swagger.ts` around lines 24 - 27, The restore-on-mount flow in useSwagger is currently gated by a hardcoded isAuthenticated stub, which is only a temporary TODO. Replace the inline constant with the real authentication source used by the app, and keep the condition in the same restore effect logic so the hook only runs when actual auth state is available. Use the useSwagger hook and its isAuthenticated check as the place to wire this in.src/services/schema-service.ts (1)
39-50: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueSave error discards response detail.
savethrows a generic'Failed to save schema'regardless of status code or server-provided error body, which limits what callers can surface to users (e.g., quota/auth failures vs. generic 500s look identical).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/services/schema-service.ts` around lines 39 - 50, The save flow in SchemaService.save currently throws a generic error and drops the HTTP status and server error body, so update the fetch failure handling to preserve response details for callers. In the save method, inspect the non-OK response from /api/schema and build the thrown error using the response status/statusText and any parsed error payload when available, so different failure cases can be distinguished by consumers.src/components/swagger-control/swagger-control.test.tsx (1)
81-93: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winAdd coverage for the timeout/AbortError branch.
Tests cover the generic save failure (
ok: false) but not theAbortErrorpath that showsrequestTimeoutError, which is a distinct branch inSwaggerControl's save handler.✅ Suggested additional test
it('shows a timeout toast when the save request is aborted', async () => { global.fetch = vi.fn().mockRejectedValue( Object.assign(new Error('aborted'), { name: 'AbortError' }), ) as unknown as typeof fetch; renderWithToast(<SwaggerControl {...baseProps} isValid />); await userEvent.click(screen.getByRole('button', { name: 'saveButton' })); await waitFor(() => { expect(screen.getByRole('alert')).toHaveTextContent('requestTimeoutError'); }); });🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/swagger-control/swagger-control.test.tsx` around lines 81 - 93, Add test coverage in SwaggerControl for the AbortError save-failure branch: the existing save failure test only covers a false ok response, so add a new case in swagger-control.test.tsx that mocks fetch to reject with an AbortError and asserts the toast shows requestTimeoutError. Use the existing save handler flow in SwaggerControl and the saveButton/alert queries to place the new test near the current schemaSaveError case.src/components/swagger-viewer/swagger-viewer.tsx (1)
88-88: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRedundant type cast.
getMethodColoralready returnsChipProps['color'](per its definition), so theas ChipProps['color']cast here is unnecessary.♻️ Proposed simplification
- <Chip - color={getMethodColor(endpoint.method) as ChipProps['color']} + <Chip + color={getMethodColor(endpoint.method)}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/swagger-viewer/swagger-viewer.tsx` at line 88, The Chip color prop in swagger-viewer’s endpoint rendering uses an unnecessary type cast because getMethodColor already returns ChipProps['color']; remove the redundant cast at the getMethodColor call site in swagger-viewer.tsx and keep the existing function typing intact.src/components/swagger-control/swagger-control.tsx (1)
29-39: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueTrack the auth TODO.
isAuthenticatedis hardcoded totrue, so the auth guard and conditional rendering are currently dead code. Fine as an interim placeholder given the TODO, but flag for follow-up once real auth lands.Also applies to: 69-73
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/swagger-control/swagger-control.tsx` around lines 29 - 39, `isAuthenticated` in `SwaggerControl` is hardcoded to true, so the auth guard in `handleSaveSchema` and the conditional rendering are effectively dead code. Keep the placeholder only if needed for the TODO, but make sure this is tracked for follow-up and is easy to replace once real auth is wired in; update both the save guard and the related render branch to use the eventual auth source instead of the inline mock.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/utils/hooks/use-swagger.ts`:
- Around line 29-49: The debounce cleanup in useSwagger’s useEffect only clears
the timer, so an older in-flight validateSwaggerSchema(editorValue) call can
still resolve later and overwrite isValid, error, schema, or format with stale
data. Add a cancellation guard or request token inside useEffect so each
validation run can detect when it has been superseded by a newer editorValue,
and only apply setIsValid, setError, setSchema, and setFormat updates for the
latest run.
---
Nitpick comments:
In `@src/components/swagger-control/swagger-control.test.tsx`:
- Around line 81-93: Add test coverage in SwaggerControl for the AbortError
save-failure branch: the existing save failure test only covers a false ok
response, so add a new case in swagger-control.test.tsx that mocks fetch to
reject with an AbortError and asserts the toast shows requestTimeoutError. Use
the existing save handler flow in SwaggerControl and the saveButton/alert
queries to place the new test near the current schemaSaveError case.
In `@src/components/swagger-control/swagger-control.tsx`:
- Around line 29-39: `isAuthenticated` in `SwaggerControl` is hardcoded to true,
so the auth guard in `handleSaveSchema` and the conditional rendering are
effectively dead code. Keep the placeholder only if needed for the TODO, but
make sure this is tracked for follow-up and is easy to replace once real auth is
wired in; update both the save guard and the related render branch to use the
eventual auth source instead of the inline mock.
In `@src/components/swagger-viewer/swagger-viewer.tsx`:
- Line 88: The Chip color prop in swagger-viewer’s endpoint rendering uses an
unnecessary type cast because getMethodColor already returns ChipProps['color'];
remove the redundant cast at the getMethodColor call site in swagger-viewer.tsx
and keep the existing function typing intact.
In `@src/services/schema-service.ts`:
- Around line 39-50: The save flow in SchemaService.save currently throws a
generic error and drops the HTTP status and server error body, so update the
fetch failure handling to preserve response details for callers. In the save
method, inspect the non-OK response from /api/schema and build the thrown error
using the response status/statusText and any parsed error payload when
available, so different failure cases can be distinguished by consumers.
In `@src/utils/hooks/use-swagger.ts`:
- Around line 24-27: The restore-on-mount flow in useSwagger is currently gated
by a hardcoded isAuthenticated stub, which is only a temporary TODO. Replace the
inline constant with the real authentication source used by the app, and keep
the condition in the same restore effect logic so the hook only runs when actual
auth state is available. Use the useSwagger hook and its isAuthenticated check
as the place to wire this in.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 77ee2abe-05f1-4d7d-94b5-22ceff3148fc
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (36)
package.jsonsrc/app/[locale]/page.tsxsrc/app/globals.csssrc/components/format-toggle/format-toggle.tsxsrc/components/header/header.tsxsrc/components/index.tssrc/components/main-text/main-text.test.tsxsrc/components/main-text/main-text.tsxsrc/components/swagger-control/swagger-control.test.tsxsrc/components/swagger-control/swagger-control.tsxsrc/components/swagger-editor/swagger-editor.test.tsxsrc/components/swagger-editor/swagger-editor.tsxsrc/components/swagger-monaco-editor/swagger-monaco-editor.test.tsxsrc/components/swagger-monaco-editor/swagger-monaco-editor.tsxsrc/components/swagger-viewer/swagger-viewer.test.tsxsrc/components/swagger-viewer/swagger-viewer.tsxsrc/constants/default-schema.tssrc/constants/index.tssrc/i18n/messages/en.jsonsrc/i18n/messages/ru.jsonsrc/services/schema-service.tssrc/types/index.tssrc/utils/hooks/use-swagger.test.tssrc/utils/hooks/use-swagger.tssrc/utils/network/get-signal-with-timeout.tssrc/utils/swagger-editor/get-method-color.tssrc/utils/swagger-editor/get-swagger-endpoints.tssrc/utils/swagger-editor/group-endpoints-by-path.tssrc/utils/swagger-editor/is-record.tssrc/utils/swagger-editor/schema-format-convert.test.tssrc/utils/swagger-editor/schema-format-parse.test.tssrc/utils/swagger-editor/schema-format.tssrc/utils/swagger-editor/schema-types.tssrc/utils/swagger-editor/swagger-validation.test.tssrc/utils/swagger-editor/swagger-validation.tstsconfig.json
💤 Files with no reviewable changes (1)
- src/app/globals.css
✅ Files skipped from review due to trivial changes (7)
- src/utils/network/get-signal-with-timeout.ts
- src/utils/swagger-editor/schema-format-parse.test.ts
- src/constants/index.ts
- src/utils/swagger-editor/get-method-color.ts
- src/utils/swagger-editor/is-record.ts
- tsconfig.json
- src/i18n/messages/en.json
🚧 Files skipped from review as they are similar to previous changes (1)
- src/components/swagger-viewer/swagger-viewer.test.tsx
| useEffect(() => { | ||
| const timeoutId = window.setTimeout(() => { | ||
| validateSwaggerSchema(editorValue) | ||
| .then((result) => { | ||
| setIsValid(result.isValid); | ||
| setError(result.error); | ||
| setSchema(result.schema); | ||
|
|
||
| if (result.isValid) { | ||
| setFormat(result.detectedFormat); | ||
| } | ||
| }) | ||
| .catch((validationError) => { | ||
| setError( | ||
| validationError instanceof Error ? validationError.message : t('conversionError'), | ||
| ); | ||
| }); | ||
| }, VALIDATION_DEBOUNCE_MS); | ||
|
|
||
| return () => window.clearTimeout(timeoutId); | ||
| }, [editorValue, t]); |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Map the relevant file and related validation helper
git ls-files 'src/utils/hooks/use-swagger.ts' 'src/utils/**' | sed -n '1,120p'
echo
echo '--- outline: src/utils/hooks/use-swagger.ts ---'
ast-grep outline src/utils/hooks/use-swagger.ts --view expanded || true
echo
echo '--- outline: potential validation helper files ---'
fd -a 'swagger' src/utils src | sed -n '1,120p' || true
rg -n "validateSwaggerSchema|SwaggerParser|VALIDATION_DEBOUNCE_MS|useEffect\\(" src/utils src -g '!**/*.d.ts' -g '!**/node_modules/**' || trueRepository: AlyaEngineer/swagger-editor-app
Length of output: 6073
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- src/utils/hooks/use-swagger.ts ---'
cat -n src/utils/hooks/use-swagger.ts | sed -n '1,220p'
echo
echo '--- src/utils/swagger-editor/swagger-validation.ts ---'
cat -n src/utils/swagger-editor/swagger-validation.ts | sed -n '1,220p'Repository: AlyaEngineer/swagger-editor-app
Length of output: 5981
Prevent stale validation results from overwriting the current editor state
clearTimeout only cancels the debounce timer; once validateSwaggerSchema(editorValue) is in flight, a slower earlier request can still resolve after a later edit and overwrite isValid/error/schema/format with stale data. Add a cancellation flag or request token and skip state updates for superseded runs.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/utils/hooks/use-swagger.ts` around lines 29 - 49, The debounce cleanup in
useSwagger’s useEffect only clears the timer, so an older in-flight
validateSwaggerSchema(editorValue) call can still resolve later and overwrite
isValid, error, schema, or format with stale data. Add a cancellation guard or
request token inside useEffect so each validation run can detect when it has
been superseded by a newer editorValue, and only apply setIsValid, setError,
setSchema, and setFormat updates for the latest run.
Summary
Implements the first Swagger Viewer step from Feature 4: endpoint list rendering.
This PR replaces the temporary SwaggerViewer placeholder with a real endpoint list organized by path and HTTP method. It is based on the current
story/3-schema-json-yaml-supportEditor branch and keeps the newsrc/components/swagger-viewerstructure as the source of truth.Changes Made
pathsswagger-viewpath as a compatibility re-export to avoid duplicate Viewer implementationsRelated issue
Closes #64
Feature
Feature 4: Swagger Viewer
Acceptance criteria
Feature 1: App Header
Feature 2: Sign In / Sign Up
Feature 3: Swagger Editor
Feature 4: Swagger Viewer
Feature 5: History and Analytics
Feature 6: About Page
Feature 7: General Requirements
Feature 8: YouTube Video
Screenshots
TODO: add screenshot from the Swagger Viewer endpoint list.
Deployment
TODO: add Vercel Preview URL after PR creation.
Verification
npm test— 16 files, 68 tests passednpm run lint— passednpm run build— passedgit diff --check— passedKnown limitations
Viewer tasks.
Type of change
Checklist
any/@ts-ignoreSummary by CodeRabbit
New Features
Bug Fixes
Tests