Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
237de51
poc
notrab Jan 19, 2026
9045cc6
dummy preview page
notrab Jan 19, 2026
cc5f236
fix new line
notrab Jan 19, 2026
ddc8bf6
fmt new spec
notrab Jan 19, 2026
9da0a88
update readme for docs site
notrab Jan 20, 2026
3ae1447
Apply suggestions from code review
notrab Jan 20, 2026
61b4438
move generator file
notrab Jan 20, 2026
06c49c5
remove local dev env arg
notrab Jan 20, 2026
66e4b1e
update ci check
notrab Jan 20, 2026
30dff75
lint
notrab Jan 20, 2026
67ff063
fix frozen lock
notrab Jan 20, 2026
c75e78f
lint spec
notrab Jan 20, 2026
aaf1a73
update readme
notrab Jan 20, 2026
80f06e0
add colored diff
notrab Jan 21, 2026
630309f
test diff
notrab Jan 21, 2026
ab5927b
lint
notrab Jan 21, 2026
fa0119d
revert
notrab Jan 21, 2026
bdca6ea
readme
notrab Jan 21, 2026
fac4754
deploy switch
notrab Jan 21, 2026
1973ef6
run the openapi-check
notrab Jan 23, 2026
911bc3c
add changeset
notrab Jan 23, 2026
f1dd11d
continue-on-error
notrab Jan 23, 2026
b1cea1a
update readme structure
notrab Jan 23, 2026
323e565
Merge branch 'main' into openapi-spec-generator
notrab Jan 23, 2026
98bece8
update spec
notrab Jan 23, 2026
f493d51
announce mintlify errors in slack
notrab Jan 25, 2026
3945545
retry on transient errors
notrab Jan 25, 2026
a16f9eb
rename environment variable
notrab Jan 25, 2026
7ad6563
update wording
notrab Jan 25, 2026
91dfe3c
make right config types
notrab Jan 25, 2026
600294a
remove mintlify comment
notrab Jan 25, 2026
21b72af
update readme variable secret comment
notrab Jan 25, 2026
bba27af
add node types
notrab Jan 25, 2026
692a119
update preview text
notrab Jan 25, 2026
b640ca9
rename types
notrab Jan 25, 2026
16a641f
update mintlify deploy failed comment
notrab Jan 25, 2026
87c5180
replace mock databaseurl for openapi generation
notrab Jan 25, 2026
ac91cff
check server readiness
notrab Jan 25, 2026
4e11eb8
update openapi.json
notrab Jan 25, 2026
8ac20f5
update docs
notrab Jan 25, 2026
83ae0ba
apply coderabbit suggestion
notrab Jan 25, 2026
f7d7031
Merge branch 'main' into openapi-spec-generator
notrab Jan 28, 2026
0d1d1d5
revert to simpler times
notrab Jan 28, 2026
367c991
tidy
notrab Jan 28, 2026
ffb49ae
EnsApiConfigInput
notrab Jan 28, 2026
1a94122
add openapi mock config
notrab Jan 28, 2026
5d7e8ee
apply coderabbit suggestions
notrab Feb 1, 2026
e59fb6f
Merge branch 'main' into openapi-spec-generator
notrab Feb 1, 2026
4037d9f
update openapi.json
notrab Feb 1, 2026
9d1bf2a
update openapi.json
notrab Feb 1, 2026
5cade8d
update readme
notrab Feb 1, 2026
5965d3f
timeout check
notrab Feb 1, 2026
f287094
print parse error
notrab Feb 1, 2026
42a19d0
add docstring for openapi-generator
notrab Feb 1, 2026
731b4fe
Update docs/docs.ensnode.io/scripts/generate-openapi.ts
notrab Feb 1, 2026
690b155
Update .github/workflows/test_ci.yml
notrab Feb 1, 2026
09bf81d
Update .github/workflows/deploy_switch_ensnode_environment.yml
notrab Feb 1, 2026
546d0f4
Update apps/ensapi/src/config/openapi-mock-config.ts
notrab Feb 1, 2026
e82231a
apply suggestions from coderabbit and vercel
notrab Feb 1, 2026
a5ed508
exit trap
notrab Feb 2, 2026
ab00660
apply vercel ai code suggestions
notrab Feb 2, 2026
57261ce
Merge branch 'main' into openapi-spec-generator
notrab Feb 2, 2026
6bd4d09
fix lock
notrab Feb 2, 2026
419468c
log invalid value
notrab Feb 2, 2026
e14ef97
Update .changeset/gentle-clouds-dance.md
notrab Feb 3, 2026
32ea6a4
Update docs/docs.ensnode.io/README.md
notrab Feb 3, 2026
76cab69
Update docs/docs.ensnode.io/README.md
notrab Feb 3, 2026
3d37753
Apply suggestions from code review
notrab Feb 3, 2026
41c95b2
mintlify status check
notrab Feb 3, 2026
c69b37a
apply code suggestions
notrab Feb 3, 2026
cf0fc54
add script for generate openapi spec
notrab Feb 9, 2026
5d563ea
update slack msg
notrab Feb 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/bright-waves-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@docs/mintlify": patch
---

