Conversation
🦋 Changeset detectedLatest commit: 298f87f The changes in this PR will be included in the next version bump. This PR includes changesets to release 19 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 |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThis PR bumps the ensnode-sdk package version and introduces exported validation functions for the Indexing Status data model. It adds serialized Zod schemas and refactors deserialization pipelines to use an intermediate Unvalidated type pattern, enabling consumer-side validation use cases. Changes
Sequence DiagramsequenceDiagram
actor Consumer
participant SerializedData as Serialized Data
participant Schema1 as Serialized Schema
participant Builder as Unvalidated Builder
participant Schema2 as Final Validation Schema
participant ValidatedData as Validated Data
Consumer->>SerializedData: Input serialized JSON/object
SerializedData->>Schema1: Apply serialized schema<br/>(e.g., makeSerializedCrossChainIndexingStatusSnapshotSchema)
Schema1->>Builder: Transform via builder function<br/>(e.g., buildUnvalidatedCrossChainIndexingStatusSnapshot)
Builder->>Schema2: Pipe through final schema<br/>(e.g., makeCrossChainIndexingStatusSnapshotSchema)
Schema2->>ValidatedData: Parse and return validated result
ValidatedData-->>Consumer: Validated, typed data<br/>or throw Error on failure
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 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 |
.../ensnode-sdk/src/ensindexer/indexing-status/zod-schema/omnichain-indexing-status-snapshot.ts
Dismissed
Show dismissed
Hide dismissed
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In
`@packages/ensnode-sdk/src/ensindexer/indexing-status/zod-schema/cross-chain-indexing-status-snapshot.ts`:
- Around line 108-116: The schema factory
makeSerializedCrossChainIndexingStatusSnapshotSchema uses
z.enum(CrossChainIndexingStrategyIds) but CrossChainIndexingStrategyIds is a
const object (not a string tuple), so replace z.enum(...) with
z.nativeEnum(CrossChainIndexingStrategyIds) to correctly validate that value;
update the import/usage in makeSerializedCrossChainIndexingStatusSnapshotSchema
so the strategy property uses z.nativeEnum(CrossChainIndexingStrategyIds) while
leaving the other fields (slowestChainIndexingCursor, snapshotTime,
omnichainSnapshot) unchanged.
In
`@packages/ensnode-sdk/src/ensindexer/indexing-status/zod-schema/omnichain-indexing-status-snapshot.ts`:
- Around line 284-301: The Backfill schema created by
makeOmnichainIndexingStatusSnapshotBackfillSchema only includes the Queued and
Backfill branch in the discriminatedUnion for "chainStatus", causing valid
Backfill snapshots with Completed chains to fail; update the discriminatedUnion
call inside makeOmnichainIndexingStatusSnapshotBackfillSchema to include the
Completed variant (the same schema used for serialized variants, e.g.,
makeChainIndexingStatusSnapshotCompletedSchema) so the union matches the type
ChainIndexingStatusSnapshotForOmnichainIndexingStatusSnapshotBackfill and the
runtime check
checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill.
...nsnode-sdk/src/ensindexer/indexing-status/zod-schema/cross-chain-indexing-status-snapshot.ts
Show resolved
Hide resolved
.../ensnode-sdk/src/ensindexer/indexing-status/zod-schema/omnichain-indexing-status-snapshot.ts
Show resolved
Hide resolved
There was a problem hiding this comment.
Pull request overview
This PR extends the ENSNode SDK’s ENSIndexer indexing-status module refactor by adding a standalone validation layer and updating deserialization to validate via “serialized → unvalidated → validated” pipelines. This enables consumers to validate already-shaped indexing-status objects without going through full serialization.
Changes:
- Added
validate*helpers for indexing-status models (CrossChain/Omnichain/Realtime) that validateUnvalidated<T>via Zod schemas. - Introduced “serialized” Zod schemas and updated deserializers to transform serialized payloads into unvalidated business models before piping into validation schemas.
- Adjusted duration parsing and updated ENSApi’s
/amirealtimequery parsing to explicitly coerce numbers.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 14 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/ensnode-sdk/src/shared/zod-schemas.ts | Changes makeDurationSchema parsing behavior (coercion removed). |
| packages/ensnode-sdk/src/ensindexer/indexing-status/zod-schema/realtime-indexing-status-projection.ts | Switches to .object, adds serialized schema maker. |
| packages/ensnode-sdk/src/ensindexer/indexing-status/zod-schema/omnichain-indexing-status-snapshot.ts | Reworks omnichain snapshot schemas (Map-based) and adds serialized variants. |
| packages/ensnode-sdk/src/ensindexer/indexing-status/zod-schema/cross-chain-indexing-status-snapshot.ts | Removes debug logging, adds serialized schema maker. |
| packages/ensnode-sdk/src/ensindexer/indexing-status/validate/realtime-indexing-status-projection.ts | New validation helper for realtime projection. |
| packages/ensnode-sdk/src/ensindexer/indexing-status/validate/omnichain-indexing-status-snapshot.ts | New validation helper for omnichain snapshot. |
| packages/ensnode-sdk/src/ensindexer/indexing-status/validate/cross-chain-indexing-status-snapshot.ts | New validation helper for cross-chain snapshot. |
| packages/ensnode-sdk/src/ensindexer/indexing-status/deserialize/realtime-indexing-status-projection.ts | Adds unvalidated builder + pipes serialized schema into validated schema. |
| packages/ensnode-sdk/src/ensindexer/indexing-status/deserialize/omnichain-indexing-status-snapshot.ts | Adds unvalidated builder (record → Map) + serialized→validated pipeline. |
| packages/ensnode-sdk/src/ensindexer/indexing-status/deserialize/cross-chain-indexing-status-snapshot.ts | Adds unvalidated builder + serialized→validated pipeline. |
| packages/ensnode-sdk/src/api/indexing-status/zod-schemas.ts | Adds serialized response schemas and imports serialized realtime schema. |
| packages/ensnode-sdk/src/api/indexing-status/deserialize.ts | Deserializes via serialized schema → unvalidated builder → validated schema. |
| apps/ensapi/src/handlers/amirealtime-api.ts | Updates query param parsing to explicitly coerce to number before duration validation. |
| .changeset/ten-cups-grab.md | Adds changeset for new validate* functions. |
Comments suppressed due to low confidence (1)
packages/ensnode-sdk/src/shared/zod-schemas.ts:94
makeDurationSchemano longer coerces input to a number. This breaks callers that pass durations as strings/unknown (e.g.deserializeDuration(record.totalIncrementalDuration)in ENSApi DB code, wheretotalIncrementalDurationis a string). Consider restoringz.coerce.number()here (or adding a separatemakeCoercedDurationSchema) so both deserialization and validation paths continue to accept serialized numeric strings.
z
.number({
error: `${valueLabel} must be a number.`,
})
.pipe(makeNonNegativeIntegerSchema(valueLabel));
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
.../ensnode-sdk/src/ensindexer/indexing-status/zod-schema/omnichain-indexing-status-snapshot.ts
Show resolved
Hide resolved
.../ensnode-sdk/src/ensindexer/indexing-status/zod-schema/omnichain-indexing-status-snapshot.ts
Show resolved
Hide resolved
.../ensnode-sdk/src/ensindexer/indexing-status/zod-schema/omnichain-indexing-status-snapshot.ts
Show resolved
Hide resolved
.../ensnode-sdk/src/ensindexer/indexing-status/zod-schema/omnichain-indexing-status-snapshot.ts
Show resolved
Hide resolved
.../ensnode-sdk/src/ensindexer/indexing-status/zod-schema/omnichain-indexing-status-snapshot.ts
Show resolved
Hide resolved
.../ensnode-sdk/src/ensindexer/indexing-status/zod-schema/omnichain-indexing-status-snapshot.ts
Show resolved
Hide resolved
.../ensnode-sdk/src/ensindexer/indexing-status/zod-schema/omnichain-indexing-status-snapshot.ts
Show resolved
Hide resolved
08d9a24 to
35b5a36
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In @.changeset/ten-cups-grab.md:
- Line 5: The changeset note uses the awkward phrase "consumers side"; update
the wording to "consumer side" (or "consumers' side" if you prefer possessive)
so the sentence reads: "These functions enable new use cases on the consumer
side." Locate the sentence mentioning "consumers side" in the .changeset note
and replace it accordingly.
In `@packages/ensnode-sdk/src/api/indexing-status/zod-schemas.ts`:
- Around line 13-16: Change the runtime import of
SerializedIndexingStatusResponse and SerializedIndexingStatusResponseOk to a
type-only import since they are only used for JSDoc links; specifically replace
the current import that brings those symbols into runtime with a type import
referencing SerializedIndexingStatusResponse and
SerializedIndexingStatusResponseOk from serialized-response so they are removed
from the emitted bundle while keeping the JSDoc `@link` references intact.
In
`@packages/ensnode-sdk/src/ensindexer/indexing-status/deserialize/realtime-indexing-status-projection.ts`:
- Around line 35-37: The pipeline currently uses
.transform(buildUnvalidatedRealtimeIndexingStatusProjection) on the schema
produced by makeSerializedRealtimeIndexingStatusProjectionSchema(valueLabel) but
transform runs after parsing; replace that call with
.preprocess(buildUnvalidatedRealtimeIndexingStatusProjection) so preprocessing
occurs before validation and the resulting value matches the expected input for
makeRealtimeIndexingStatusProjectionSchema(valueLabel); update the chain to use
.preprocess(...) .pipe(makeRealtimeIndexingStatusProjectionSchema(valueLabel))
and keep existing coercion logic in makeDurationSchema unchanged.
...nsnode-sdk/src/ensindexer/indexing-status/deserialize/realtime-indexing-status-projection.ts
Show resolved
Hide resolved
...nsnode-sdk/src/ensindexer/indexing-status/deserialize/realtime-indexing-status-projection.ts
Show resolved
Hide resolved
Define business-layer-oriented schema for each `OmnichainIndexingStatusSnapshot` variant, including more precise definition for `chains` schema. Also, using similar approach, create zod-schemas for `SerializedOmnichainIndexingStatusSnapshot`.
Compose serialization-layer schema and business-layer schema to enable precise deserialization protocol.
Validation-layer uses just business-level schema and does not rely on serialization-layer schema at all.
Create independent schemas for each layer, business and serialization
Compose serialization-layer schema and business-layer schema to enable precise deserialization protocol.
Validation-layer uses just business-level schema and does not rely on serialization-layer schema at all.
Create independent schemas for each layer, business and serialization
Compose serialization-layer schema and business-layer schema to enable precise deserialization protocol.
Validation-layer uses just business-level schema and does not rely on serialization-layer schema at all.
Create independent schemas for each layer, business and serialization
35b5a36 to
ea86060
Compare
… data model. These functions enable new use cases on consumers side.
Assume input type for maybe serialized data is `Unvalidated<Serialized*>` to highlight the target type for the input and allow partial input to fail deserialization attempt.
Remove generic definitions, that were replaced by granular definitions for each `OmnichainIndexingStatusSnapshot` variant.
9a0370b to
298f87f
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| * | ||
| * @throws Error if the provided object is not a valid {@link OmnichainIndexingStatusSnapshot}. | ||
| */ | ||
| export function validateOmnichainIndexingStatusSnapshot( |
There was a problem hiding this comment.
The new validate functions (validateOmnichainIndexingStatusSnapshot, validateCrossChainIndexingStatusSnapshot, and validateRealtimeIndexingStatusProjection) are not being exported from the indexing-status module's index.ts file. The PR description states that "Consumers using ENSNode SDK will now be able to... b. Validate an unvalidated object with shape matching business-layer data model", but without exporting these functions, they are not accessible to consumers.
The index.ts file at packages/ensnode-sdk/src/ensindexer/indexing-status/index.ts only exports from validate/chain-indexing-status-snapshot but is missing exports for the three new validate modules. You should add these exports:
- export * from "./validate/omnichain-indexing-status-snapshot";
- export * from "./validate/cross-chain-indexing-status-snapshot";
- export * from "./validate/realtime-indexing-status-projection";
| import { | ||
| SerializedOmnichainIndexingStatusSnapshot, | ||
| SerializedOmnichainIndexingStatusSnapshotBackfill, | ||
| SerializedOmnichainIndexingStatusSnapshotCompleted, | ||
| SerializedOmnichainIndexingStatusSnapshotFollowing, | ||
| SerializedOmnichainIndexingStatusSnapshotUnstarted, | ||
| } from "../serialize/omnichain-indexing-status-snapshot"; |
There was a problem hiding this comment.
The Serialized* types (SerializedOmnichainIndexingStatusSnapshot, SerializedOmnichainIndexingStatusSnapshotBackfill, SerializedOmnichainIndexingStatusSnapshotCompleted, SerializedOmnichainIndexingStatusSnapshotFollowing, SerializedOmnichainIndexingStatusSnapshotUnstarted) are only used in JSDoc comments and should be imported with the 'type' keyword to indicate they are type-only imports. Change line 23 to use 'import type {' instead of 'import {'.
| export const makeSerializedIndexingStatusResponseOkSchema = ( | ||
| valueLabel: string = "Serialized Indexing Status Response OK", | ||
| ) => | ||
| z.strictObject({ |
There was a problem hiding this comment.
The new serialized schema makers (makeSerializedIndexingStatusResponseOkSchema and makeSerializedIndexingStatusResponseSchema) use z.strictObject, which is inconsistent with the pattern used in the ensindexer indexing status schemas that were changed from z.strictObject to z.object. For consistency with the ensindexer schemas, consider using z.object instead of z.strictObject here.
| z.strictObject({ | |
| z.object({ |
| import { | ||
| SerializedIndexingStatusResponse, | ||
| SerializedIndexingStatusResponseOk, | ||
| } from "./serialized-response"; |
There was a problem hiding this comment.
Unused imports SerializedIndexingStatusResponse, SerializedIndexingStatusResponseOk.
| SerializedOmnichainIndexingStatusSnapshot, | ||
| SerializedOmnichainIndexingStatusSnapshotBackfill, | ||
| SerializedOmnichainIndexingStatusSnapshotCompleted, | ||
| SerializedOmnichainIndexingStatusSnapshotFollowing, | ||
| SerializedOmnichainIndexingStatusSnapshotUnstarted, | ||
| } from "../serialize/omnichain-indexing-status-snapshot"; | ||
| import { |
There was a problem hiding this comment.
Unused imports SerializedOmnichainIndexingStatusSnapshot, SerializedOmnichainIndexingStatusSnapshotBackfill, SerializedOmnichainIndexingStatusSnapshotCompleted, SerializedOmnichainIndexingStatusSnapshotFollowing, SerializedOmnichainIndexingStatusSnapshotUnstarted.
| SerializedOmnichainIndexingStatusSnapshot, | |
| SerializedOmnichainIndexingStatusSnapshotBackfill, | |
| SerializedOmnichainIndexingStatusSnapshotCompleted, | |
| SerializedOmnichainIndexingStatusSnapshotFollowing, | |
| SerializedOmnichainIndexingStatusSnapshotUnstarted, | |
| } from "../serialize/omnichain-indexing-status-snapshot"; | |
| import { |
Lite PR
Tip: Review docs on the ENSNode PR process
Summary
a. Deserialize a serialized representation of business-layer data model, including validation.
b. Validate an unvalidated object with shape matching business-layer data model.
Why
/api/configinto/api/indexing-status#1405, Indexing Status API will soon be different for ENSApi and ENSIndexer. Changes in this PR enable re-using ENSIndexer data model in the future ENSApi data model for Indexing Status.Testing
/api/indexing-statuson local ENSIndexer instance./api/indexing-statuson local ENSApi instance connected to ENSIndexer Alpha in the Green env.Notes for Reviewer (Optional)
OmnichainIndexingStatusSnapshotdata model #1627Pre-Review Checklist (Blocking)