feat: schema json yaml support - #63
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThis PR adds a Swagger/OpenAPI editor flow with schema parsing and validation, JSON/YAML conversion, Monaco-based editing, save/format controls, endpoint viewing, and page wiring. ChangesSwagger Editor Feature
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Nitpick comments (8)
src/utils/swagger-editor/get-swagger-endpoints.ts (1)
30-39: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winHardcoded fallback string bypasses i18n.
'No summary'is a hardcoded English string, while sibling components (e.g.swagger-view.tsx,swagger-editor.tsx) useuseTranslationsfor all user-facing text and the PR addsru.json. Consider returningnull/undefinedfor a missing summary and letting the consuming component apply the translated fallback viauseTranslations.🤖 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/swagger-editor/get-swagger-endpoints.ts` around lines 30 - 39, The endpoint summary fallback in getSwaggerEndpoints is hardcoded in English, which bypasses the app’s translation flow. Update the logic in getSwaggerEndpoints to stop emitting a literal fallback string when summary and operationId are missing, and instead return a null/undefined-style value so the consuming UI can apply the localized fallback via useTranslations, consistent with swagger-view and swagger-editor.src/utils/swagger-editor/schema-format.ts (1)
40-40: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRedundant option:
uniqueKeysalready defaults totrue.The
yamlpackage'sparsealready checks key uniqueness by default, so{ uniqueKeys: true }is a no-op here. Harmless, but can be dropped for clarity.🤖 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/swagger-editor/schema-format.ts` at line 40, The parse call in schema-format.ts is passing a redundant uniqueKeys option because yaml.parse already enforces unique keys by default. Update the parsing logic in parse/parsedYaml to remove the unnecessary option and keep the call using the default behavior, preserving the existing YAML validation flow while making the code clearer.src/utils/hooks/swagger-hook.test.ts (1)
58-69: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMissing coverage for network failure path.
Tests cover HTTP-level failure (
ok: false) but not a rejectedfetchpromise, which is the scenario flagged in the hook review (unhandled rejection). Consider adding a case mockingfetchto reject.🤖 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/swagger-hook.test.ts` around lines 58 - 69, Add a test in swagger-hook.test.ts to cover the rejected fetch path for useSwaggerHook, since the current restore-case only checks an HTTP response with ok false. Mock fetch to reject, render the hook, and verify editorValue stays at the initial/default value without causing an unhandled rejection; keep the existing assertions around /api/schema and use the same hook entry points and helpers (useSwaggerHook, mockFetchOnce, renderHook, waitFor) to place the new coverage alongside the current restore-response test.src/utils/hooks/swagger-hook.ts (1)
15-18: 🔒 Security & Privacy | 🔵 Trivial | 💤 Low valueAuth stub always grants access.
isAuthenticatedis hardcodedtrue, so restore-from-server always runs regardless of real auth state. This matches the PR's stated known gap (blocked on real auth), so no action needed now beyond tracking, but worth a reminder before merge to production.🤖 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/swagger-hook.ts` around lines 15 - 18, The Swagger hook currently hardcodes auth as always true, so the restore-from-server path in swagger-hook.ts is effectively unguarded. Replace the inline stub in swagger-hook’s isAuthenticated setup with the real authentication check used by the app, or keep the TODO clearly isolated behind a temporary mock only for non-production paths. Make sure the restore flow is gated by the actual auth state before merging to production.src/components/swagger-view/swagger-view.tsx (2)
50-57: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueLGTM overall, minor: method chip color is static.
Chip
color="primary"is applied uniformly to all HTTP methods (GET/POST/DELETE/etc.), losing an opportunity to visually differentiate methods. Not blocking.🤖 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-view/swagger-view.tsx` around lines 50 - 57, The HTTP method Chip in swagger-view is using a fixed primary color for every verb, so update the chip rendering in SwaggerView to choose color dynamically based on endpoint.method instead of hardcoding color="primary". Use the existing endpoint.method value in the same JSX block to map GET/POST/PUT/PATCH/DELETE and other methods to distinct chip colors while keeping the current label and sizing behavior.
29-33: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueUntranslated heading text.
"Swagger Viewer"is hardcoded while the rest of the component (and sibling components) usesnext-intlviauseTranslations. Consider moving this to theswaggerViewertranslation namespace for consistency.🤖 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-view/swagger-view.tsx` around lines 29 - 33, The heading in SwaggerView is hardcoded instead of using the existing next-intl pattern used elsewhere in the component tree. Update the SwaggerView component to read the title from the swaggerViewer translation namespace via useTranslations, and replace the literal “Swagger Viewer” with the translated key so it matches the rest of the localized UI.src/components/swagger-editor/swagger-editor.tsx (1)
5-14: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueInconsistent import style: alias vs relative paths.
SwaggerMonacoEditoris imported via the@componentsbarrel whileMainTextandSwaggerControluse relative paths. This is likely a byproduct ofSwaggerViewer/related components missing from the barrel index (per PR description); once fixed, consider standardizing on the alias import for consistency.🤖 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-editor/swagger-editor.tsx` around lines 5 - 14, The import style in the Swagger editor component is inconsistent because `SwaggerMonacoEditor` uses the `@components` barrel while `MainText` and `SwaggerControl` are pulled in via relative paths. Update the `swagger-editor` component imports to use the same alias-based pattern throughout, and if the missing exports are now available in the components barrel, import `MainText` and `SwaggerControl` from `@components` as well to keep the module references consistent.src/components/swagger-editor/swagger-editor.test.tsx (1)
1-55: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winLGTM, though note this suite doesn't yet cover the viewer panel/endpoint-card rendering, since
SwaggerVieweris not wired into the component under test. Once wiring is fixed, add coverage assertingSwaggerViewerreceives the derived endpoints.🤖 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-editor/swagger-editor.test.tsx` around lines 1 - 55, The SwaggerEditor test suite only covers the alert states and does not verify viewer rendering, so once SwaggerViewer is connected in SwaggerEditor, add a test that mocks or spies on SwaggerViewer and asserts it receives the derived endpoints from the schema. Use the existing SwaggerEditor, SwaggerViewer, and useSwaggerHook symbols to locate the component flow, and update the test setup to cover the endpoint-card/viewer panel output when the schema is valid.
🤖 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/components/swagger-control/swagger-control.tsx`:
- Around line 51-73: The handleSaveSchema request can hang indefinitely because
the fetch call has no timeout or abort handling, leaving isSaving stuck true and
the Save button disabled. Update handleSaveSchema to use an AbortController (or
equivalent timeout mechanism) around the /api/schema fetch, abort the request
after a reasonable delay, and surface a clear timeout-specific error through
setError while ensuring the finally block still resets isSaving. Reference the
handleSaveSchema function and its fetch('/api/schema', ...) call when
implementing the fix.
In `@src/components/swagger-editor/swagger-editor.tsx`:
- Around line 81-87: The viewer panel is still rendering placeholder text
instead of the real Swagger viewer. Update swagger-editor.tsx so the
`SwaggerViewer` component is rendered in the second `Paper` within
`SwaggerEditor`, passing the already-derived `endpoints` and `isValid` props
from the surrounding logic. Remove the literal text and wire the component in
where the current `SwaggerViewer` string appears.
In `@src/components/swagger-monaco-editor/swagger-monaco-editor.tsx`:
- Around line 32-52: The SwaggerMonacoEditor component currently
remounts/reconfigures Monaco purely from value and language changes, which
clears undo history and cursor/view state when switching between JSON and YAML.
Update SwaggerMonacoEditor to keep a stable Monaco model per format by using
persistent models or a unique path for each format, and enable
saveViewState/restoreViewState so toggling format preserves the editor state.
Use the existing SwaggerMonacoEditor and MonacoEditor integration points to wire
this state retention without changing the controlled value behavior.
In `@src/utils/hooks/swagger-hook.ts`:
- Around line 41-56: The restoreSchema helper currently only handles non-OK
responses, so a rejected fetch('/api/schema') can escape as an unhandled promise
rejection. Update restoreSchema in swagger-hook to catch network/runtime errors
around the fetch and JSON parsing, and make the restoreSchema() invocation
safely handle the promise (for example by awaiting it in an async context or
attaching a rejection handler) so failures are contained without noisy console
errors.
- Around line 36-57: The restore logic in useEffect/restoreSchema can overwrite
in-progress user edits when /api/schema resolves late. Update swagger-hook.ts so
restoreSchema only applies setEditorValue and setFormat if the editor is still
pristine, or gate it with a hasUserEdited flag that is set once the user types.
Use the existing isAuthenticated-driven effect and the restoreSchema helper to
place the guard before updating state.
In `@src/utils/swagger-editor/schema-format.ts`:
- Around line 27-38: The JSON parsing path in schema-format.ts is swallowing
both syntax errors and the explicit “Schema must be an object” failure, so the
code always falls through to the YAML fallback. Update the logic around the
JSON.parse block in the schema-format parser to capture that error and only use
the YAML result when appropriate; if YAML also fails, rethrow the original
JSON-related error (or a combined error) so callers get the real failure. Keep
the fix centered in the schema-format parsing flow and make sure the behavior
matches the intent of schema-format-parse.test.ts.
In `@src/utils/swagger-editor/swagger-validation.ts`:
- Around line 14-38: The schema validation flow in validateSwaggerSchema
currently lets SwaggerParser.validate resolve external $ref URLs, which can
trigger browser outbound requests on every edit/restore. Update the validation
call in validateSwaggerSchema to disable external reference resolution by
passing a resolve configuration with external set to false, while keeping the
existing parseSchema, isOpenApiDocument, and error handling behavior intact.
---
Nitpick comments:
In `@src/components/swagger-editor/swagger-editor.test.tsx`:
- Around line 1-55: The SwaggerEditor test suite only covers the alert states
and does not verify viewer rendering, so once SwaggerViewer is connected in
SwaggerEditor, add a test that mocks or spies on SwaggerViewer and asserts it
receives the derived endpoints from the schema. Use the existing SwaggerEditor,
SwaggerViewer, and useSwaggerHook symbols to locate the component flow, and
update the test setup to cover the endpoint-card/viewer panel output when the
schema is valid.
In `@src/components/swagger-editor/swagger-editor.tsx`:
- Around line 5-14: The import style in the Swagger editor component is
inconsistent because `SwaggerMonacoEditor` uses the `@components` barrel while
`MainText` and `SwaggerControl` are pulled in via relative paths. Update the
`swagger-editor` component imports to use the same alias-based pattern
throughout, and if the missing exports are now available in the components
barrel, import `MainText` and `SwaggerControl` from `@components` as well to
keep the module references consistent.
In `@src/components/swagger-view/swagger-view.tsx`:
- Around line 50-57: The HTTP method Chip in swagger-view is using a fixed
primary color for every verb, so update the chip rendering in SwaggerView to
choose color dynamically based on endpoint.method instead of hardcoding
color="primary". Use the existing endpoint.method value in the same JSX block to
map GET/POST/PUT/PATCH/DELETE and other methods to distinct chip colors while
keeping the current label and sizing behavior.
- Around line 29-33: The heading in SwaggerView is hardcoded instead of using
the existing next-intl pattern used elsewhere in the component tree. Update the
SwaggerView component to read the title from the swaggerViewer translation
namespace via useTranslations, and replace the literal “Swagger Viewer” with the
translated key so it matches the rest of the localized UI.
In `@src/utils/hooks/swagger-hook.test.ts`:
- Around line 58-69: Add a test in swagger-hook.test.ts to cover the rejected
fetch path for useSwaggerHook, since the current restore-case only checks an
HTTP response with ok false. Mock fetch to reject, render the hook, and verify
editorValue stays at the initial/default value without causing an unhandled
rejection; keep the existing assertions around /api/schema and use the same hook
entry points and helpers (useSwaggerHook, mockFetchOnce, renderHook, waitFor) to
place the new coverage alongside the current restore-response test.
In `@src/utils/hooks/swagger-hook.ts`:
- Around line 15-18: The Swagger hook currently hardcodes auth as always true,
so the restore-from-server path in swagger-hook.ts is effectively unguarded.
Replace the inline stub in swagger-hook’s isAuthenticated setup with the real
authentication check used by the app, or keep the TODO clearly isolated behind a
temporary mock only for non-production paths. Make sure the restore flow is
gated by the actual auth state before merging to production.
In `@src/utils/swagger-editor/get-swagger-endpoints.ts`:
- Around line 30-39: The endpoint summary fallback in getSwaggerEndpoints is
hardcoded in English, which bypasses the app’s translation flow. Update the
logic in getSwaggerEndpoints to stop emitting a literal fallback string when
summary and operationId are missing, and instead return a null/undefined-style
value so the consuming UI can apply the localized fallback via useTranslations,
consistent with swagger-view and swagger-editor.
In `@src/utils/swagger-editor/schema-format.ts`:
- Line 40: The parse call in schema-format.ts is passing a redundant uniqueKeys
option because yaml.parse already enforces unique keys by default. Update the
parsing logic in parse/parsedYaml to remove the unnecessary option and keep the
call using the default behavior, preserving the existing YAML validation flow
while making the code clearer.
🪄 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: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 81bff6ed-6581-488b-8b5f-c5510d59e7a3
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (29)
package.jsonsrc/app/[locale]/page.tsxsrc/app/globals.csssrc/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-view/swagger-view.test.tsxsrc/components/swagger-view/swagger-view.tsxsrc/constants/default-schema.tssrc/constants/index.tssrc/i18n/messages/en.jsonsrc/i18n/messages/ru.jsonsrc/types/index.tssrc/utils/hooks/swagger-hook.test.tssrc/utils/hooks/swagger-hook.tssrc/utils/swagger-editor/get-swagger-endpoints.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/swagger-validation.test.tssrc/utils/swagger-editor/swagger-validation.tstsconfig.json
💤 Files with no reviewable changes (1)
- src/app/globals.css
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/utils/hooks/use-swagger.ts (1)
43-60: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winRestore error can be silently clobbered by the debounced validation effect.
Both this effect and the validation effect (Lines 27-41) write to the same
errorstate. On mount, the validation effect for the initialeditorValuefires ~400ms later and unconditionally callssetError(result.error). IfrestoreSchema()rejects in the meantime (Line 57-59), the restore error gets overwritten by the (likely successful,null) validation result shortly after — so the user never actually sees the restore failure.Use a dedicated error slot for restore failures (or gate the overwrite) so the two concerns don't race on the same state.
🛡️ Proposed fix
- const [error, setError] = useState<null | string>(null); + const [error, setError] = useState<null | string>(null); + const [restoreError, setRestoreError] = useState<null | string>(null);restoreSchema().catch((restoreError) => { - setError(restoreError instanceof Error ? restoreError.message : t('restoreError')); + setRestoreError(restoreError instanceof Error ? restoreError.message : t('restoreError')); });Expose
restoreErrorseparately in the returned API (or combine witherroronly for display, e.g.error ?? restoreError) so it isn't overwritten by unrelated validation 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 43 - 60, The restore failure handling in use-swagger’s useEffect is racing with the debounced validation effect and both are overwriting the same error state. Update the restoreSchema / restoreError path so restore failures are stored separately from validation errors (or only merged for display), and make sure the validation effect does not clear or replace a pending restore error; keep the unique useEffect and setError / restoreSchema flow easy to locate when applying the fix.
🧹 Nitpick comments (1)
src/utils/hooks/use-swagger.ts (1)
62-79: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy liftPersistence logic split between hook and component; verify undo/cursor preservation on format toggle.
SchemaService.saveisn't used anywhere in this hook — per cross-file evidence it's called directly fromswagger-control.tsxinstead, whilerestorelives here. Since this hook otherwise owns all schema/editor state, consider consolidating save behind ahandleSavereturned fromuseSwaggertoo, for a single cohesive persistence surface (this also matches the commit history direction of factoring both save/restore intoSchemaService).Separately,
handleFormatToggledoes a full-stringsetEditorValuereplace on every toggle. The linked issue requires that JSON↔YAML switching preserve undo history and cursor position where possible — whether that holds depends on howswagger-monaco-editor.tsx(not in this batch) reacts to a wholesalevalueprop change versus an in-place model edit. Worth confirming that component applies the new text via a diff/edit operation rather than resetting the Monaco model.🤖 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 62 - 79, The persistence flow is split across useSwagger and swagger-control.tsx, and format toggling may be resetting the editor state too aggressively. Add a cohesive handleSave from useSwagger that wraps SchemaService.save so save/restore live behind one hook API, and update callers accordingly. Also review handleFormatToggle to ensure the JSON↔YAML update is applied through an in-place Monaco edit path (as handled by swagger-monaco-editor.tsx) rather than a full value reset, so undo history and cursor position are preserved where possible.
🤖 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/services/schema-service.ts`:
- Around line 13-24: The restore() method in SchemaService should not pass
arbitrary /api/schema JSON straight through; after fetching, validate that the
parsed payload includes a schema object with both content and format before
returning it, and otherwise return null. Also update restore() to use the same
timeout/cancellation pattern as save() by passing getSignalWithTimeout() into
fetch so the initial load can be aborted on unmount.
---
Outside diff comments:
In `@src/utils/hooks/use-swagger.ts`:
- Around line 43-60: The restore failure handling in use-swagger’s useEffect is
racing with the debounced validation effect and both are overwriting the same
error state. Update the restoreSchema / restoreError path so restore failures
are stored separately from validation errors (or only merged for display), and
make sure the validation effect does not clear or replace a pending restore
error; keep the unique useEffect and setError / restoreSchema flow easy to
locate when applying the fix.
---
Nitpick comments:
In `@src/utils/hooks/use-swagger.ts`:
- Around line 62-79: The persistence flow is split across useSwagger and
swagger-control.tsx, and format toggling may be resetting the editor state too
aggressively. Add a cohesive handleSave from useSwagger that wraps
SchemaService.save so save/restore live behind one hook API, and update callers
accordingly. Also review handleFormatToggle to ensure the JSON↔YAML update is
applied through an in-place Monaco edit path (as handled by
swagger-monaco-editor.tsx) rather than a full value reset, so undo history and
cursor position are preserved where possible.
🪄 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: be2ddc27-7cfe-4dcd-9c03-a0631e8ef865
📒 Files selected for processing (7)
src/components/swagger-control/swagger-control.tsxsrc/services/schema-service.tssrc/utils/hooks/use-swagger.tssrc/utils/swagger-editor/is-record.tssrc/utils/swagger-editor/schema-format.tssrc/utils/swagger-editor/schema-types.tssrc/utils/swagger-editor/swagger-validation.ts
💤 Files with no reviewable changes (1)
- src/utils/swagger-editor/schema-types.ts
✅ Files skipped from review due to trivial changes (1)
- src/utils/swagger-editor/is-record.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- src/components/swagger-control/swagger-control.tsx
- src/utils/swagger-editor/swagger-validation.ts
- src/utils/swagger-editor/schema-format.ts
* Story/1 sticky header general (#50) * feat: install next+ts+linter+prettier+ husky+redux * feat: configs + perfectionist + lint fix * feat: install scss * refactor: add some folders * feat: install i18n + basic configs * feat: add internatiolisation * feat: language switcher * feat: dependencies update * feat: add sticky header * feat: add mui Button-and-Link-like component * fix: lint * style: add style for header * refactor: remove css from language selector * refactor: add const for flex styles in the header boxes * refactor: history style as link * fix: add some fixes * feat: schema json yaml support (#63) * chore: setup libraries * feat: swagger-editor * refactor: move title and description into a separated component * refactor: moved controls into the swaggerControl component * chore: update package-lock.json * fix: fix import in swagger-view * feat: add translations into SwaggerControl, SwaggerEditor, SwaggerViewer * fix: fix title translation in main text * fix: enforce unique keys when parsing YAML * refactor: extract DEFAULT_SCHEMA into a constant * feat: add tooltip explaining disabled format toggle * test: add test coverage for schema editing flow * fix: resolve component type errors in swagger viewer * fix: add request timeout with AbortController * fix: preserve Monaco editor undo history and cursor position on format switch * fix: prevent restore fetch from overwriting user-edited schema * fix: handle rejected promise in restoreSchema to prevent unhandled rejection * fix: replace missing setEditorValue with handleEditorChange in SwaggerEditor * fix: apply syntax highlighting immediately on editor mount * fix: preserve original JSON parse error * fix: disable external $ref resolution in schema validation to prevent SSRF * refactor: split SwaggerControl into service, component, and helper move save request to schema-service extract FormatToggle component extract getSignalWithTimeout helper switch errors to toast notifications * refactor: rename useSwaggerHook and drop unnecessary useMemo * test: fix tests after refactor * refactor: extract duplicated language-setting logic into helper in SwaggerMonacoEditor * refactor: remove redundant SwaggerViewer title * fix: use translated conversionError message instead of hardcoded string * refactor: extract SchemaFormat and isRecord into shared schema-types module * fix: reserve space for status alert to prevent layout shift on locale switch * feat: sync Monaco editor theme with app color scheme * style: add shadow, border-radius, deduplicate panel styles * test: fix ReactElement import in swagger-control tests * feat: extract schema fetch logic into SchemaService with restore and save methods * fix: extract magic number into named constant * refactor: extract isRecord type guard into its own module * fix: validate restore payload and cancel restore request on unmount * test: add tests for monaco theme * feat: add SwaggerViewer placeholder component * fix: route SwaggerControl toast messages through shared toaster namespace --------- Co-authored-by: Yulia Demir <Nightelfin91@gmail.com> * fix: remove duplicate SwaggerViewer implementation in swagger-view folder * fix: remove unused key from swaggerControl i18n namespace * fix: guard non-object JSON in SchemaService.restore * refactor: catch unhandled rejection in debounced validation --------- Co-authored-by: YuliaDemir <129578495+YuliaDemir@users.noreply.github.com> Co-authored-by: Yulia Demir <Nightelfin91@gmail.com>
Summary
Implements Feature 3 (Swagger Editor) - editing and validation of OpenAPI/Swagger schemas with format auto-detection, JSON/YAML conversion, and responsive split-view.
Changes Made
Known issues, need fixing before merge
Blocked on Feature 2 (auth)
Related issue
Closes #40, #41, #42, #43, #46
Feature
Feature 3: Swagger Editor
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
Type of change
Checklist
any/@ts-ignoreSummary by CodeRabbit
Summary by CodeRabbit