Introduce API documentation for ENSApi that's generated automatically from the OpenAPI spec
5 changes: 5 additions & 0 deletions .changeset/gentle-clouds-dance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"ensapi": patch
---

Add `OPENAPI_GENERATE_MODE` environment variable to enable starting ENSApi with a mock config exclusively for OpenAPI spec generation without external dependencies
122 changes: 122 additions & 0 deletions .github/scripts/generate_openapi_spec.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
#!/bin/bash

# Generate OpenAPI spec from ENSApi
# This script can be used both locally and in CI
#
# Usage:
# ./generate_openapi_spec.sh # Generate spec (default)
# ./generate_openapi_spec.sh --check # Generate and verify against committed version
#
# Environment variables:
# ENSAPI_PORT - Port for ENSApi (default: 4334)
# STARTUP_TIMEOUT - Seconds to wait for server startup (default: 30)
# SKIP_VALIDATION - Set to "true" to skip Mintlify validation (default: false)

set -e
Comment on lines +1 to +15
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Add set -o pipefail for safer pipe error handling.

With set -e but no pipefail, failures in the left-hand side of pipes (e.g., if curl fails but output is piped through sed/tail later in other scripts) can be silently swallowed. Since this script uses set -e, adding pipefail ensures consistent fail-fast behavior.

Proposed fix
-set -e
+set -euo pipefail
📝 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.

Suggested change
#!/bin/bash
# Generate OpenAPI spec from ENSApi
# This script can be used both locally and in CI
#
# Usage:
# ./generate_openapi_spec.sh # Generate spec (default)
# ./generate_openapi_spec.sh --check # Generate and verify against committed version
#
# Environment variables:
# ENSAPI_PORT - Port for ENSApi (default: 4334)
# STARTUP_TIMEOUT - Seconds to wait for server startup (default: 30)
# SKIP_VALIDATION - Set to "true" to skip Mintlify validation (default: false)
set -e
#!/bin/bash
# Generate OpenAPI spec from ENSApi
# This script can be used both locally and in CI
#
# Usage:
# ./generate_openapi_spec.sh # Generate spec (default)
# ./generate_openapi_spec.sh --check # Generate and verify against committed version
#
# Environment variables:
# ENSAPI_PORT - Port for ENSApi (default: 4334)
# STARTUP_TIMEOUT - Seconds to wait for server startup (default: 30)
# SKIP_VALIDATION - Set to "true" to skip Mintlify validation (default: false)
set -euo pipefail
🤖 Prompt for AI Agents
In @.github/scripts/generate_openapi_spec.sh around lines 1 - 15, The script
uses "set -e" but doesn't enable pipefail, so failures in piped commands can be
masked; update the generate_openapi_spec.sh startup options by adding "set -o
pipefail" (alongside the existing "set -e") near the top of the script so that
piped command failures cause the script to fail fast and Surface errors during
OpenAPI generation.


