Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Rate limit exceeded@enzonotario has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 13 minutes and 51 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (2)
WalkthroughReplaces the legacy OpenApi constructor with a new factory createOpenApiSpec and OpenApiSpecInstance, adds async-capable OpenAPI provisioning via OAProvider/OAProviderAsync and new composables (injectOpenapi/getGlobalOpenapi/useOpenapi), introduces the '@' path alias, and updates many import paths and utilities locations. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Consumer as Component (e.g., OAInfo)
participant Provider as OAProviderAsync
participant Fetch as fetch()
participant Parser as parseSpec / parseOpenapi
participant Factory as createOpenApiSpec
participant Vue as provide(OPENAPI_LOCAL_KEY)
Consumer->>Provider: render with :spec or :specUrl
alt specUrl provided
Provider->>Fetch: fetch(specUrl)
Fetch-->>Provider: raw spec (JSON/YAML/string)
else spec provided
Provider->>Provider: use provided spec
end
Provider->>Parser: parseSpec(raw or provided)
Parser-->>Provider: OpenAPIDocument
Provider->>Factory: createOpenApiSpec({ spec: parsed })
Factory-->>Provider: OpenApiSpecInstance
Provider->>Vue: provide(OPENAPI_LOCAL_KEY, OpenApiSpecInstance)
Provider->>Consumer: render slot with openapiInstance
Consumer->>Consumer: consume via injectOpenapi() or getGlobalOpenapi()
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes
Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (2 warnings, 1 inconclusive)
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 |
commit: |
There was a problem hiding this comment.
Actionable comments posted: 18
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
src/lib/spec/createOpenApiSpec.ts (3)
240-242:specandoriginalSpecproperties are eagerly evaluated snapshots.The returned object sets
spec: getSpec()andoriginalSpec: getOriginalSpec()at creation time. These are snapshots that won't reflect latersetSpec()orsetOriginalSpec()calls, while the getter methods will.This inconsistency between direct property access and method access could confuse consumers. Consider either:
- Documenting this behavior clearly
- Using getters in the return object to ensure consistency:
return { - spec: getSpec(), - originalSpec: getOriginalSpec(), + get spec() { return getSpec() }, + get originalSpec() { return getOriginalSpec() }, setSpec, ... }
119-139:getPathsByVerbscan returnnullitems in array.Line 127 returns
nullwhen the path/method doesn't exist, but the outerfilterat line 124 already ensures the path/method exists. The null check and return at lines 126-128 appear to be dead code.function getPathsByVerbs() { const paths = getPaths() return Object.keys(paths) .flatMap((path) => { return httpVerbs .filter((verb: string) => paths && paths[path] && paths[path][verb]) .map((verb: string) => { - if (!paths || !paths[path] || !paths[path][verb]) { - return null - } const { operationId, summary, tags } = paths[path][verb] return { path, verb, operationId, summary, tags: tags ?? [], } }) }) }
190-206:filterPathspredicate parameter lacks type annotation.The predicate parameter is typed as
(operation: any) => boolean. Consider using a more specific type likeOpenAPIV3.OperationObjectto improve type safety and IDE support.-function filterPaths(predicate: (operation: any) => boolean) { +function filterPaths(predicate: (operation: OpenAPIV3.OperationObject) => boolean) {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (73)
components.json(1 hunks)docs/.vitepress/theme/components/BrowserWindow.vue(1 hunks)docs/.vitepress/theme/components/ExampleBlock.vue(1 hunks)docs/.vitepress/theme/components/sandbox/Sandbox.vue(1 hunks)docs/.vitepress/theme/components/sandbox/SandboxIframe.vue(1 hunks)docs/.vitepress/theme/components/sandbox/SandboxPreview.vue(1 hunks)docs/.vitepress/theme/components/ui/popover/PopoverContent.vue(1 hunks)docs/.vitepress/theme/components/ui/resizable/ResizableHandle.vue(1 hunks)docs/.vitepress/theme/components/ui/resizable/ResizablePanelGroup.vue(1 hunks)docs/.vitepress/theme/components/ui/toast/Toast.vue(1 hunks)docs/.vitepress/theme/components/ui/toast/ToastAction.vue(1 hunks)docs/.vitepress/theme/components/ui/toast/ToastClose.vue(1 hunks)docs/.vitepress/theme/components/ui/toast/ToastDescription.vue(1 hunks)docs/.vitepress/theme/components/ui/toast/ToastTitle.vue(1 hunks)docs/.vitepress/theme/components/ui/toast/ToastViewport.vue(1 hunks)src/client.ts(2 hunks)src/components/Common/OAHeading.vue(1 hunks)src/components/Common/OAMarkdown.vue(1 hunks)src/components/Context/OAContext.vue(0 hunks)src/components/Context/OAContextProvider.vue(0 hunks)src/components/Context/OAProvider.vue(1 hunks)src/components/Context/OAProviderAsync.vue(2 hunks)src/components/Feature/OAInfo.vue(2 hunks)src/components/Feature/OAIntroduction.vue(2 hunks)src/components/Feature/OAOperation.vue(3 hunks)src/components/Feature/OAOperationContext.vue(1 hunks)src/components/Feature/OAServers.vue(2 hunks)src/components/Feature/OASpec.vue(3 hunks)src/components/Path/OAPaths.vue(2 hunks)src/components/Path/OAPathsGroup.vue(1 hunks)src/components/Playground/OAPlayground.vue(1 hunks)src/components/Playground/OAPlaygroundBodyInput.vue(1 hunks)src/components/Playground/OAPlaygroundParameters.vue(2 hunks)src/components/Request/OARequestBody.vue(1 hunks)src/components/Sample/OACodeSamples.vue(1 hunks)src/components/ui/badge/Badge.vue(1 hunks)src/components/ui/button/Button.vue(1 hunks)src/components/ui/checkbox/Checkbox.vue(1 hunks)src/components/ui/input/Input.vue(1 hunks)src/components/ui/label/Label.vue(1 hunks)src/components/ui/select/SelectContent.vue(1 hunks)src/components/ui/select/SelectGroup.vue(1 hunks)src/components/ui/select/SelectItem.vue(1 hunks)src/components/ui/select/SelectLabel.vue(1 hunks)src/components/ui/select/SelectScrollDownButton.vue(1 hunks)src/components/ui/select/SelectScrollUpButton.vue(1 hunks)src/components/ui/select/SelectSeparator.vue(1 hunks)src/components/ui/select/SelectTrigger.vue(1 hunks)src/components/ui/tabs/TabsContent.vue(1 hunks)src/components/ui/tabs/TabsList.vue(1 hunks)src/components/ui/tabs/TabsTrigger.vue(1 hunks)src/components/ui/textarea/Textarea.vue(1 hunks)src/components/ui/tooltip/TooltipContent.vue(1 hunks)src/composables/useOpenapi.ts(1 hunks)src/composables/usePaths.ts(2 hunks)src/composables/usePlayground.ts(1 hunks)src/composables/useSidebar.ts(2 hunks)src/composables/useTheme.ts(1 hunks)src/index.ts(1 hunks)src/lib/codeSamples/buildHarRequest.ts(1 hunks)src/lib/codeSamples/buildRequest.ts(1 hunks)src/lib/examples/getSchemaExample.ts(1 hunks)src/lib/operation/operationData.ts(1 hunks)src/lib/parser/generateCodeSamples.ts(1 hunks)src/lib/spec/createOpenApiSpec.ts(2 hunks)src/lib/utils/deepUnref.ts(1 hunks)test/composables/openapi.test.ts(2 hunks)test/composables/useOpenapi.test.ts(1 hunks)test/composables/useOpenapiWithNoSpec.test.ts(1 hunks)test/composables/usePlayground.setParameterValue.test.ts(1 hunks)test/lib/spec/createOpenApiSpec.test.ts(1 hunks)test/lib/utils/contentTypeUtils.test.ts(1 hunks)test/lib/utils/utils.test.ts(1 hunks)
💤 Files with no reviewable changes (2)
- src/components/Context/OAContextProvider.vue
- src/components/Context/OAContext.vue
🧰 Additional context used
🧠 Learnings (6)
📚 Learning: 2025-07-15T19:55:33.067Z
Learnt from: alexchexes
Repo: enzonotario/vitepress-openapi PR: 272
File: src/components/Response/OAResponse.vue:6-6
Timestamp: 2025-07-15T19:55:33.067Z
Learning: The vitepress-openapi project uses antfu/eslint-config with eslint-plugin-perfectionist which enforces import ordering by grouping imports by type rather than alphabetically. Import suggestions should respect this convention: Vue core imports, local composables, component imports, external library imports, then CSS imports.
Applied to files:
src/components/ui/input/Input.vuesrc/components/ui/select/SelectLabel.vuedocs/.vitepress/theme/components/ui/toast/Toast.vuedocs/.vitepress/theme/components/ui/popover/PopoverContent.vuesrc/composables/useSidebar.tsdocs/.vitepress/theme/components/BrowserWindow.vuesrc/components/ui/select/SelectGroup.vuesrc/client.tsdocs/.vitepress/theme/components/ExampleBlock.vuedocs/.vitepress/theme/components/ui/toast/ToastDescription.vuedocs/.vitepress/theme/components/ui/toast/ToastViewport.vuedocs/.vitepress/theme/components/ui/resizable/ResizableHandle.vuedocs/.vitepress/theme/components/ui/resizable/ResizablePanelGroup.vuedocs/.vitepress/theme/components/sandbox/Sandbox.vuesrc/components/Playground/OAPlaygroundBodyInput.vue
📚 Learning: 2025-07-09T18:29:13.510Z
Learnt from: alexchexes
Repo: enzonotario/vitepress-openapi PR: 258
File: test/composables/useSidebar.multipleTags.test.ts:63-232
Timestamp: 2025-07-09T18:29:13.510Z
Learning: In vitepress-openapi tests, the sidebarItemTemplate path parameter should use the OpenAPI spec path (e.g., `/api/cats`) not the operationId (e.g., `/findCat`). Tests may pass incorrectly if they provide explicit titles that mask wrong path parameters, since the template function uses `title || path` for display text.
Applied to files:
test/lib/spec/createOpenApiSpec.test.tssrc/composables/useSidebar.tstest/composables/useOpenapi.test.tstest/composables/openapi.test.tssrc/components/Path/OAPaths.vuetest/composables/useOpenapiWithNoSpec.test.tssrc/composables/usePaths.tssrc/lib/spec/createOpenApiSpec.ts
📚 Learning: 2025-08-17T13:10:49.905Z
Learnt from: enzonotario
Repo: enzonotario/vitepress-openapi PR: 0
File: :0-0
Timestamp: 2025-08-17T13:10:49.905Z
Learning: The vitepress-openapi project is considering a major architectural change from runtime Vue component rendering to build-time markdown generation with template slots, similar to vitepress-jsdoc approach, to improve performance, SEO, and leverage VitePress's built-in markdown renderer.
Applied to files:
src/composables/useSidebar.tssrc/client.tsdocs/.vitepress/theme/components/ExampleBlock.vuesrc/components/Path/OAPaths.vuedocs/.vitepress/theme/components/ui/toast/ToastViewport.vuedocs/.vitepress/theme/components/sandbox/Sandbox.vue
📚 Learning: 2025-07-10T21:25:08.434Z
Learnt from: alexchexes
Repo: enzonotario/vitepress-openapi PR: 267
File: src/locales/en.json:60-60
Timestamp: 2025-07-10T21:25:08.434Z
Learning: In the vitepress-openapi project, the OASchemaPropertyAttributes component follows a pattern where translation keys are passed from parent components as props, and the child component handles the actual translation using the t() function. This allows for clean separation of concerns where parent components provide the keys and child components handle the i18n translation.
Applied to files:
src/components/Playground/OAPlayground.vuesrc/components/Path/OAPaths.vuesrc/components/Request/OARequestBody.vuesrc/components/Playground/OAPlaygroundBodyInput.vue
📚 Learning: 2025-07-26T22:51:04.951Z
Learnt from: enzonotario
Repo: enzonotario/vitepress-openapi PR: 281
File: docs/public/openapi.json:33-35
Timestamp: 2025-07-26T22:51:04.951Z
Learning: In vitepress-openapi, the markdown syntax `[](/operations/operationId)` is processed by a custom markdown-it plugin that renders OAOperationLink components. The empty brackets are intentional and functional, not broken markdown links. This custom syntax automatically displays operation information without requiring explicit link text.
Applied to files:
src/components/Path/OAPaths.vue
📚 Learning: 2025-07-09T19:04:58.788Z
Learnt from: alexchexes
Repo: enzonotario/vitepress-openapi PR: 258
File: test/composables/useSidebar.multipleTags.test.ts:63-232
Timestamp: 2025-07-09T19:04:58.788Z
Learning: The sidebarItemTemplateForMethodPath function in vitepress-openapi generates titles with fallback logic: operation['x-sidebar-title'] || summary || `${method.toUpperCase()} ${path}`. When testing operations without summaries, the expected title should be the fallback format like 'GET /account/stats', not just the path.
Applied to files:
src/components/Path/OAPaths.vuetest/composables/useOpenapiWithNoSpec.test.tssrc/lib/spec/createOpenApiSpec.ts
🧬 Code graph analysis (8)
test/lib/spec/createOpenApiSpec.test.ts (1)
src/lib/spec/createOpenApiSpec.ts (1)
createOpenApiSpec(29-263)
test/composables/useOpenapi.test.ts (2)
src/composables/useOpenapi.ts (1)
useOpenapi(57-94)test/testsConstants.ts (2)
spec(1-136)specWithSchemaAndContentTypes(512-566)
src/client.ts (2)
src/index.ts (1)
OpenApiSpecInstance(10-10)src/lib/spec/createOpenApiSpec.ts (1)
OpenApiSpecInstance(5-27)
test/composables/openapi.test.ts (2)
src/client.ts (1)
createOpenApiSpec(56-56)src/index.ts (1)
createOpenApiSpec(10-10)
src/composables/useOpenapi.ts (5)
src/index.ts (6)
OpenApiSpecInstance(10-10)parseSpec(11-11)createOpenApiSpec(10-10)injectOpenapi(5-5)getGlobalOpenapi(4-4)useOpenapi(6-6)src/lib/spec/createOpenApiSpec.ts (2)
OpenApiSpecInstance(5-27)createOpenApiSpec(29-263)src/types.ts (1)
OpenAPIDocument(25-25)src/lib/utils/parseSpec.ts (1)
parseSpec(4-22)src/lib/parser/parseOpenapi.ts (1)
parseOpenapi(16-138)
test/composables/useOpenapiWithNoSpec.test.ts (3)
src/client.ts (1)
createOpenApiSpec(56-56)src/index.ts (1)
createOpenApiSpec(10-10)src/lib/spec/createOpenApiSpec.ts (1)
createOpenApiSpec(29-263)
src/composables/usePaths.ts (1)
src/lib/spec/createOpenApiSpec.ts (1)
createOpenApiSpec(29-263)
src/lib/spec/createOpenApiSpec.ts (4)
src/index.ts (2)
OpenApiSpecInstance(10-10)createOpenApiSpec(10-10)src/types.ts (3)
OpenAPIDocument(25-25)ParsedPaths(27-31)ParsedOpenAPI(33-35)test/testsConstants.ts (1)
spec(1-136)src/client.ts (1)
createOpenApiSpec(56-56)
🪛 GitHub Check: lint
src/components/Context/OAProvider.vue
[warning] 47-47:
Variable 'openapi' is already declared in the upper scope
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Run E2E Tests on Vercel Preview
- GitHub Check: Run E2E Tests Locally
🔇 Additional comments (72)
src/components/Feature/OAOperationContext.vue (1)
8-10: Import path updates are correctly refactored and consistent across the codebase.The import path changes on lines 8-10 are accurate. All new module paths exist with the expected exports:
src/lib/operation/operationData.tsexportsOPERATION_DATA_KEYandinitOperationDatasrc/lib/utils/resolveBaseUrl.tsexportsresolveBaseUrlsrc/lib/utils/utils.tsexportsisLocalStorageAvailableNo stray old import paths remain in the codebase, confirming the refactoring is complete and consistent.
src/components/ui/tabs/TabsTrigger.vue (1)
7-7: Import path update looks consistent with utils refactor.src/components/ui/tooltip/TooltipContent.vue (1)
6-6: Import path update looks consistent with utils refactor.test/lib/utils/contentTypeUtils.test.ts (1)
2-9: Test import path update is fine (matches new utils location).src/components/ui/badge/Badge.vue (1)
5-5: Import path update looks consistent with utils refactor.src/components/Common/OAHeading.vue (1)
5-5: Import path update looks consistent with utils refactor.src/components/ui/textarea/Textarea.vue (1)
4-4: Import path update looks consistent with utils refactor.src/lib/parser/generateCodeSamples.ts (1)
6-6: No issues found. The import statement is correct and theresolveBaseUrlfunction is properly exported fromsrc/lib/utils/resolveBaseUrl.ts.src/lib/codeSamples/buildRequest.ts (1)
6-6: No action needed. TheresolveBaseUrlexport exists atsrc/lib/utils/resolveBaseUrl.tsand is correctly imported inbuildRequest.ts.src/lib/codeSamples/buildHarRequest.ts (1)
3-3: Import move to../utils/contentTypeUtilsis consistent with the refactor.
Relative resolution fromsrc/lib/codeSamples/buildHarRequest.ts→src/lib/utils/contentTypeUtils.tslooks correct.docs/.vitepress/theme/components/BrowserWindow.vue (1)
2-2: Import-path update is correct and keeps behavior unchanged.src/lib/examples/getSchemaExample.ts (1)
3-3: Import-path update to../utils/contentTypeUtilslooks correct.
No functional changes in schema example selection logic.src/components/Common/OAMarkdown.vue (1)
3-3: Import-path update is fine; no behavior change.components.json (1)
14-14: LGTM!The alias update to
lib/utils/utilsaligns with the project-wide module restructuring. This ensures consistent resolution for utility imports across the codebase.docs/.vitepress/theme/components/ui/toast/ToastAction.vue (1)
6-6: LGTM!Import path updated consistently with the project-wide utils module restructuring.
test/lib/utils/utils.test.ts (1)
2-2: LGTM!Import path correctly adjusted to the new nested utils module location.
src/components/ui/select/SelectScrollUpButton.vue (1)
7-7: LGTM!Import path updated consistently with the project-wide utils module restructuring.
src/components/Context/OAProviderAsync.vue (2)
42-55: The concern in this review comment about requiring<Suspense>boundaries is technically valid but is already properly addressed in the codebase.OAProviderAsyncuses top-levelawait(lines 42 and 48) and is exclusively rendered within a<Suspense>boundary in its parent componentOAProvider.vue(line 41), with an appropriate fallback template. No action is required.
48-53: Empty spec handling is intentional and working as designed.When
specis falsy,parsedSpecbecomes{}which is the intended default behavior. ThecreateOpenApiSpecfunction is explicitly designed to handle empty specs—all getter methods safely manage the empty object with appropriate null checks and default returns (e.g.,getOperationreturnsnull,getPathsreturns{},getOperationsTagsreturns[]). This is confirmed by comprehensive test coverage including the test case "creates an instance with default empty spec" which validates thatgetSpec()returns{}when no spec is provided.docs/.vitepress/theme/components/ui/toast/ToastTitle.vue (1)
6-6: LGTM! Import path updated correctly.The import path for the
cnutility has been correctly updated to the new nested module structure.src/components/ui/select/SelectSeparator.vue (1)
6-6: LGTM! Import path refactored correctly.The
cnutility import has been updated to reflect the new module structure.src/components/ui/select/SelectItem.vue (1)
7-7: LGTM! Import path updated correctly.The import path for
cnaligns with the new nested utils module structure.src/components/Path/OAPathsGroup.vue (1)
6-6: LGTM! Import path updated correctly.The
scrollToHashutility import has been correctly updated to the new module structure.src/components/ui/select/SelectContent.vue (1)
7-7: LGTM! Import path refactored correctly.The import path update for
cnis consistent with the broader refactor.src/components/ui/select/SelectScrollDownButton.vue (1)
7-7: LGTM! Import path updated correctly.The
cnutility import has been correctly updated to the nested module path.docs/.vitepress/theme/components/sandbox/SandboxPreview.vue (1)
7-7: LGTM! Import path updated correctly.The
scrollToHashutility import has been correctly updated to the new module structure.docs/.vitepress/theme/components/ui/toast/ToastDescription.vue (1)
6-6: LGTM! Import path updated correctly.The import path for
cnhas been correctly updated to the new nested module structure (../../../../../../src/lib/utils/utils). A check of the codebase confirms no remaining old imports fromlib/utilsexist, indicating the migration is complete.src/components/ui/input/Input.vue (1)
4-4: LGTM!Import path correctly updated to the new
lib/utils/utilsmodule location, consistent with the project-wide refactor.docs/.vitepress/theme/components/sandbox/SandboxIframe.vue (1)
4-5: LGTM!Import paths correctly updated for both
deepUnrefandcnutilities to their new module locations underlib/utils/.src/components/ui/button/Button.vue (1)
6-6: LGTM!Import path correctly updated to the new
lib/utils/utilsmodule location.src/components/ui/select/SelectLabel.vue (1)
5-5: LGTM!Import path correctly updated to the new
lib/utils/utilsmodule location, consistent with other Select components in this refactor.src/composables/usePlayground.ts (1)
2-4: LGTM!Import paths correctly updated to the new
lib/operation/operationDatamodule location. Type and value imports are properly separated, following the project's import ordering convention. Based on learnings, the import grouping follows the antfu/eslint-config pattern.src/composables/useTheme.ts (1)
9-11: Import-path refactor looks safe; ensuredeepUnrefis exported from the new location.
No behavioral changes here; main risk is a broken export/module resolution after the move. Consider verifying via typecheck/build on CI.src/components/ui/select/SelectTrigger.vue (1)
6-8:cnimport path update is fine; confirmlib/utils/utilsis the canonical export.src/components/Sample/OACodeSamples.vue (1)
1-6: OperationData/OPERATION_DATA_KEY relocation is fine; ensure the provider and consumers share the same token instance.
If the token is re-declared in multiple modules after the refactor,inject()will silently fail at runtime.src/components/Request/OARequestBody.vue (1)
1-8: Import-path refactor OK; verify OPERATION_DATA_KEY is the single shared source of truth post-move.src/components/ui/checkbox/Checkbox.vue (1)
7-9:cnimport path update looks good.src/components/ui/select/SelectGroup.vue (1)
5-7:cnimport path update looks good.docs/.vitepress/theme/components/sandbox/Sandbox.vue (1)
7-7: LGTM! Import path updated correctly.The
deepUnrefutility has been relocated to theutilssubdirectory. The import path is correct and usage remains unchanged.docs/.vitepress/theme/components/ui/resizable/ResizableHandle.vue (1)
7-7: LGTM! Import path updated correctly.The
cnutility import path has been updated to reflect the new nestedutils/utilsmodule structure, consistent with the repository-wide refactor.docs/.vitepress/theme/components/ui/toast/ToastViewport.vue (1)
6-6: LGTM! Import path updated correctly.The
cnutility import path aligns with the repository-wide refactor moving utilities to the nestedutils/utilsmodule.src/components/ui/label/Label.vue (1)
6-6: LGTM! Import path updated correctly.The
cnutility import path has been updated consistently with the utils module reorganization.src/components/ui/tabs/TabsContent.vue (1)
6-6: LGTM! Import path updated correctly.The
cnutility import path has been updated consistently with the repository-wide utils module reorganization.docs/.vitepress/theme/components/ui/toast/ToastClose.vue (1)
7-7: LGTM! Import path updated correctly.The
cnutility import path has been updated consistently with other toast components in this refactor.src/components/Playground/OAPlaygroundParameters.vue (2)
15-15: LGTM! Import consolidation looks correct.The
isLocalStorageAvailableutility has been properly consolidated into theutils/utilsmodule and added to the existing import statement.
4-4: LGTM! All imports updated consistently across the codebase.Verified that all 12
operationDataimports across the codebase use the correct new pathlib/operation/operationData. No stale import paths remain. The changes in OAPlaygroundParameters.vue align with the rest of the project.src/components/Feature/OASpec.vue (1)
3-3: Component migration to OAProvider is complete and consistent.The migration from
OAContextProvidertoOAProvideris correct. No stale references to the old component remain in the codebase—all imports have been updated and the old component file has been removed. The props and event interface are properly maintained across the component hierarchy.src/components/Feature/OAIntroduction.vue (1)
2-2: LGTM! Consistent migration to OAProvider.The component migration follows the same pattern as other feature components (OAServers, OAOperation). The API surface is preserved.
Also applies to: 15-20
src/lib/operation/operationData.ts (1)
2-7: LGTM! Import paths correctly adjusted for new location.The import paths have been updated to reflect the file's new location in
lib/operation/. All relative path adjustments are correct given the file moved fromlib/tolib/operation/.test/composables/usePlayground.setParameterValue.test.ts (1)
1-1: LGTM! Test import path updated correctly.The import path correctly reflects the relocated
operationDatamodule fromlib/tolib/operation/.src/composables/usePaths.ts (1)
3-3: LGTM! Factory migration consistent with broader refactor.The migration from
OpenApitocreateOpenApiSpecis correctly implemented. The transformation pipeline and method usage (getPathsByVerbs,getFilteredTags) are preserved.Also applies to: 14-20
src/components/Feature/OAOperation.vue (1)
3-3: LGTM! Consistent OAProvider migration.The component migration preserves all props (
:spec,:spec-url) and events (@update:spec), maintaining backward compatibility. The slot structure remains unchanged.Also applies to: 56-74
src/components/Playground/OAPlaygroundBodyInput.vue (1)
5-5: Import paths verified and correctly organized.The import paths in
OAPlaygroundBodyInput.vuecorrectly reference the reorganized modules:
- Line 5:
createCompositeKeyfromlib/playground/createCompositeKey.ts(module exists, export present)- Lines 6-11: utility functions (
isFormUrlEncoded,isJson,isMultipartFormData,isXml) fromlib/utils/contentTypeUtils.ts(module exists, all exports present)src/composables/useSidebar.ts (1)
8-8: Return type compatibility verified. The migration from theOpenApiconstructor to thecreateOpenApiSpecfactory correctly preserves the lazy initialization pattern.createOpenApiSpecreturnsOpenApiSpecInstancewith all required methods:getPaths,getOperationsTags,getPathsWithoutTags, andgetFilteredTags, as used throughout the file.src/components/Feature/OAServers.vue (1)
2-2: OAProvider API compatibility verified.The migration from
OAContextProvidertoOAProvideris correct.OAProviderproperly exposes the required:specprop and#default="{ openapi }"slot structure. No remaining references toOAContextProviderwere found in the codebase.test/composables/openapi.test.ts (3)
2-2: Good: tests now exercise the public entry export forcreateOpenApiSpec.
7-7: Good migration from singleton-styleOpenApi(...)to factory-stylecreateOpenApiSpec(...).Also applies to: 10-10
26-29: Good coverage fororiginalSpecplumbing via the new factory API.src/index.ts (1)
3-7: ExportinggetGlobalOpenapi/injectOpenapi/useOpenapifrom the root is a nice API ergonomics improvement.src/components/Playground/OAPlayground.vue (1)
3-3: Import path refactor looks consistent with the newlib/operation/*layout.Also applies to: 8-8
src/components/Feature/OAInfo.vue (1)
2-2: VerifyOAProvidermatches the old provider slot contract ({ openapi }) for sync rendering.
Given this is a component-boundary change, please confirmOAProvideralways provides the expected slot props and handles bothObjectandStringspecs the same way the removed provider did.Also applies to: 14-19
test/composables/useOpenapi.test.ts (1)
1-217: Nice coverage for the syncuseOpenapisurface (method presence + tag/path helpers).src/client.ts (2)
4-4: Good:OAEnhanceAppContext.openapiis now typed to the newOpenApiSpecInstancesurface.Also applies to: 11-12
56-56: Good:createOpenApiSpecis re-exported from the client entry for consumers who import fromvitepress-openapi/client.src/components/Context/OAProvider.vue (2)
32-33: Non-reactive computed values may cause stale behavior.
needsAsyncandexistingOpenapiare computed once during setup. If thespec,specUrl, oropenapiprops change after initial render, these values won't update, potentially leading to incorrect rendering paths.Consider using
computed()for reactive behavior:-const needsAsync = props.spec || props.specUrl -const existingOpenapi = props.openapi ?? injectOpenapi() ?? getGlobalOpenapi() +const needsAsync = computed(() => props.spec || props.specUrl) +const existingOpenapi = computed(() => props.openapi ?? injectOpenapi() ?? getGlobalOpenapi())Then update references in the template to use
.valueor rely on Vue's auto-unwrapping.
35-37: Conditional provide executes only at setup time.The
providecall inside theifblock runs once during component setup. IfexistingOpenapiorneedsAsyncchanges later, the provided value won't update. This is likely intentional given the current non-reactive design, but worth confirming this aligns with expected usage patterns.src/components/Path/OAPaths.vue (2)
33-33: Non-reactive OpenAPI instance retrieval.Similar to
OAProvider.vue,openapiis computed once at setup time. If the global or injected instance changes after mount, this component won't react. This appears intentional for the current architecture but limits dynamic spec switching.
37-63: LGTM! Proper null-guard and slot forwarding.The template correctly guards against null
openapiwithv-if, and the slot forwarding pattern properly exposes all named slots toOAOperationContent. The explicitopenapiprop pass-through ensures the child component receives the instance.src/composables/useOpenapi.ts (2)
82-87:asyncParsealways mutates global instance.The
asyncParsefunction unconditionally assigns toglobalInstance, even when the component might have received its instance via injection. This could unexpectedly overwrite a different spec that was set elsewhere.If local-only async parsing is needed in the future, consider accepting an option to avoid mutating the global state.
90-93: Return type mixes instance properties with method.The returned object spreads instance properties and adds an
asyncmethod. This design works but means consumers get a mix of static property values (captured at call time) and methods. ThespecandoriginalSpecproperties on the spread will be snapshots, while methods likegetSpec()will return current values.This is likely intentional but worth documenting for API consumers.
src/lib/spec/createOpenApiSpec.ts (2)
40-48:getSpec()has defensive double-check but may still throw unexpectedly.The function checks
!innerSpectwice—once to trigger lazy init and once to throw. However, ifoptions.specisnullorundefined, the first check passes,setSpecis called with{}, andinnerSpecbecomes{}. The second check then passes (since{}is truthy), so no error is thrown.The throw at line 45-46 appears unreachable given the current logic. If the intent is to error on missing specs, the condition should check for empty objects too, or the throw should be removed.
29-32: LGTM! Clean factory function signature with sensible defaults.The factory function has a clear signature with optional parameters and appropriate defaults. The separation of
specandoriginalSpecallows tracking of both parsed and original versions.
(cherry picked from commit 1d89878)
cfd3407 to
c6e90cc
Compare
c6e90cc to
63849d9
Compare
There was a problem hiding this comment.
Actionable comments posted: 10
♻️ Duplicate comments (7)
src/components/Context/OAProvider.vue (2)
47-49: Variable shadowing resolved.The slot variable has been correctly renamed to
asyncOpenapito avoid shadowing theopenapiprop.
58-60: Fallback message lacks i18n and styling.This hardcoded English message should use a translation key for i18n support. Consider using the project's error styling pattern.
src/index.ts (1)
17-21: Good backward compatibility approach with deprecated alias.The deprecated
OpenApialias pointing tocreateOpenApiSpecaddresses the breaking change concern from the previous review. This allows existing consumers to migrate gradually.Consider adding this deprecation to release notes or changelog to ensure visibility.
src/composables/useOpenapi.ts (3)
11-13: Module-level singleton may cause SSR state pollution.
globalInstancepersists across requests in SSR environments (e.g., VitePress SSR builds), potentially causing state leakage between users/requests.For VitePress specifically, consider if this is acceptable given typical usage patterns, or if app-level provide/inject would be safer.
#!/bin/bash # Check if VitePress SSR is used rg -n "ssr|SSR" --type=ts -g '!node_modules' | head -10
15-20: Good extraction of shared instance building logic.The
buildInstancehelper consolidates the common logic between sync and async instance creation, addressing the previous review feedback about code duplication.
76-76: Silent empty instance fallback may mask configuration errors.When no spec is provided and no injection/global instance exists, silently creating an empty instance could hide misconfiguration where a spec was expected.
Consider adding a development-mode warning:
- const instance = injectOpenapi() ?? globalInstance ?? createOpenApiSpec({}) + const injected = injectOpenapi() + const instance = injected ?? globalInstance ?? createOpenApiSpec({}) + if (!injected && !globalInstance && import.meta.env.DEV) { + console.warn('[useOpenapi] No spec provided and no existing instance found. Using empty instance.') + }src/components/Context/OAProviderAsync.vue (1)
44-46: Emitting during async setup may fire before parent listeners are attached.This concern from the previous review remains valid. The
emit('update:spec', spec)occurs during async setup, which may complete before the parent has attached listeners.Consider deferring with
onMounted:+import { provide, onMounted } from 'vue' ... -if (spec) { - emit('update:spec', spec) -} +onMounted(() => { + if (spec) { + emit('update:spec', spec) + } +})
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (2)
e2e/local/tests.spec.ts-snapshots/parameters-1-chromium-linux.pngis excluded by!**/*.pnge2e/local/tests.spec.ts-snapshots/parameters-1-firefox-linux.pngis excluded by!**/*.png
📒 Files selected for processing (40)
docs/.vitepress/config.mts(1 hunks)src/components/Common/OACodeValue.vue(1 hunks)src/components/Common/OAHeading.vue(1 hunks)src/components/Common/OAMarkdown.vue(1 hunks)src/components/Context/OAProvider.vue(1 hunks)src/components/Context/OAProviderAsync.vue(2 hunks)src/components/Feature/OAOperationContext.vue(1 hunks)src/components/Parameter/OAParameter.vue(1 hunks)src/components/Parameter/OAParameterExamples.vue(1 hunks)src/components/Path/OAPathsGroup.vue(1 hunks)src/components/Playground/OAPlayground.vue(1 hunks)src/components/Playground/OAPlaygroundBodyInput.vue(1 hunks)src/components/Playground/OAPlaygroundParameterInput.vue(1 hunks)src/components/Playground/OAPlaygroundParameters.vue(1 hunks)src/components/Playground/OAPlaygroundResponseContent.vue(1 hunks)src/components/Request/OARequestBody.vue(1 hunks)src/components/Sample/OACodeSamples.vue(1 hunks)src/components/ui/badge/Badge.vue(1 hunks)src/components/ui/button/Button.vue(1 hunks)src/components/ui/checkbox/Checkbox.vue(1 hunks)src/components/ui/input/Input.vue(1 hunks)src/components/ui/label/Label.vue(1 hunks)src/components/ui/select/SelectContent.vue(1 hunks)src/components/ui/select/SelectGroup.vue(1 hunks)src/components/ui/select/SelectItem.vue(1 hunks)src/components/ui/select/SelectLabel.vue(1 hunks)src/components/ui/select/SelectScrollDownButton.vue(1 hunks)src/components/ui/select/SelectScrollUpButton.vue(1 hunks)src/components/ui/select/SelectSeparator.vue(1 hunks)src/components/ui/select/SelectTrigger.vue(1 hunks)src/components/ui/tabs/TabsContent.vue(1 hunks)src/components/ui/tabs/TabsList.vue(1 hunks)src/components/ui/tabs/TabsTrigger.vue(1 hunks)src/components/ui/textarea/Textarea.vue(1 hunks)src/components/ui/tooltip/TooltipContent.vue(1 hunks)src/composables/useOpenapi.ts(1 hunks)src/index.ts(1 hunks)test/composables/useOpenapi.test.ts(1 hunks)tsconfig.json(1 hunks)vite.config.ts(1 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-07-15T19:55:33.067Z
Learnt from: alexchexes
Repo: enzonotario/vitepress-openapi PR: 272
File: src/components/Response/OAResponse.vue:6-6
Timestamp: 2025-07-15T19:55:33.067Z
Learning: The vitepress-openapi project uses antfu/eslint-config with eslint-plugin-perfectionist which enforces import ordering by grouping imports by type rather than alphabetically. Import suggestions should respect this convention: Vue core imports, local composables, component imports, external library imports, then CSS imports.
Applied to files:
src/components/ui/checkbox/Checkbox.vuesrc/components/ui/tabs/TabsContent.vuetsconfig.jsonsrc/components/ui/select/SelectSeparator.vuesrc/components/ui/input/Input.vuesrc/components/ui/select/SelectGroup.vuesrc/components/ui/tabs/TabsList.vue
📚 Learning: 2025-07-10T21:25:08.434Z
Learnt from: alexchexes
Repo: enzonotario/vitepress-openapi PR: 267
File: src/locales/en.json:60-60
Timestamp: 2025-07-10T21:25:08.434Z
Learning: In the vitepress-openapi project, the OASchemaPropertyAttributes component follows a pattern where translation keys are passed from parent components as props, and the child component handles the actual translation using the t() function. This allows for clean separation of concerns where parent components provide the keys and child components handle the i18n translation.
Applied to files:
src/components/Playground/OAPlaygroundBodyInput.vuesrc/components/Parameter/OAParameter.vuesrc/components/Request/OARequestBody.vuesrc/components/Playground/OAPlayground.vue
📚 Learning: 2025-07-27T18:38:22.901Z
Learnt from: alexchexes
Repo: enzonotario/vitepress-openapi PR: 0
File: :0-0
Timestamp: 2025-07-27T18:38:22.901Z
Learning: In the vitepress-openapi project, wrapping translation keys with t() before passing them to OASchemaPropertyAttributes causes double translation issues and console warnings. The component expects untranslated keys like 'Valid values' which it then translates using t(titleCase(key)). Passing already translated strings like 'Valores válidos' results in translation lookup failures and console warnings.
Applied to files:
src/components/Context/OAProvider.vue
📚 Learning: 2025-07-09T19:04:58.788Z
Learnt from: alexchexes
Repo: enzonotario/vitepress-openapi PR: 258
File: test/composables/useSidebar.multipleTags.test.ts:63-232
Timestamp: 2025-07-09T19:04:58.788Z
Learning: The sidebarItemTemplateForMethodPath function in vitepress-openapi generates titles with fallback logic: operation['x-sidebar-title'] || summary || `${method.toUpperCase()} ${path}`. When testing operations without summaries, the expected title should be the fallback format like 'GET /account/stats', not just the path.
Applied to files:
src/components/Context/OAProvider.vue
🧬 Code graph analysis (3)
test/composables/useOpenapi.test.ts (2)
src/composables/useOpenapi.ts (1)
useOpenapi(58-95)test/testsConstants.ts (2)
spec(1-136)specWithSchemaAndContentTypes(512-566)
src/index.ts (2)
src/client.ts (1)
createOpenApiSpec(56-56)src/lib/spec/createOpenApiSpec.ts (1)
createOpenApiSpec(29-263)
src/composables/useOpenapi.ts (4)
src/index.ts (6)
OpenApiSpecInstance(11-11)createOpenApiSpec(11-11)parseSpec(12-12)injectOpenapi(6-6)getGlobalOpenapi(5-5)useOpenapi(7-7)src/client.ts (2)
createOpenApiSpec(56-56)useOpenapi(49-49)src/lib/utils/parseSpec.ts (1)
parseSpec(4-22)src/lib/parser/parseOpenapi.ts (1)
parseOpenapi(16-138)
🪛 GitHub Actions: .github/workflows/lint.yml
src/components/Common/OACodeValue.vue
[error] 5-5: ESLint: perfectionist/sort-imports - Expected "@/lib/format/formatValueForDisplay" (external) to come before "../../composables/usePlayground" (parent).
🪛 GitHub Check: lint
src/components/Feature/OAOperationContext.vue
[failure] 7-7:
Expected "@/lib/codeSamples/buildRequest" (external) to come before "../../composables/useTheme" (parent)
src/components/Path/OAPathsGroup.vue
[failure] 6-6:
Expected "@/lib/utils/utils" (external) to come before "../../composables/useTheme" (parent)
src/components/Parameter/OAParameter.vue
[failure] 4-4:
Expected "@/lib/parser/constraintsParser" to come before "scule"
src/components/Common/OAMarkdown.vue
[failure] 3-3:
Expected "@/lib/utils/utils" (external) to come before "../../composables/useMarkdown" (parent)
src/components/Parameter/OAParameterExamples.vue
[failure] 6-6:
Expected "@/lib/examples/getPropertyExamples" (external) to come before "../../composables/useTheme" (parent)
src/components/Common/OAHeading.vue
[failure] 5-5:
Expected "@/lib/utils/utils" (external) to come before "../../composables/useTheme" (parent)
src/components/Common/OACodeValue.vue
[failure] 5-5:
Expected "@/lib/format/formatValueForDisplay" (external) to come before "../../composables/usePlayground" (parent)
src/components/Playground/OAPlayground.vue
[failure] 8-8:
Expected "@/lib/operation/operationData" (external) to come before "../../composables/useTheme" (parent)
[failure] 3-3:
Expected "@/lib/operation/operationData" to come before "@scalar/openapi-types"
src/components/Context/OAProviderAsync.vue
[failure] 6-6:
Expected "@/lib/parser/parseOpenapi" (external) to come before "../../composables/useOpenapi" (parent)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Run E2E Tests on Vercel Preview
- GitHub Check: Run E2E Tests Locally
🔇 Additional comments (37)
src/components/Playground/OAPlaygroundResponseContent.vue (1)
4-4: LGTM!The import path update from a relative path to the
@alias is a clean refactor that improves maintainability by avoiding deep relative paths.src/components/Request/OARequestBody.vue (1)
2-2: LGTM! Import paths updated correctly.The import paths have been successfully updated to use the
@alias, which improves maintainability by making paths shorter and easier to refactor. Both imports from the same module are updated consistently. The@alias is properly configured in bothvite.config.tsandtsconfig.jsonto point to thesrc/directory, and the new module pathsrc/lib/operation/operationData.tsexists as expected.src/components/Playground/OAPlaygroundBodyInput.vue (1)
5-11: Alias-based utility imports look correct and non-breakingSwitching
createCompositeKeyand thecontentTypeUtilshelpers to@-based paths is consistent with the alias refactor and does not affect runtime behavior, assuming the alias is configured tosrc. The usages below in this file remain type-safe and coherent with the previous logic.src/components/ui/textarea/Textarea.vue (1)
1-4: Alias-basedcnimport looks goodSwitching
cnto@/lib/utils/utilsis consistent with the new alias setup and does not affect behavior.src/components/ui/badge/Badge.vue (1)
1-5:cnalias import change is correctUsing
@/lib/utils/utilsforcnmatches the new utils location and alias strategy; no functional impact.vite.config.ts (1)
9-13: Vite@alias configuration looks appropriateDefining
resolve.alias['@'] = resolve(__dirname, 'src')is consistent with the new import paths and integrates cleanly with the existing build config.tsconfig.json (1)
16-19: LGTM!The TypeScript path alias configuration is correctly set up to enable
@/*imports resolving tosrc/*, which aligns with the Vite configuration and enables consistent alias usage throughout the codebase.docs/.vitepress/config.mts (1)
283-284: LGTM!The Vite alias configuration correctly maps
@to thesrcdirectory, enabling runtime module resolution that aligns with the TypeScript path alias configuration intsconfig.json.src/components/ui/tabs/TabsTrigger.vue (1)
7-7: LGTM!The import path has been correctly updated to use the new
@alias, improving maintainability by replacing the brittle deep relative path with a stable alias reference.src/components/ui/tabs/TabsList.vue (1)
6-6: LGTM! Previous concern addressed.The import path has been updated to use the stable
@alias, directly addressing the previous review feedback about avoiding brittle deep relative paths. This improves maintainability and reduces the risk of breakage during future refactoring.src/components/ui/select/SelectItem.vue (1)
7-7: LGTM!The import path has been correctly updated to use the new
@alias, consistent with the project-wide refactoring to improve import maintainability.src/components/ui/select/SelectContent.vue (1)
7-7: LGTM!The import path has been correctly updated to use the new
@alias, consistent with the project-wide refactoring to improve import maintainability.src/components/ui/button/Button.vue (1)
6-6: Alias import update looks correctThe cn import now points to
@/lib/utils/utils, consistent with the new alias-based utils layout and doesn’t affect runtime behavior.src/components/ui/input/Input.vue (1)
4-4: Consistent cn alias refactorThe cn import path refactor to
@/lib/utils/utilsaligns with the new alias scheme and keeps the rest of the component unchanged.src/components/ui/select/SelectLabel.vue (1)
5-5: cn import path change is safeUpdating cn to
@/lib/utils/utilsis consistent with the shared utils refactor and doesn’t alter the component’s behavior.src/components/ui/select/SelectScrollDownButton.vue (1)
7-7: Import alias migration looks goodThe cn import now uses the shared
@/lib/utils/utilsalias, matching the rest of the UI components with no behavior change.src/components/ui/select/SelectSeparator.vue (1)
6-6: cn alias refactor is consistentSwitching cn to
@/lib/utils/utilsfollows the new utils alias convention and keeps runtime behavior identical.src/components/ui/select/SelectScrollUpButton.vue (1)
7-7: Safe cn import path updateThe cn import path update to
@/lib/utils/utilsis aligned with the project-wide refactor and doesn’t impact the component logic.src/components/ui/tooltip/TooltipContent.vue (1)
6-6: Tooltip cn alias change is alignedThe cn import update to
@/lib/utils/utilsmatches the shared utils alias pattern and doesn’t alter behavior.src/components/ui/label/Label.vue (1)
6-6: LGTM: Import path updated to use alias.The import path refactoring is consistent with the project-wide aliasing strategy.
src/components/ui/select/SelectTrigger.vue (1)
7-7: LGTM: Import path updated to use alias.The import path refactoring is consistent with the project-wide aliasing strategy.
src/components/ui/tabs/TabsContent.vue (1)
6-6: LGTM: Import path updated to use alias.The import path refactoring is consistent with the project-wide aliasing strategy, and the import ordering follows the project's eslint-plugin-perfectionist conventions.
src/components/ui/checkbox/Checkbox.vue (1)
8-8: LGTM: Import path updated to use alias.The import path refactoring is consistent with the project-wide aliasing strategy, and the import ordering follows the project's conventions.
src/components/ui/select/SelectGroup.vue (1)
6-6: LGTM: Import path updated to use alias.The import path refactoring is consistent with the project-wide aliasing strategy, and the import ordering follows the project's conventions.
src/components/Playground/OAPlaygroundParameterInput.vue (1)
4-5: LGTM: Import paths updated to use alias.The import path refactoring for both
getPropertyExampleandformatValueForPlaceholderutilities is consistent with the project-wide aliasing strategy.src/components/Playground/OAPlaygroundParameters.vue (1)
4-4: LGTM: Import paths comprehensively updated to use alias.All six import path updates are consistent with the project-wide aliasing strategy and reflect the module reorganization (e.g.,
operationDatamoved tolib/operation/operationData).Also applies to: 11-15
src/components/Sample/OACodeSamples.vue (1)
2-2: LGTM: Import paths updated to use alias and new module location.The imports have been refactored to use the alias-based path and reflect the module reorganization from
lib/operationDatatolib/operation/operationData. BothOperationDatatype andOPERATION_DATA_KEYsymbol are correctly exported from the module and properly imported on lines 2 and 5.test/composables/useOpenapi.test.ts (4)
1-28: LGTM! Well-structured test setup with comprehensive API coverage.The test file properly validates all public methods of the
useOpenapicomposable. The async test suites correctly usebeforeAllfor async setup instead of asyncdescribecallbacks.
219-233: Async test suite correctly implements the beforeAll pattern.The past review concern about async
describecallbacks has been properly addressed. The setup now uses synchronousdescribewithbeforeAllfor async initialization.
235-309: Comprehensive security scheme testing.The
securityUitests cover important scenarios: single schemes, combined (AND) schemes, alternative (OR) schemes, and empty security. This provides good coverage for the security UI generation logic.
60-64: The minimal spec is acceptable for this edge-case test. The implementation explicitly handles missingpaths(returning empty array at line 171) and uses null coalescing for missinginfoandservers. This defensive pattern is used consistently across the test suite for testing empty/edge-case behavior. No changes needed.src/components/Context/OAProvider.vue (1)
32-37: Non-reactive computed values won't update on prop changes.
needsAsyncandexistingOpenapiare computed once during setup. If props change after mount (e.g.,specbecomes available later), the component won't re-evaluate these conditions.If dynamic prop changes are expected, consider using
computed():-const needsAsync = props.spec || props.specUrl -const existingOpenapi = props.openapi ?? injectOpenapi() ?? getGlobalOpenapi() +const needsAsync = computed(() => props.spec || props.specUrl) +const existingOpenapi = computed(() => props.openapi ?? injectOpenapi() ?? getGlobalOpenapi())Then update template references to
needsAsync.value/existingOpenapi.value, or useunref().Is dynamic prop mutation expected for this component, or is it intended to be configured once at mount?
src/index.ts (1)
4-11: Public API surface updated with new composable exports.The exports now expose
getGlobalOpenapi,injectOpenapi, anduseOpenapialongsidecreateOpenApiSpecand its type. This provides a clean API for consumers.src/composables/useOpenapi.ts (2)
78-89: Async method correctly throws when no spec available.The
asyncParsefunction properly validates that a spec is provided before proceeding, which is good defensive programming.
68-74: Global instance mutation on each call with spec.The codebase demonstrates this pattern: theme setup calls
useOpenapi({ spec })to initialize globally, then individual pages (e.g.,docs/customizations/playground-examples.md) call it again with different specs. Each call overwritesglobalInstance, causing state to shift between pages. This affects components likeoperationLink.tsthat useuseOpenapi()without spec and rely on the global fallback.Components using the injection pattern (
injectOpenapi()) are insulated, but those depending onglobalInstancewill get inconsistent state. Consider:
- Documenting this as expected behavior (one-time initialization in theme setup only)
- Preventing overwriting after initial setup
- Requiring spec to be passed through component props/injection rather than relying on global state
src/components/Context/OAProviderAsync.vue (2)
48-55: The concern about runtime issues from an empty spec object is not substantiated. ThegetSpec()method increateOpenApiSpec.ts(lines 40-45) explicitly handles the empty object case: it either uses the provided spec, falls back to an empty object, or throws a clear error ("OpenAPI spec is not defined"). Additionally, all methods that callgetSpec()defensively access properties using null coalescing operators (??), returning safe fallback values like empty arrays or objects when properties are missing. The current implementation is already protected against the described runtime issues.Likely an incorrect or invalid review comment.
35-40:parseSpecToDocumentfunction is not used correctly in the current implementation.The function is defined and called at line 52 to provide the
originalSpecparameter. However,parseOpenapi().parseAsync()at line 48 already handles string-to-object conversion internally viaparseSpec(). Since the rawspecvariable (which could be a string fromfetchSpec()) is passed to bothparseAsync()andparseSpecToDocument(), the function duplicates the parsing logic already present in the pipeline. Consider removingparseSpecToDocument()and passing the result ofparseAsync()for bothspecandoriginalSpecparameters, or clarify the intended difference between the two values.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (5)
src/components/Playground/OAPlaygroundBodyInput.vue (1)
3-3: Optional: alignOAExampleObjectimport with@aliasFor consistency with the rest of the file, you could switch this to the alias path (e.g.
@/types) if that maps correctly in your tsconfig/vite alias setup.src/components/Context/OAProvider.vue (1)
47-48: Variable shadowing resolved.The slot variable has been correctly renamed to
asyncOpenapi, resolving the shadowing issue flagged in the previous review.src/components/Context/OAProviderAsync.vue (2)
3-7: Import ordering issue flagged in previous review.The import ordering concern (@ imports should precede ../../ imports) was already identified in the previous review. Ensure the linter rule is satisfied.
44-46: Emit timing during async setup flagged in previous review.The concern about
emit('update:spec', spec)potentially firing before parent listeners are attached was already raised in the previous review. Deferring withonMountedornextTickmay be necessary depending on parent usage patterns.src/components/Common/OAHeading.vue (1)
2-5: Import ordering issue already flagged.This import ordering linter failure was already identified in a previous review. Please ensure the imports are reordered to satisfy the linter as suggested in the earlier comment.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (37)
docs/.vitepress/config.mts(1 hunks)src/components/Common/OACodeValue.vue(1 hunks)src/components/Common/OAHeading.vue(1 hunks)src/components/Common/OAMarkdown.vue(1 hunks)src/components/Context/OAProvider.vue(1 hunks)src/components/Context/OAProviderAsync.vue(2 hunks)src/components/Feature/OAOperationContext.vue(1 hunks)src/components/Parameter/OAParameter.vue(1 hunks)src/components/Parameter/OAParameterExamples.vue(1 hunks)src/components/Path/OAPathsGroup.vue(1 hunks)src/components/Playground/OAPlayground.vue(1 hunks)src/components/Playground/OAPlaygroundBodyInput.vue(1 hunks)src/components/Playground/OAPlaygroundParameterInput.vue(1 hunks)src/components/Playground/OAPlaygroundParameters.vue(1 hunks)src/components/Playground/OAPlaygroundResponseContent.vue(1 hunks)src/components/Request/OARequestBody.vue(1 hunks)src/components/Sample/OACodeSamples.vue(1 hunks)src/components/ui/badge/Badge.vue(1 hunks)src/components/ui/button/Button.vue(1 hunks)src/components/ui/checkbox/Checkbox.vue(1 hunks)src/components/ui/input/Input.vue(1 hunks)src/components/ui/label/Label.vue(1 hunks)src/components/ui/select/SelectContent.vue(1 hunks)src/components/ui/select/SelectGroup.vue(1 hunks)src/components/ui/select/SelectItem.vue(1 hunks)src/components/ui/select/SelectLabel.vue(1 hunks)src/components/ui/select/SelectScrollDownButton.vue(1 hunks)src/components/ui/select/SelectScrollUpButton.vue(1 hunks)src/components/ui/select/SelectSeparator.vue(1 hunks)src/components/ui/select/SelectTrigger.vue(1 hunks)src/components/ui/tabs/TabsContent.vue(1 hunks)src/components/ui/tabs/TabsList.vue(1 hunks)src/components/ui/tabs/TabsTrigger.vue(1 hunks)src/components/ui/textarea/Textarea.vue(1 hunks)src/components/ui/tooltip/TooltipContent.vue(1 hunks)tsconfig.json(1 hunks)vite.config.ts(1 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-07-15T19:55:33.067Z
Learnt from: alexchexes
Repo: enzonotario/vitepress-openapi PR: 272
File: src/components/Response/OAResponse.vue:6-6
Timestamp: 2025-07-15T19:55:33.067Z
Learning: The vitepress-openapi project uses antfu/eslint-config with eslint-plugin-perfectionist which enforces import ordering by grouping imports by type rather than alphabetically. Import suggestions should respect this convention: Vue core imports, local composables, component imports, external library imports, then CSS imports.
Applied to files:
src/components/Path/OAPathsGroup.vuesrc/components/Feature/OAOperationContext.vuesrc/components/Parameter/OAParameter.vuesrc/components/ui/select/SelectGroup.vuesrc/components/Common/OAMarkdown.vuesrc/components/ui/tabs/TabsList.vuesrc/components/ui/checkbox/Checkbox.vuesrc/components/Common/OACodeValue.vuesrc/components/Playground/OAPlayground.vuesrc/components/Common/OAHeading.vuesrc/components/Parameter/OAParameterExamples.vuesrc/components/ui/input/Input.vuevite.config.tstsconfig.jsonsrc/components/Context/OAProviderAsync.vuesrc/components/Playground/OAPlaygroundBodyInput.vuesrc/components/ui/select/SelectSeparator.vue
📚 Learning: 2025-07-10T21:25:08.434Z
Learnt from: alexchexes
Repo: enzonotario/vitepress-openapi PR: 267
File: src/locales/en.json:60-60
Timestamp: 2025-07-10T21:25:08.434Z
Learning: In the vitepress-openapi project, the OASchemaPropertyAttributes component follows a pattern where translation keys are passed from parent components as props, and the child component handles the actual translation using the t() function. This allows for clean separation of concerns where parent components provide the keys and child components handle the i18n translation.
Applied to files:
src/components/Parameter/OAParameter.vuesrc/components/Playground/OAPlayground.vuesrc/components/Request/OARequestBody.vuesrc/components/Playground/OAPlaygroundBodyInput.vue
📚 Learning: 2025-07-27T18:38:22.901Z
Learnt from: alexchexes
Repo: enzonotario/vitepress-openapi PR: 0
File: :0-0
Timestamp: 2025-07-27T18:38:22.901Z
Learning: In the vitepress-openapi project, wrapping translation keys with t() before passing them to OASchemaPropertyAttributes causes double translation issues and console warnings. The component expects untranslated keys like 'Valid values' which it then translates using t(titleCase(key)). Passing already translated strings like 'Valores válidos' results in translation lookup failures and console warnings.
Applied to files:
src/components/Context/OAProvider.vue
📚 Learning: 2025-07-09T19:04:58.788Z
Learnt from: alexchexes
Repo: enzonotario/vitepress-openapi PR: 258
File: test/composables/useSidebar.multipleTags.test.ts:63-232
Timestamp: 2025-07-09T19:04:58.788Z
Learning: The sidebarItemTemplateForMethodPath function in vitepress-openapi generates titles with fallback logic: operation['x-sidebar-title'] || summary || `${method.toUpperCase()} ${path}`. When testing operations without summaries, the expected title should be the fallback format like 'GET /account/stats', not just the path.
Applied to files:
src/components/Context/OAProvider.vue
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Run E2E Tests on Vercel Preview
- GitHub Check: Run E2E Tests Locally
🔇 Additional comments (36)
src/components/Playground/OAPlaygroundResponseContent.vue (1)
2-2: The@alias is properly configured and the target path exists.The import path is correctly set up. The
@alias is configured in bothtsconfig.jsonandvite.config.tsto resolve to thesrcdirectory, the target modulesrc/lib/playground/getDownloadFileName.tsexists, and thegetDownloadFileNameFromContentDispositionfunction is properly exported from it.src/components/Playground/OAPlaygroundBodyInput.vue (1)
4-11: Alias import refactor here looks correctSwitching to the
@-based paths forcreateCompositeKeyandcontentTypeUtilskeeps this file aligned with the new module resolution scheme and matches their existing usage patterns below. No behavioral changes introduced.src/components/Feature/OAOperationContext.vue (1)
4-7: LGTM! Refactoring to path aliases is clean.The imports have been successfully updated to use the
@/path alias, pointing to the newly reorganized library structure. The current import order follows eslint-plugin-perfectionist's default grouping, with alias imports properly positioned before the parent import on line 10, resolving the issue flagged in the previous review.src/components/Context/OAProvider.vue (1)
32-37: Clarify precedence when bothopenapiprop andspec/specUrlare provided.If a caller provides both the
openapiprop (an existing instance) andspec/specUrl, the current logic prioritizesspec/specUrl(line 32 setsneedsAsyncto truthy, line 35's condition becomes false, and line 41 enters the async path), effectively ignoring theopenapiprop. This behavior may not be intuitive to consumers.Consider either documenting this precedence clearly in component docs/props, or adding a warning in development mode when both are provided.
Would you like me to generate a prop validation warning for this scenario?
src/components/Context/OAProviderAsync.vue (1)
48-55: Async initialization and provide logic looks correct.The async resolution of the spec, parsing via
parseOpenapi().parseAsync, creation of the OpenAPI instance withcreateOpenApiSpec, and provision viaOPENAPI_LOCAL_KEYfollows a clean async pattern that integrates well with Vue 3's Suspense.src/components/Parameter/OAParameterExamples.vue (1)
2-4: Alias-based example utils imports look correctSwitching the example helpers to
@/lib/examples/*and placing them before the parent composable imports is consistent with the alias setup and resolves the earlier import-ordering lint. No behavioral change introduced here.src/components/Common/OAMarkdown.vue (1)
2-3: cn utility import refactor is consistent with utils aliasImporting
cnfrom@/lib/utils/utilsinstead of the relative utils path aligns this component with the shared alias pattern and keeps the template logic unchanged.src/components/Path/OAPathsGroup.vue (1)
3-6: scrollToHash import moved to utils alias without behavior changeUsing
@/lib/utils/utilsforscrollToHashmatches the new alias convention and keepsonPathClicksemantics identical.src/components/Common/OACodeValue.vue (1)
2-5: formatValueForDisplay import updated to alias; component behavior unchangedPointing
formatValueForDisplayto@/lib/format/formatValueForDisplayis consistent with the alias-based structure and doesn’t affect how values are rendered or how clicks propagate to the playground.tsconfig.json (1)
16-21: TS path alias configuration matches new '@/…' importsAdding
"paths": { "@/*": ["src/*"] }undercompilerOptionsand keepingincludepointed atsrcensures TypeScript can resolve the new@/…imports used throughout the components. As long as your bundler (e.g., Vite) is configured with the same@→srcalias, TS and runtime resolution will stay in sync.src/components/Parameter/OAParameter.vue (1)
2-4: getConstraints import moved to parser alias cleanlySwitching
getConstraintsto@/lib/parser/constraintsParserkeeps the constraints logic intact and aligns this component with the alias-based parser location.src/components/Playground/OAPlaygroundParameterInput.vue (1)
2-3: Alias-based imports for examples and formatting look correctUsing
@/lib/examples/getPropertyExampleand@/lib/format/formatValueForDisplaykeeps the parameter example and placeholder formatting logic unchanged while matching the new alias structure.src/components/ui/tabs/TabsList.vue (1)
4-6: cn import switched to stable utils alias with no behavior changeImporting
cnfrom@/lib/utils/utilsinstead of the deep relative path makes this component more robust to moves and is consistent with the rest of the UI layer.src/components/ui/checkbox/Checkbox.vue (1)
5-5: LGTM!The alias-based import path aligns with the project-wide refactoring and maintains proper import ordering conventions.
src/components/ui/textarea/Textarea.vue (1)
3-3: LGTM!Import path update is consistent with the project-wide alias refactoring.
src/components/ui/select/SelectItem.vue (1)
4-4: LGTM!The alias-based import follows the consistent refactoring pattern across the codebase.
src/components/ui/select/SelectContent.vue (1)
4-4: LGTM!Import path refactoring applied correctly while maintaining proper import ordering.
src/components/ui/button/Button.vue (1)
5-5: LGTM!The import path update maintains consistency with the project-wide alias refactoring.
src/components/ui/select/SelectLabel.vue (1)
4-4: LGTM!Import path update is consistent with the broader refactoring effort.
src/components/ui/select/SelectGroup.vue (1)
4-4: LGTM!The import path refactoring is consistent across all reviewed files and follows proper import ordering conventions.
Based on learnings, the project uses antfu/eslint-config with eslint-plugin-perfectionist for import ordering, and this change maintains those conventions.
src/components/ui/select/SelectScrollDownButton.vue (1)
4-4: LGTM! Verify alias configuration.The import path update to use the
@alias improves maintainability and consistency across the codebase.Ensure the
@alias is properly configured in bothtsconfig.jsonandvite.config.ts. Run the following script to verify the configuration:#!/bin/bash # Verify alias configuration exists echo "=== Checking tsconfig.json ===" cat tsconfig.json | jq '.compilerOptions.paths' echo -e "\n=== Checking vite.config.ts ===" rg -A 5 "resolve.*alias" vite.config.tssrc/components/ui/tabs/TabsTrigger.vue (1)
5-5: Alias import forcnlooks correctSwitching
cnto@/lib/utils/utilsis consistent with the new alias-based layout and keeps usage unchanged in the template.src/components/ui/select/SelectSeparator.vue (1)
4-4: Consistentcnalias importImporting
cnfrom@/lib/utils/utilsaligns this component with the shared utils alias; no behavior change.src/components/ui/select/SelectScrollUpButton.vue (1)
4-4:cnimport refactor is aligned with alias strategyThe new
@/lib/utils/utilspath is consistent with the utilities alias and keeps the SelectScrollUpButton behavior intact.src/components/ui/badge/Badge.vue (1)
4-4: Badge now uses shared utils aliasUsing
@/lib/utils/utilsforcnstandardizes badge styling utilities with the rest of the UI components.docs/.vitepress/config.mts (1)
282-285: Docs Vite@alias matches project-level patternAdding
@pointing to../../srcmirrors the main Vite config style and enables alias imports inside docs without changing runtime behavior. Just ensure this stays in sync with the root Vite/TS path mappings if the folder structure changes.src/components/Playground/OAPlayground.vue (1)
2-4: OperationData imports correctly migrated to alias pathImporting both
OperationDataandOPERATION_DATA_KEYfrom@/lib/operation/operationDatakeeps the injection/typing intact and aligns with the alias-based structure and prior lint expectations for alias vs parent imports. Based on learnings, this should satisfy the import-order rules.src/components/ui/input/Input.vue (1)
3-3: Input component now uses sharedcnaliasThe
cnimport from@/lib/utils/utilsis consistent with the refactor across UI components and keeps the input classes logic unchanged.src/components/ui/select/SelectTrigger.vue (1)
4-4: SelectTriggercnrefactor is consistent and non-breakingSwitching to
@/lib/utils/utilsforcnstandardizes the utils import and leaves the SelectTrigger API and styling behavior unchanged.src/components/ui/label/Label.vue (1)
4-4: LGTM!The import path refactor to use the alias is clean and correct.
vite.config.ts (1)
9-13: LGTM!The alias configuration correctly enables
@as a path alias to thesrcdirectory, supporting the import refactoring throughout the codebase.src/components/ui/tabs/TabsContent.vue (1)
4-4: LGTM!The import path refactor to use the alias is consistent with the broader refactoring effort.
src/components/ui/tooltip/TooltipContent.vue (1)
4-4: LGTM!The import path refactor is correct and consistent with other UI component updates in this PR.
src/components/Sample/OACodeSamples.vue (1)
2-3: LGTM!The import path refactor for operation-related types and constants is clean and correct.
src/components/Request/OARequestBody.vue (1)
2-4: LGTM!The import path refactor is consistent with other operation-related components in this PR.
src/components/Playground/OAPlaygroundParameters.vue (1)
2-10: LGTM!The comprehensive refactor of multiple imports to alias-based paths is correct and well-organized.
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
docs/.vitepress/config.mts(3 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-08-17T13:10:49.905Z
Learnt from: enzonotario
Repo: enzonotario/vitepress-openapi PR: 0
File: :0-0
Timestamp: 2025-08-17T13:10:49.905Z
Learning: The vitepress-openapi project is considering a major architectural change from runtime Vue component rendering to build-time markdown generation with template slots, similar to vitepress-jsdoc approach, to improve performance, SEO, and leverage VitePress's built-in markdown renderer.
Applied to files:
docs/.vitepress/config.mts
📚 Learning: 2025-08-17T13:10:49.905Z
Learnt from: enzonotario
Repo: enzonotario/vitepress-openapi PR: 0
File: :0-0
Timestamp: 2025-08-17T13:10:49.905Z
Learning: GitHub issue #297 was created to track the proposal for implementing build-time markdown generation with template slots for OpenAPI operations in the vitepress-openapi project, which would improve performance, SEO, and integration with VitePress's built-in markdown renderer.
Applied to files:
docs/.vitepress/config.mts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Run E2E Tests Locally
- GitHub Check: Run E2E Tests on Vercel Preview
🔇 Additional comments (3)
docs/.vitepress/config.mts (3)
2-2: LGTM! Path resolution setup is correct.The ES module equivalent of
__dirnameis properly established usingfileURLToPathanddirname, androotDiris correctly resolved to the repository root. This is the standard and recommended approach for path resolution in ES modules.Also applies to: 15-17
292-298: LGTM! Conditional alias logic is sound.The retention of environment-specific aliases for development is appropriate. Development environments use source files directly via these aliases, while production uses the built package. The new '@', '@docs', and '@public' aliases being unconditional is intentional and allows them to be available in all environments.
289-298: The '@' alias is correctly configured and resolves properly across the codebase.The alias configuration in config.mts (lines 289-298) properly maps '@' to the src directory using
resolve(rootDir, 'src'), whererootDiris correctly resolved to the repository root. The path.resolve() method creates a full, absolute path, which is required for Vite alias resolution.The configuration is verified to be working correctly:
- TypeScript is configured with matching path mappings in tsconfig.json ("@/": ["src/"]) to enable proper IDE support
- Numerous Vue components throughout src/components/ actively use '@/' imports (e.g.,
@/lib/utils/utils,@/lib/spec/createOpenApiSpec,@/lib/operation/operationData, etc.)- All referenced directories exist: src/lib/utils, src/lib/spec, src/lib/parser, src/lib/operation, and other subdirectories
- All imported files are resolvable within the src directory structure
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
e2e/local/dev/docs/.vitepress/config.ts(2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-07-09T18:29:13.510Z
Learnt from: alexchexes
Repo: enzonotario/vitepress-openapi PR: 258
File: test/composables/useSidebar.multipleTags.test.ts:63-232
Timestamp: 2025-07-09T18:29:13.510Z
Learning: In vitepress-openapi tests, the sidebarItemTemplate path parameter should use the OpenAPI spec path (e.g., `/api/cats`) not the operationId (e.g., `/findCat`). Tests may pass incorrectly if they provide explicit titles that mask wrong path parameters, since the template function uses `title || path` for display text.
Applied to files:
e2e/local/dev/docs/.vitepress/config.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Run E2E Tests Locally
- GitHub Check: Run E2E Tests on Vercel Preview
🔇 Additional comments (1)
e2e/local/dev/docs/.vitepress/config.ts (1)
8-10: LGTM! Correct ESM path resolution pattern.The implementation correctly computes the project root directory using standard ESM patterns for path resolution. The 6-level traversal accurately reflects the file's location in the directory structure.
09895b2 to
ccb5648
Compare
Description
Related issues/external references
Types of changes