feat(apps/ensadmin): add interactive REST API playground to ENSAdmin#1951
feat(apps/ensadmin): add interactive REST API playground to ENSAdmin#1951
Conversation
…t`) powered by Scalar, loading the OpenAPI spec from the connected ENSApi instance. Introduced `@ensnode/scalar-react` wrapper package.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
2 Skipped Deployments
|
🦋 Changeset detectedLatest commit: ba62521 The changes in this PR will be included in the next version bump. This PR includes changesets to release 24 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 45 minutes and 57 seconds. ⌛ 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. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughAdds an interactive REST API Reference at /api/rest in ENSAdmin using a new Changes
Sequence Diagram(s)sequenceDiagram
participant Browser
participant ENSAdmin as ENSAdmin (client page)
participant ENSApi as ENSApi (server /openapi.json)
participant Scalar as Scalar UI (ApiReferenceReact)
Browser->>ENSAdmin: navigate to /api/rest
ENSAdmin->>ENSAdmin: useValidatedSelectedConnection(), useOpenApiUrl()
ENSAdmin->>ENSApi: GET /openapi.json (computed URL)
ENSApi-->>ENSAdmin: OpenAPI JSON URL / spec
ENSAdmin->>Scalar: render ScalarApiReference with url + serverUrl
Scalar-->>Browser: interactive API playground UI
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Adds an interactive REST API playground to ENSAdmin by introducing an ENSNode-themed wrapper around Scalar’s React API Reference component and wiring it into the ENSAdmin navigation and route structure.
Changes:
- Introduces new workspace package
@ensnode/scalar-reactwrapping@scalar/api-reference-reactwith ENSNode styling defaults. - Adds
/api/restpage (plus breadcrumb/actions parallel routes + loading state) to render Scalar against the connected ENSApi’s/openapi.json. - Exposes the new page via the ENSAdmin sidebar and gates it behind a new
restApifeature flag.
Reviewed changes
Copilot reviewed 13 out of 14 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-lock.yaml | Adds Scalar + transitive dependencies required for the REST API reference UI. |
| packages/scalar-react/package.json | Defines new @ensnode/scalar-react package metadata and dependencies. |
| packages/scalar-react/tsup.config.ts | Adds build config for the new wrapper package. |
| packages/scalar-react/tsconfig.json | Adds TypeScript config for the new wrapper package. |
| packages/scalar-react/src/index.ts | Exposes the wrapper component entrypoint. |
| packages/scalar-react/src/api-reference.tsx | Implements the Scalar wrapper + ENSNode-themed defaults. |
| apps/ensadmin/package.json | Adds dependency on @ensnode/scalar-react. |
| apps/ensadmin/src/hooks/active/use-ensadmin-features.tsx | Adds restApi feature status used for gating the new page. |
| apps/ensadmin/src/components/app-sidebar.tsx | Adds “REST API Reference” nav item under APIs. |
| apps/ensadmin/src/app/api/rest/page.tsx | New REST API reference page loading /openapi.json from the selected connection. |
| apps/ensadmin/src/app/api/rest/loading.tsx | Loading state for the new route. |
| apps/ensadmin/src/app/@breadcrumbs/(apis)/api/rest/page.tsx | Breadcrumb slot content for the new page. |
| apps/ensadmin/src/app/@actions/api/rest/page.tsx | Actions slot (copy OpenAPI URL) for the new page. |
| .changeset/tangy-pants-camp.md | Changeset entry describing the feature addition. |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| '@scalar/use-tooltip@1.0.6': | ||
| resolution: {integrity: sha512-f0gadIaUnILfi9qYAk7g+fNTsvLGXnam8oOUTxovavC1ocYuGTEykdz3g2MTqnAqRS8OkAB64h9mHf0FBfg6mg==} | ||
| engines: {node: '>=18'} | ||
| deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. | ||
|
|
There was a problem hiding this comment.
The lockfile adds @scalar/use-tooltip@1.0.6 which is marked as deprecated. Since this is now part of the dependency graph pulled in by @scalar/api-reference-react, it would be good to either (1) upgrade Scalar to a version that no longer depends on the deprecated package, or (2) document/track this deprecation so it doesn’t get missed during dependency health/security reviews.
| { | ||
| "name": "@ensnode/scalar-react", | ||
| "version": "0.0.0", | ||
| "type": "module", | ||
| "description": "Scalar API Reference React component for ENSNode", | ||
| "license": "MIT", | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "git+https://github.com/namehash/ensnode.git", | ||
| "directory": "packages/scalar-react" | ||
| }, | ||
| "homepage": "https://github.com/namehash/ensnode/tree/main/packages/scalar-react", | ||
| "files": [ | ||
| "dist" | ||
| ], | ||
| "exports": { | ||
| ".": "./src/index.ts" | ||
| }, | ||
| "publishConfig": { | ||
| "exports": { | ||
| ".": { | ||
| "default": "./dist/index.js", | ||
| "types": "./dist/index.d.ts" | ||
| } | ||
| }, | ||
| "main": "./dist/index.js", | ||
| "module": "./dist/index.mjs", | ||
| "types": "./dist/index.d.ts" | ||
| }, |
There was a problem hiding this comment.
@ensnode/scalar-react is introduced with version 0.0.0 and no publishConfig.access. If this package is intended to be published like the other @ensnode/* packages, it should be versioned via changesets (typically aligning with the repo’s fixed-version set) and include publishConfig.access: "public" to match existing packages’ publishing metadata.
|
One remaining UX issue I need to resolve with this is when you scroll it has a sticky container so the header moves. I'll try modify the class for the docs/playground area so it sits within the normal scrollable |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/ensadmin/src/app/`@actions/api/rest/page.tsx:
- Around line 10-14: Extract the duplicated URL derivation into a shared hook
named useOpenApiUrl that calls useValidatedSelectedConnection and returns
useMemo(() => new URL("/openapi.json", selectedConnection).toString(),
[selectedConnection]); colocate the new hook with the REST feature (e.g.,
hooks/active) and then replace the inline useMemo in both
useValidatedSelectedConnection call sites (the components referencing the exact
expression in `@actions/api/rest/page.tsx` and api/rest/page.tsx) to instead call
useOpenApiUrl().
In `@packages/scalar-react/package.json`:
- Line 31: Replace the deprecated "prepublish" script in package.json with an
explicit "build" script and add a "prepack" script that invokes it: remove the
"prepublish": "tsup" entry, add "build": "tsup" and add "prepack": "npm run
build" so packaging/publishing reliably runs the build step; ensure you update
any CI/publish docs that referenced "prepublish".
- Around line 20-25: The exports object in package.json currently lists the
"default" condition before "types", which causes Node's condition-resolution to
pick "default" and skip the "types" entry; update the exports "." entry so the
"types" key appears before "default" (i.e., reorder the keys under "exports" ->
"." to place "types" first) to ensure TypeScript moduleResolution
(bundler/node16/nodenext) can find the declared types.
In `@packages/scalar-react/src/api-reference.tsx`:
- Around line 27-47: Replace the typeof window check in ScalarApiReference with
the project's useHydrated hook: import useHydrated from "@/hooks/use-hydrated",
call const hydrated = useHydrated() inside the ScalarApiReference function and
return null when !hydrated; keep the configuration object and the
ApiReferenceReact render (configuration and ApiReferenceReact identifiers remain
unchanged) so the component renders consistently between server and client and
avoids hydration mismatch.
🪄 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: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 5957238b-9a9d-4b2a-bc0e-e4025d0a63ef
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (13)
.changeset/tangy-pants-camp.mdapps/ensadmin/package.jsonapps/ensadmin/src/app/@actions/api/rest/page.tsxapps/ensadmin/src/app/@breadcrumbs/(apis)/api/rest/page.tsxapps/ensadmin/src/app/api/rest/loading.tsxapps/ensadmin/src/app/api/rest/page.tsxapps/ensadmin/src/components/app-sidebar.tsxapps/ensadmin/src/hooks/active/use-ensadmin-features.tsxpackages/scalar-react/package.jsonpackages/scalar-react/src/api-reference.tsxpackages/scalar-react/src/index.tspackages/scalar-react/tsconfig.jsonpackages/scalar-react/tsup.config.ts
| "exports": { | ||
| ".": { | ||
| "default": "./dist/index.js", | ||
| "types": "./dist/index.d.ts" | ||
| } | ||
| }, |
There was a problem hiding this comment.
Put "types" before "default" in the exports conditions.
Node resolves export conditions in object-key order, and once a matching condition is hit, later ones are ignored. With "default" listed before "types", TypeScript's moduleResolution: "bundler"/"node16"/"nodenext" will match default first and never use the declared types entry, degrading type resolution for consumers. Conventionally types must always come first.
🔧 Proposed fix
"publishConfig": {
"exports": {
".": {
- "default": "./dist/index.js",
- "types": "./dist/index.d.ts"
+ "types": "./dist/index.d.ts",
+ "default": "./dist/index.js"
}
},🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/scalar-react/package.json` around lines 20 - 25, The exports object
in package.json currently lists the "default" condition before "types", which
causes Node's condition-resolution to pick "default" and skip the "types" entry;
update the exports "." entry so the "types" key appears before "default" (i.e.,
reorder the keys under "exports" -> "." to place "types" first) to ensure
TypeScript moduleResolution (bundler/node16/nodenext) can find the declared
types.
| "types": "./dist/index.d.ts" | ||
| }, | ||
| "scripts": { | ||
| "prepublish": "tsup", |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
prepublish is deprecated by npm; use build + prepack.
npm has deprecated the prepublish lifecycle script (it runs inconsistently across npm install/npm publish and is a known footgun). Replace with an explicit build script, and wire it via prepack (which reliably runs before packing/publishing and doesn't run on npm install).
🔧 Proposed fix
"scripts": {
- "prepublish": "tsup",
+ "build": "tsup",
+ "prepack": "tsup",
"dev": "tsup --watch",📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "prepublish": "tsup", | |
| "build": "tsup", | |
| "prepack": "tsup", |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/scalar-react/package.json` at line 31, Replace the deprecated
"prepublish" script in package.json with an explicit "build" script and add a
"prepack" script that invokes it: remove the "prepublish": "tsup" entry, add
"build": "tsup" and add "prepack": "npm run build" so packaging/publishing
reliably runs the build step; ensure you update any CI/publish docs that
referenced "prepublish".
| export function ScalarApiReference({ url }: ScalarApiReferenceProps) { | ||
| if (typeof window === "undefined") return null; | ||
|
|
||
| const configuration: NonNullable<ReferenceProps["configuration"]> = { | ||
| url, | ||
| theme: "none", | ||
| hideDownloadButton: true, | ||
| hiddenClients: true, | ||
| defaultOpenAllTags: true, | ||
| forceDarkModeState: "light", | ||
| hideDarkModeToggle: true, | ||
| withDefaultFonts: false, | ||
| hideClientButton: true, | ||
| customCss: CUSTOM_CSS, | ||
| }; | ||
|
|
||
| return ( | ||
| <div className="flex-1"> | ||
| <ApiReferenceReact configuration={configuration} /> | ||
| </div> | ||
| ); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Find the scalar-react API reference file and check its content
fd -t f "api-reference.tsx" packages/scalar-react/src/
# Check if the file exists and contains the use client directive
find . -path "*/packages/scalar-react/src/api-reference.tsx" -exec cat -n {} \;Repository: namehash/ensnode
Length of output: 1866
🏁 Script executed:
# Search for where ScalarApiReference is used
rg "ScalarApiReference" --type tsx --type ts -B 2 -A 2Repository: namehash/ensnode
Length of output: 87
🏁 Script executed:
# Check the calling site at apps/ensadmin
fd -t f "page.tsx" apps/ensadmin/src/app/api/rest/Repository: namehash/ensnode
Length of output: 99
🏁 Script executed:
# Look for use client directives in the scalar-react package
rg "use client" packages/scalar-react/Repository: namehash/ensnode
Length of output: 117
🏁 Script executed:
# Check the actual usage at the calling page
cat -n apps/ensadmin/src/app/api/rest/page.tsxRepository: namehash/ensnode
Length of output: 954
🏁 Script executed:
# Check if there are any other components in the scalar-react package
ls -la packages/scalar-react/src/Repository: namehash/ensnode
Length of output: 295
🏁 Script executed:
# Search for other typeof window checks in the codebase for comparison
rg "typeof window" --type ts --type tsx -B 2 -A 2Repository: namehash/ensnode
Length of output: 87
🏁 Script executed:
# Search for typeof window patterns without specifying type
rg "typeof window" -B 2 -A 2Repository: namehash/ensnode
Length of output: 1697
🏁 Script executed:
# Check if there are any dynamic imports with ssr: false in the codebase
rg "ssr.*false" -B 2 -A 2Repository: namehash/ensnode
Length of output: 42
🏁 Script executed:
# Check the structure of `@scalar/api-reference-react` to understand if it requires a mount guard
rg "@scalar/api-reference-react" -B 1 -A 1Repository: namehash/ensnode
Length of output: 1303
🏁 Script executed:
# Check the GraphiQLEditor component to see how it handles the same pattern
cat -n apps/ensadmin/src/components/graphiql-editor/components.tsx | head -30Repository: namehash/ensnode
Length of output: 1247
🏁 Script executed:
# Check if there are any hydration-related errors or issues reported in the repo
rg "hydration" -iRepository: namehash/ensnode
Length of output: 550
🏁 Script executed:
# Look for React version and Next.js configuration
cat apps/ensadmin/package.json | grep -A 5 '"react"' && cat apps/ensadmin/package.json | grep -A 5 '"next"'Repository: namehash/ensnode
Length of output: 371
🏁 Script executed:
# Check if there's a use-hydrated hook being used anywhere
cat -n apps/ensadmin/src/hooks/use-hydrated.tsRepository: namehash/ensnode
Length of output: 554
🏁 Script executed:
# Search for usage of the use-hydrated hook to understand the hydration pattern
rg "use-hydrated\|useHydrated" -B 2 -A 2Repository: namehash/ensnode
Length of output: 42
🏁 Script executed:
# Check Next.js configuration for SSR settings
cat apps/ensadmin/next.config.tsRepository: namehash/ensnode
Length of output: 307
🏁 Script executed:
# Verify SPA configuration - check if there are any dynamic routes that might trigger SSR
rg "\[.*\]" apps/ensadmin/src/app/ --type ts --type tsx | head -20Repository: namehash/ensnode
Length of output: 87
🏁 Script executed:
# Check if there are any API routes or server components that might indicate SSR
fd "route.ts" apps/ensadmin/src/app/Repository: namehash/ensnode
Length of output: 98
🏁 Script executed:
# Confirm the build output by checking if there are any other hydration-related patterns
rg "suppressHydrationWarning" apps/ensadmin/Repository: namehash/ensnode
Length of output: 42
Use the project's useHydrated() hook to avoid hydration mismatch, not typeof window === "undefined".
The typeof window === "undefined" check causes a hydration mismatch: the component renders null during the static build phase but renders the full tree on the client. Import useHydrated from @/hooks/use-hydrated and wrap the component rendering:
import { useHydrated } from "@ensnode/scalar-react";
// or locally if not exported: import { useHydrated } from "@/hooks/use-hydrated";
export function ScalarApiReference({ url }: ScalarApiReferenceProps) {
const hydrated = useHydrated();
if (!hydrated) return null;
const configuration: NonNullable<ReferenceProps["configuration"]> = {This aligns with the project's existing hydration pattern (e.g., useIsomorphicEffect from rooks) and avoids the build-time/client-time render mismatch.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export function ScalarApiReference({ url }: ScalarApiReferenceProps) { | |
| if (typeof window === "undefined") return null; | |
| const configuration: NonNullable<ReferenceProps["configuration"]> = { | |
| url, | |
| theme: "none", | |
| hideDownloadButton: true, | |
| hiddenClients: true, | |
| defaultOpenAllTags: true, | |
| forceDarkModeState: "light", | |
| hideDarkModeToggle: true, | |
| withDefaultFonts: false, | |
| hideClientButton: true, | |
| customCss: CUSTOM_CSS, | |
| }; | |
| return ( | |
| <div className="flex-1"> | |
| <ApiReferenceReact configuration={configuration} /> | |
| </div> | |
| ); | |
| import { useHydrated } from "@/hooks/use-hydrated"; | |
| export function ScalarApiReference({ url }: ScalarApiReferenceProps) { | |
| const hydrated = useHydrated(); | |
| if (!hydrated) return null; | |
| const configuration: NonNullable<ReferenceProps["configuration"]> = { | |
| url, | |
| theme: "none", | |
| hideDownloadButton: true, | |
| hiddenClients: true, | |
| defaultOpenAllTags: true, | |
| forceDarkModeState: "light", | |
| hideDarkModeToggle: true, | |
| withDefaultFonts: false, | |
| hideClientButton: true, | |
| customCss: CUSTOM_CSS, | |
| }; | |
| return ( | |
| <div className="flex-1"> | |
| <ApiReferenceReact configuration={configuration} /> | |
| </div> | |
| ); | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/scalar-react/src/api-reference.tsx` around lines 27 - 47, Replace
the typeof window check in ScalarApiReference with the project's useHydrated
hook: import useHydrated from "@/hooks/use-hydrated", call const hydrated =
useHydrated() inside the ScalarApiReference function and return null when
!hydrated; keep the configuration object and the ApiReferenceReact render
(configuration and ApiReferenceReact identifiers remain unchanged) so the
component renders consistently between server and client and avoids hydration
mismatch.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 15 changed files in this pull request and generated 2 comments.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| export function ScalarApiReference({ url, serverUrl }: ScalarApiReferenceProps) { | ||
| if (typeof window === "undefined") return null; | ||
|
|
There was a problem hiding this comment.
ScalarApiReference returns null during the server render (typeof window === "undefined") but renders the full Scalar UI on the first client render. In Next.js client components this can cause a hydration mismatch (server markup is empty, client markup is not). Consider gating on a mounted state set in useEffect (or equivalent hydration guard) so the first client render matches the server output, then render Scalar after mount.
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
packages/scalar-react/src/api-reference.tsx (1)
53-70:⚠️ Potential issue | 🟠 MajorUse a mount guard instead of
typeof windowfor Scalar.Line 54 can hydrate as
nullon the server but as the full Scalar tree on the first browser render. Keep the first client render identical, then mount Scalar after hydration.🐛 Proposed fix
+import { useEffect, useState } from "react"; import { ApiReferenceReact, type ReferenceProps } from "@scalar/api-reference-react"; import "@scalar/api-reference-react/style.css"; @@ export function ScalarApiReference({ url, serverUrl }: ScalarApiReferenceProps) { - if (typeof window === "undefined") return null; + const [isMounted, setIsMounted] = useState(false); + + useEffect(() => { + setIsMounted(true); + }, []); + + if (!isMounted) return null; const configuration: NonNullable<ReferenceProps["configuration"]> = {Scalar’s React integration docs describe the wrapper as client-side and call out SSR/SSG caveats: https://scalar.com/products/api-references/integrations/react
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/scalar-react/src/api-reference.tsx` around lines 53 - 70, The current server/client guard in ScalarApiReference uses typeof window and can cause a hydration mismatch; replace it with a mount guard inside the component: add a mounted state (e.g., useState(false)) and set it to true in useEffect(() => setMounted(true), []), return null while !mounted, and only render ApiReferenceReact after mounted; keep the existing configuration object (configuration) and all props (url, serverUrl) unchanged and ensure React plus useState/useEffect are imported so the first client render matches the server render.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/ensadmin/src/app/`@actions/api/rest/page.tsx:
- Around line 12-20: The URL span can grow indefinitely in the flex row; update
the container div (the element rendering the URL and CopyButton) to include
"min-w-0" and make the URL span (the element rendering {url}) use truncation
classes (e.g., add "truncate" and keep "overflow-hidden" if needed) so long
OpenAPI/local URLs are ellipsized instead of pushing the CopyButton; optionally
add a title attribute to the span to surface the full URL on hover.
In `@packages/scalar-react/src/api-reference.tsx`:
- Around line 16-31: The CUSTOM_CSS currently hardcodes a 4rem header and forces
an internal scroll (see .references-layout, .references-rendered,
.references-navigation-list) which makes Scalar own page layout; remove the
calc(100svh - 4rem) usage and the forced overflow-y:auto and instead let the
component inherit height from its parent (use height: 100% / max-height: 100% or
unset those rules) so the ENSAdmin route container can control header height and
global scrolling; update the CUSTOM_CSS constant to drop those hard-coded
size/scroll rules and rely on parent-provided sizing, and document in the
component README that the parent must provide the available height or scrolling
container.
---
Duplicate comments:
In `@packages/scalar-react/src/api-reference.tsx`:
- Around line 53-70: The current server/client guard in ScalarApiReference uses
typeof window and can cause a hydration mismatch; replace it with a mount guard
inside the component: add a mounted state (e.g., useState(false)) and set it to
true in useEffect(() => setMounted(true), []), return null while !mounted, and
only render ApiReferenceReact after mounted; keep the existing configuration
object (configuration) and all props (url, serverUrl) unchanged and ensure React
plus useState/useEffect are imported so the first client render matches the
server render.
🪄 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: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: d1b33048-79c9-4daa-9278-28b31235351c
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (6)
apps/ensadmin/src/app/@actions/api/rest/page.tsxapps/ensadmin/src/app/api/rest/page.tsxapps/ensadmin/src/components/header.tsxapps/ensadmin/src/hooks/active/use-openapi-url.tspackages/scalar-react/package.jsonpackages/scalar-react/src/api-reference.tsx
|
@copilot resolve the merge conflicts in this pull request |
Greptile SummaryThis PR adds an interactive REST API playground at Confidence Score: 5/5Safe to merge — no logic or data-integrity issues found. All findings are P2 (style/best-practice) suggestions. The feature gating, URL construction, routing slots, and global header change are all correctly implemented and follow existing patterns. packages/scalar-react/src/api-reference.tsx — minor: Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[User visits /api/rest] --> B[RequireENSAdminFeature\nfeature=restApi]
B --> C{configQuery status}
C -- pending --> D[Show loading spinner]
C -- error --> E[Show error card]
C -- success --> F[restApi = supported]
F --> G[RestApiPage]
G --> H[useOpenApiUrl\nnew URL /openapi.json, connection]
G --> I[useValidatedSelectedConnection]
H --> J[ScalarApiReference\nurl, serverUrl]
I --> J
J --> K[ApiReferenceReact\nVue-under-the-hood\nfetches OpenAPI spec]
K --> L[Interactive REST playground]
Reviews (1): Last reviewed commit: "apply code suggestions" | Re-trigger Greptile |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 15 changed files in this pull request and generated 1 comment.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@copilot resolve the merge conflicts in this pull request |
Lite PR
Summary
@ensnode/scalar-reactwrapper package around@scalar/api-reference-reactwith ENSNode-themed styling defaults/api/restpage in ENSAdmin that renders an interactvie REST API playground powered by the connected ENSApi instance's/openapi.jsonWhy
Testing
pnpm buildsucceeds with/api/restin the route tableapi/graphqlerrors remain)/api/rest?connection=https://api.alpha.ensnode.iowith HTTP 200Notes for Reviewer (Optional)
The
restApifeature is gated simply on config loading successfully (no plugin check), since/openapi.jsonis always served by any ENSApi instance (same as other pages)@scalar/api-reference-reactis a Vue-under-the-hood wrapper (it's client-side only, which is fine since the page requires an active connection anyway)The links in the nav are still static, and not dynamic.
Pre-Review Checklist (Blocking)