# Configuration
ENSAPI_PORT="${ENSAPI_PORT:-4334}"
STARTUP_TIMEOUT="${STARTUP_TIMEOUT:-30}"
SKIP_VALIDATION="${SKIP_VALIDATION:-false}"
ENSAPI_URL="http://localhost:${ENSAPI_PORT}"

# Parse arguments
CHECK_MODE=false
for arg in "$@"; do
case $arg in
--check)
CHECK_MODE=true
shift
;;
esac
done
Comment on lines +23 to +32
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

shift inside a for arg in "$@" loop is misleading.

The shift on line 29 modifies positional parameters but doesn't affect the for loop's iteration (which snapshots "$@" at the start). It's harmless but misleading—readers may think it's skipping the next argument. Consider removing it or switching to a while loop if you need to consume arguments.

Proposed cleanup
 # Parse arguments
 CHECK_MODE=false
 for arg in "$@"; do
   case $arg in
     --check)
       CHECK_MODE=true
-      shift
       ;;
   esac
 done
📝 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.

Suggested change
# Parse arguments
CHECK_MODE=false
for arg in "$@"; do
case $arg in
--check)
CHECK_MODE=true
shift
;;
esac
done
# Parse arguments
CHECK_MODE=false
for arg in "$@"; do
case $arg in
--check)
CHECK_MODE=true
;;
esac
done
🤖 Prompt for AI Agents
In @.github/scripts/generate_openapi_spec.sh around lines 23 - 32, The for-loop
iterating over "$@" uses shift (inside the block handling --check) which is
misleading because the for-loop snapshot isn't affected; remove the shift or
convert the loop to a proper while/shift pattern. Specifically, either delete
the shift line inside the case that sets CHECK_MODE=true (leaving the for arg in
"$@" intact and no positional consumption), or replace the "for arg in \"$@\";
do ... done" with a "while [ $# -gt 0 ]; do arg=\"$1\"; case $arg in ... esac;
shift; done" pattern so the shift actually consumes arguments; update references
to CHECK_MODE and the --check case accordingly.


# Detect repository root
if [ -n "$GITHUB_WORKSPACE" ]; then
REPO_ROOT="$GITHUB_WORKSPACE"
else
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
REPO_ROOT="$( cd "$SCRIPT_DIR/../.." && pwd )"
fi

OPENAPI_JSON="$REPO_ROOT/docs/docs.ensnode.io/openapi.json"
ENSAPI_PID=""

# Cleanup function
cleanup() {
if [ -n "$ENSAPI_PID" ]; then
echo "Stopping ENSApi (PID: $ENSAPI_PID)..."
kill "$ENSAPI_PID" 2>/dev/null || true
wait "$ENSAPI_PID" 2>/dev/null || true
fi
}

trap cleanup EXIT INT TERM

echo "Starting ENSApi in OpenAPI generate mode..."

# Start ENSApi in background
cd "$REPO_ROOT"
OPENAPI_GENERATE_MODE=true pnpm --filter ensapi start &
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ENSAPI_PORT is documented as configurable, but the script never passes it through to the ENSApi process (via PORT). In OPENAPI_GENERATE_MODE, ENSApi will start on its default port, so setting ENSAPI_PORT will cause the readiness curl and generator to target the wrong port. Pass PORT=$ENSAPI_PORT (or set ENSAPI_PORT to also export PORT) when starting ENSApi.

Suggested change
OPENAPI_GENERATE_MODE=true pnpm --filter ensapi start &
PORT="$ENSAPI_PORT" OPENAPI_GENERATE_MODE=true pnpm --filter ensapi start &

Copilot uses AI. Check for mistakes.
ENSAPI_PID=$!

# Wait for server to be ready
echo "Waiting for ENSApi to start (timeout: ${STARTUP_TIMEOUT}s)..."
SERVER_READY=false
for i in $(seq 1 "$STARTUP_TIMEOUT"); do
if curl --fail --silent --max-time 5 "${ENSAPI_URL}/openapi.json" > /dev/null 2>&1; then
echo "ENSApi is ready and responding"
SERVER_READY=true
break
fi

# Check if the process is still running
if ! kill -0 "$ENSAPI_PID" 2>/dev/null; then
echo "Error: ENSApi process exited unexpectedly"
exit 1
fi

echo "Waiting for ENSApi to start... ($i/$STARTUP_TIMEOUT)"
sleep 1
done

if [ "$SERVER_READY" != "true" ]; then
echo "Error: ENSApi failed to start within ${STARTUP_TIMEOUT} seconds"
exit 1
fi

# Generate the OpenAPI spec
echo "Generating OpenAPI spec..."
pnpm --filter @docs/mintlify openapi:generate "$ENSAPI_URL"

# Stop the server now that we have the spec
echo "Stopping ENSApi..."
kill "$ENSAPI_PID" 2>/dev/null || true
wait "$ENSAPI_PID" 2>/dev/null || true
ENSAPI_PID=""

# Check mode: verify spec matches committed version
if [ "$CHECK_MODE" = "true" ]; then
echo "Verifying OpenAPI spec matches committed version..."
if git diff --quiet "$OPENAPI_JSON"; then
echo "OpenAPI spec is in sync with codebase"
else
echo "Error: OpenAPI spec is out of sync"
echo ""
echo "The committed openapi.json differs from what ENSApi generates:"
echo ""
git diff --color "$OPENAPI_JSON"
echo ""
echo "To fix, run: ./.github/scripts/generate_openapi_spec.sh"
echo "Then commit the updated openapi.json."
exit 1
fi
fi

# Validate with Mintlify (unless skipped)
if [ "$SKIP_VALIDATION" != "true" ]; then
echo "Validating OpenAPI spec with Mintlify..."
pnpm dlx mintlify openapi-check "$OPENAPI_JSON"
fi

echo "Done!"
105 changes: 105 additions & 0 deletions .github/workflows/deploy_switch_ensnode_environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,111 @@ jobs:
chmod +x ./.github/scripts/promote_ensadmin.sh
./.github/scripts/promote_ensadmin.sh

- name: Trigger Mintlify Docs Rebuild
id: mintlify_rebuild
# Non-blocking: failures are reported to Slack and can be manually retriggered
continue-on-error: true
env:
MINTLIFY_API_TOKEN: ${{ secrets.MINTLIFY_API_TOKEN }}
MINTLIFY_PROJECT_ID: ${{ vars.MINTLIFY_PROJECT_ID }}
run: |
# Trigger the rebuild and capture the statusId
HTTP_RESPONSE=$(curl --silent --write-out "\n%{http_code}" \
--connect-timeout 10 \
--max-time 30 \
--retry 2 \
--retry-delay 5 \
--request POST \
--url "https://api.mintlify.com/v1/project/update/${MINTLIFY_PROJECT_ID}" \
--header "Authorization: Bearer ${MINTLIFY_API_TOKEN}")

HTTP_BODY=$(echo "$HTTP_RESPONSE" | sed '$d')
HTTP_CODE=$(echo "$HTTP_RESPONSE" | tail -n1)
Comment thread
notrab marked this conversation as resolved.

if [ "$HTTP_CODE" -lt 200 ] || [ "$HTTP_CODE" -ge 300 ]; then
echo "Mintlify API returned HTTP $HTTP_CODE"
echo "Response body: $HTTP_BODY"
exit 1
fi

echo "Mintlify rebuild triggered successfully (HTTP $HTTP_CODE)"

# Extract statusId from response
STATUS_ID=$(echo "$HTTP_BODY" | jq -r '.statusId // empty')
if [ -z "$STATUS_ID" ]; then
echo "Failed to extract statusId from response"
echo "Response body: $HTTP_BODY"
exit 1
fi

echo "Status ID: $STATUS_ID"

# Poll for completion (max 5 minutes, checking every 10 seconds)
MAX_ATTEMPTS=30
ATTEMPT=0

while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do
ATTEMPT=$((ATTEMPT + 1))
echo "Checking status (attempt $ATTEMPT/$MAX_ATTEMPTS)..."

STATUS_RESPONSE=$(curl --silent --write-out "\n%{http_code}" \
--connect-timeout 10 \
--max-time 30 \
--request GET \
--url "https://api.mintlify.com/v1/project/update-status/${STATUS_ID}" \
--header "Authorization: Bearer ${MINTLIFY_API_TOKEN}")

STATUS_BODY=$(echo "$STATUS_RESPONSE" | sed '$d')
STATUS_CODE=$(echo "$STATUS_RESPONSE" | tail -n1)

if [ "$STATUS_CODE" -lt 200 ] || [ "$STATUS_CODE" -ge 300 ]; then
echo "Status check failed with HTTP $STATUS_CODE"
echo "Response: $STATUS_BODY"
sleep 10
continue
fi

STATUS=$(echo "$STATUS_BODY" | jq -r '.status // empty')
echo "Current status: $STATUS"

case "$STATUS" in
"success")
echo "Mintlify docs rebuild completed successfully"
exit 0
;;
"failure")
echo "Mintlify docs rebuild failed"
exit 1
;;
"queued"|"in_progress")
sleep 10
;;
*)
echo "Unknown status: $STATUS"
sleep 10
;;
esac
done

echo "Timeout waiting for Mintlify rebuild to complete"
exit 1

- name: Notify Mintlify Rebuild Failure
if: steps.mintlify_rebuild.outcome == 'failure'
uses: ./.github/actions/send_slack_notification
with:
slack_webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
slack_title: "Mintlify Docs Rebuild Failed"
slack_message: "Mintlify docs rebuild failed during environment switch to ${{ inputs.target }}. Check the workflow logs for details."

- name: Notify Mintlify Rebuild Success
if: steps.mintlify_rebuild.outcome == 'success'
uses: ./.github/actions/send_slack_notification
with:
slack_webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
slack_title: "Mintlify Docs Rebuilt"
slack_message: "Mintlify docs successfully rebuilt for environment switch to ${{ inputs.target }}. API Reference built from: https://api.alpha.ensnode.io/openapi.json"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@notrab I'd also like to see an additional separate Slack notification sent to notify us of successfully rebuilt Mintlify docs. This notification ideally should also include a reference to the specific URL to the OpenAPI.json that the new production Mintlify API docs were successfully built from.

Goal: Help everyone in our team build a stronger mental model for how all these pieces are working together.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated the message to include the URL to the OpenAPI spec https://api.alpha.ensnode.io/openapi.json.

Trafik handles the routing so this URL should always be the prod one.

- name: Send Slack Notification
uses: ./.github/actions/send_slack_notification
with:
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/test_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,16 @@
- uses: ./.github/actions/setup_node_environment
- run: pnpm test

openapi-sync-check:
name: "OpenAPI Spec Sync Check"
runs-on: blacksmith-4vcpu-ubuntu-2204
Comment thread
lightwalker-eth marked this conversation as resolved.
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup_node_environment
- name: Generate and verify OpenAPI spec
run: ./.github/scripts/generate_openapi_spec.sh --check

integrity-check:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium test

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
name: "Integrity Check"
runs-on: blacksmith-4vcpu-ubuntu-2204
services:
Expand Down
21 changes: 21 additions & 0 deletions apps/ensapi/.env.local.example
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,24 @@ DATABASE_URL=postgresql://dbuser:abcd1234@localhost:5432/my_database
# Note: ENS_HOLIDAY_AWARDS_START date must be before or the same as ENS_HOLIDAY_AWARDS_END
# ENS_HOLIDAY_AWARDS_START="2025-12-01T00:00:00Z"
# ENS_HOLIDAY_AWARDS_END="2025-12-31T23:59:59Z"

# OpenAPI Generate Mode
# Optional. When set to "true", ENSApi starts with a minimal mock configuration,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feedback:

  1. Please document specific references to each of the other environment variables that are ignored when this is set to true. Or, alternatively, document something like: causes all other environment variable configurations to be ignored except for X, Y, and Z as it might be easier to say what isn't ignored, than to make a big list of everything that is ignored.
  2. I believe it's important that when this environment variable is set, ENSApi should refuse to serve any route other than the route for the openapi.json file. I understand we can achieve this as follows:
    1. Introduce some new "global" middleware, such as can be seen here.
    2. This new "global" middleware can have some simple logic:
      1. If this environment variable has been set and the route is not the route for the openapi.json file: return a HTTP 503 service unavailable error with some little message about how ENSApi was started in this OpenAPI generate mode and therefore only route X is available.
      2. Else: pass through the request.
    3. Update the docs for this environment variable to note how when it is set, all APIs return HTTP 503 service unavailable with the exception of route X to get the openapi.json file.
    4. The logic for how the "config" object in ENSApi is built should be refined. More specifically: EnsApiConfig / EnsApiConfigSchema as defined in apps/ensapi/src/config/config.schema.ts should be updated to include a new boolean field named something like inOpenApiGenerateMode. This should be implemented such that the value will be false unless the related environment variable is explicitly set to "true". The logic in the new "global" middleware should then read from this variable to decide its behaviour.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lightwalker-eth great idea about the middleware. Makes things a bit simpler and more isolated, thanks!

# bypassing the need for a real database, ENSIndexer, or RPC connections.
# This is useful for generating the OpenAPI spec without external dependencies.
#
# When enabled:
# - All routes return HTTP 503 Service Unavailable EXCEPT for /openapi.json
# - The following environment variables are IGNORED (mock values are used instead):
# - DATABASE_URL
# - ENSINDEXER_URL
# - THEGRAPH_API_KEY
# - All RPC configuration variables (ALCHEMY_API_KEY, QUICKNODE_API_KEY,
# QUICKNODE_ENDPOINT_NAME, DRPC_API_KEY, RPC_URL_*)
# - ENS_HOLIDAY_AWARDS_START
# - ENS_HOLIDAY_AWARDS_END
# - The following environment variables are still respected:
# - PORT
# - LOG_LEVEL
#
# OPENAPI_GENERATE_MODE=true
28 changes: 28 additions & 0 deletions apps/ensapi/src/config/config.schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import logger from "@/lib/logger";
vi.mock("@/lib/logger", () => ({
default: {
error: vi.fn(),
info: vi.fn(),
warn: vi.fn(),
},
}));

Expand Down Expand Up @@ -58,6 +60,28 @@ describe("buildConfigFromEnvironment", () => {
mockFetch.mockReset();
});

it("returns mock config without fetching when OPENAPI_GENERATE_MODE is enabled", async () => {
const result = await buildConfigFromEnvironment({
OPENAPI_GENERATE_MODE: "true",
PORT: "5000",
});

expect(mockFetch).not.toHaveBeenCalled();
expect(result.port).toBe(5000);
expect(result.namespace).toBe("mainnet");
});

it("logs warning when OPENAPI_GENERATE_MODE has invalid value", async () => {
mockFetch.mockResolvedValueOnce({
ok: true,
json: () => Promise.resolve(serializeENSIndexerPublicConfig(ENSINDEXER_PUBLIC_CONFIG)),
});

await buildConfigFromEnvironment({ ...BASE_ENV, OPENAPI_GENERATE_MODE: "false" });

expect(logger.warn).toHaveBeenCalled();
});
Comment on lines +74 to +83
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider asserting the warning message content.

The test confirms logger.warn was called but doesn't verify the message. Asserting on the message string (or at least a substring) would guard against regressions where the warning is triggered by a different code path.

Suggested improvement
-    expect(logger.warn).toHaveBeenCalled();
+    expect(logger.warn).toHaveBeenCalledWith(
+      expect.stringContaining("OPENAPI_GENERATE_MODE is set to 'false'"),
+    );
📝 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.

Suggested change
it("logs warning when OPENAPI_GENERATE_MODE has invalid value", async () => {
mockFetch.mockResolvedValueOnce({
ok: true,
json: () => Promise.resolve(serializeENSIndexerPublicConfig(ENSINDEXER_PUBLIC_CONFIG)),
});
await buildConfigFromEnvironment({ ...BASE_ENV, OPENAPI_GENERATE_MODE: "false" });
expect(logger.warn).toHaveBeenCalled();
});
it("logs warning when OPENAPI_GENERATE_MODE has invalid value", async () => {
mockFetch.mockResolvedValueOnce({
ok: true,
json: () => Promise.resolve(serializeENSIndexerPublicConfig(ENSINDEXER_PUBLIC_CONFIG)),
});
await buildConfigFromEnvironment({ ...BASE_ENV, OPENAPI_GENERATE_MODE: "false" });
expect(logger.warn).toHaveBeenCalledWith(
expect.stringContaining("OPENAPI_GENERATE_MODE is set to 'false'"),
);
});
🤖 Prompt for AI Agents
In `@apps/ensapi/src/config/config.schema.test.ts` around lines 74 - 83, Update
the test that calls buildConfigFromEnvironment with OPENAPI_GENERATE_MODE:
"false" to also assert the warning message content so we guard the warning's
origin; replace or augment expect(logger.warn).toHaveBeenCalled() with an
assertion like
expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining("OPENAPI_GENERATE_MODE")
or the specific substring your code logs) or use
toHaveBeenCalledWith(expect.stringMatching(/invalid.*OPENAPI_GENERATE_MODE/i))
to verify the message includes the expected text from the warning emitted by
buildConfigFromEnvironment.


it("returns a valid config object using environment variables", async () => {
mockFetch.mockResolvedValueOnce({
ok: true,
Expand All @@ -84,6 +108,7 @@ describe("buildConfigFromEnvironment", () => {
]),
ensHolidayAwardsStart: ENS_HOLIDAY_AWARDS_START_DATE,
ensHolidayAwardsEnd: ENS_HOLIDAY_AWARDS_END_DATE,
inOpenApiGenerateMode: false,
});
});

Expand Down Expand Up @@ -166,6 +191,7 @@ describe("buildEnsApiPublicConfig", () => {
]),
ensHolidayAwardsStart: ENS_HOLIDAY_AWARDS_START_DATE,
ensHolidayAwardsEnd: ENS_HOLIDAY_AWARDS_END_DATE,
inOpenApiGenerateMode: false,
};

const result = buildEnsApiPublicConfig(mockConfig);
Expand All @@ -191,6 +217,7 @@ describe("buildEnsApiPublicConfig", () => {
rpcConfigs: new Map(),
ensHolidayAwardsStart: ENS_HOLIDAY_AWARDS_START_DATE,
ensHolidayAwardsEnd: ENS_HOLIDAY_AWARDS_END_DATE,
inOpenApiGenerateMode: false,
};

const result = buildEnsApiPublicConfig(mockConfig);
Expand Down Expand Up @@ -227,6 +254,7 @@ describe("buildEnsApiPublicConfig", () => {
ensHolidayAwardsStart: ENS_HOLIDAY_AWARDS_START_DATE,
ensHolidayAwardsEnd: ENS_HOLIDAY_AWARDS_END_DATE,
theGraphApiKey: "secret-api-key",
inOpenApiGenerateMode: false,
};

const result = buildEnsApiPublicConfig(mockConfig);
Expand Down
Loading
Loading