Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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/nice-foxes-cheat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"ensapi": patch
---

Comment thread
sevenzing marked this conversation as resolved.
Add example responses to autogenerated openapi doc
5 changes: 5 additions & 0 deletions .changeset/smooth-foxes-boil.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@ensnode/ensnode-sdk": patch
---

Moved examples to separate file to reuse them in ensapi, such that we can test examples in ensnode-sdk with schema parsing and show them in openapi docs
29 changes: 21 additions & 8 deletions apps/ensapi/src/handlers/api/explore/name-tokens-api.routes.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import { createRoute, z } from "@hono/zod-openapi";

import {
ErrorResponseSchema,
errorResponseBadRequestExample,
errorResponseInternalServerErrorExample,
makeErrorResponseSchema,
makeNameTokensResponseErrorNameTokensNotIndexedSchema,
makeNameTokensResponseErrorSchema,
makeNameTokensResponseSchema,
makeNodeSchema,
nameTokensNotIndexedExample,
nameTokensResponseOkExample,
nameTokensServiceUnavailableExample,
} from "@ensnode/ensnode-sdk/internal";

import { params } from "@/lib/handlers/params.schema";
Expand Down Expand Up @@ -42,31 +49,37 @@ export const getNameTokensRoute = createRoute({
description: "Name tokens known",
content: {
"application/json": {
schema: makeNameTokensResponseSchema("Name Tokens Response", true),
schema: makeNameTokensResponseSchema("Name Tokens Response", true).openapi({
example: nameTokensResponseOkExample,
}),
},
},
},
400: {
description: "Invalid input",
content: {
"application/json": {
schema: ErrorResponseSchema,
schema: makeErrorResponseSchema().openapi({ example: errorResponseBadRequestExample }),
},
},
},
404: {
description: "Name tokens not indexed",
content: {
"application/json": {
schema: makeNameTokensResponseSchema("Name Tokens Response", true),
schema: makeNameTokensResponseErrorNameTokensNotIndexedSchema().openapi({
example: nameTokensNotIndexedExample,
}),
},
},
},
500: {
description: "Internal server error",
content: {
"application/json": {
schema: ErrorResponseSchema,
schema: makeErrorResponseSchema().openapi({
example: errorResponseInternalServerErrorExample,
}),
},
},
},
Expand All @@ -75,11 +88,11 @@ export const getNameTokensRoute = createRoute({
"Service unavailable - Name Tokens API prerequisites not met (indexing status not ready or required plugins not activated)",
content: {
"application/json": {
schema: makeNameTokensResponseSchema("Name Tokens Response", true),
schema: makeNameTokensResponseErrorSchema().openapi({
example: nameTokensServiceUnavailableExample,
}),
},
},
},
},
});

export const routes = [getNameTokensRoute];
12 changes: 7 additions & 5 deletions apps/ensapi/src/handlers/api/explore/name-tokens-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import {
type NameTokensRequest,
NameTokensResponseCodes,
NameTokensResponseErrorCodes,
type NameTokensResponseErrorIndexingStatusUnsupported,
type NameTokensResponseErrorNameTokensNotIndexed,
type NameTokensResponseOk,
type PluginName,
serializeNameTokensResponse,
} from "@ensnode/ensnode-sdk";
Expand Down Expand Up @@ -59,7 +61,7 @@ app.openapi(getNameTokensRoute, async (c) => {
details:
"Indexing status has not yet reached the required state to enable the Name Tokens API.",
},
}),
} satisfies NameTokensResponseErrorIndexingStatusUnsupported),
503,
);
}
Expand All @@ -78,7 +80,7 @@ app.openapi(getNameTokensRoute, async (c) => {
makeNameTokensNotIndexedResponse(
`The 'name' param must not be ENS Root, no tokens exist for it.`,
),
),
) satisfies NameTokensResponseErrorNameTokensNotIndexed,
404,
);
}
Expand All @@ -95,7 +97,7 @@ app.openapi(getNameTokensRoute, async (c) => {
makeNameTokensNotIndexedResponse(
`This ENSNode instance has not been configured to index tokens for the requested name: '${name}'`,
),
),
) satisfies NameTokensResponseErrorNameTokensNotIndexed,
404,
);
}
Expand Down Expand Up @@ -125,7 +127,7 @@ app.openapi(getNameTokensRoute, async (c) => {
makeNameTokensNotIndexedResponse(
`No Name Tokens were indexed by this ENSNode instance for the requested ${errorMessageSubject}.`,
),
),
) satisfies NameTokensResponseErrorNameTokensNotIndexed,
404,
);
}
Expand All @@ -134,7 +136,7 @@ app.openapi(getNameTokensRoute, async (c) => {
serializeNameTokensResponse({
responseCode: NameTokensResponseCodes.Ok,
registeredNameTokens,
}),
} satisfies NameTokensResponseOk),
200,
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,15 @@ import {
RegistrarActionsOrders,
} from "@ensnode/ensnode-sdk";
import {
errorResponseBadRequestExample,
makeErrorResponseSchema,
makeNodeSchema,
makeNormalizedAddressSchema,
makePositiveIntegerSchema,
makeRegistrarActionsResponseErrorSchema,
makeSerializedRegistrarActionsResponseOkSchema,
makeUnixTimestampSchema,
registrarActionsResponseOkExample,
} from "@ensnode/ensnode-sdk/internal";

import { params } from "@/lib/handlers/params.schema";
Expand Down Expand Up @@ -59,12 +64,14 @@ export const registrarActionsQuerySchema = z
.pipe(z.coerce.number())
.pipe(makeUnixTimestampSchema("beginTimestamp"))
.optional()
.openapi({ type: "integer" })
.describe("Filter actions at or after this Unix timestamp"),

endTimestamp: params.queryParam
.pipe(z.coerce.number())
.pipe(makeUnixTimestampSchema("endTimestamp"))
.optional()
.openapi({ type: "integer" })
.describe("Filter actions at or before this Unix timestamp"),
})
.refine(
Expand Down Expand Up @@ -96,12 +103,29 @@ export const getRegistrarActionsRoute = createRoute({
responses: {
200: {
description: "Successfully retrieved registrar actions",
content: {
"application/json": {
schema: makeSerializedRegistrarActionsResponseOkSchema().openapi({
example: registrarActionsResponseOkExample,
Comment thread
sevenzing marked this conversation as resolved.
}),
},
},
Comment thread
sevenzing marked this conversation as resolved.
},
400: {
description: "Invalid query",
content: {
"application/json": {
schema: makeErrorResponseSchema().openapi({ example: errorResponseBadRequestExample }),
},
},
},
500: {
description: "Internal server error",
content: {
"application/json": {
schema: makeRegistrarActionsResponseErrorSchema("Registrar Actions Error Response"),
},
},
},
Comment thread
sevenzing marked this conversation as resolved.
},
});
Expand All @@ -125,14 +149,33 @@ export const getRegistrarActionsByParentNodeRoute = createRoute({
responses: {
200: {
description: "Successfully retrieved registrar actions",
content: {
"application/json": {
schema: makeSerializedRegistrarActionsResponseOkSchema(
"Registrar Actions By ParentNode Response",
).openapi({
example: registrarActionsResponseOkExample,
}),
},
},
},
400: {
description: "Invalid input",
content: {
"application/json": {
schema: makeErrorResponseSchema().openapi({ example: errorResponseBadRequestExample }),
},
},
},
500: {
description: "Internal server error",
content: {
"application/json": {
schema: makeRegistrarActionsResponseErrorSchema(
"Registrar Actions By ParentNode Error Response",
),
},
},
},
},
});

export const routes = [getRegistrarActionsRoute, getRegistrarActionsByParentNodeRoute];
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ app.openapi(getRegistrarActionsRoute, async (c) => {
pageContext,
accurateAsOf,
} satisfies RegistrarActionsResponseOk),
200,
);
} catch (error) {
const errorMessage = error instanceof Error ? error.message : "Unknown error";
Expand Down Expand Up @@ -196,6 +197,7 @@ app.openapi(getRegistrarActionsByParentNodeRoute, async (c) => {
pageContext,
accurateAsOf,
} satisfies RegistrarActionsResponseOk),
200,
);
} catch (error) {
const errorMessage = error instanceof Error ? error.message : "Unknown error";
Expand Down
2 changes: 0 additions & 2 deletions apps/ensapi/src/handlers/api/meta/realtime-api.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,3 @@ export const realtimeGetMeta = createRoute({
},
},
});

export const routes = [realtimeGetMeta];
2 changes: 0 additions & 2 deletions apps/ensapi/src/handlers/api/meta/status-api.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,3 @@ export const getIndexingStatusRoute = createRoute({
},
},
});

export const routes = [getIndexingStatusRoute];
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import { createRoute, z } from "@hono/zod-openapi";

import {
errorResponseInternalServerErrorExample,
errorResponseInvalidAddressExample,
errorResponseInvalidNameExample,
makeErrorResponseSchema,
makeResolvePrimaryNameResponseSchema,
makeResolvePrimaryNamesResponseSchema,
makeResolveRecordsResponseSchema,
resolvePrimaryNameResponseExample,
resolvePrimaryNamesResponseExample,
resolveRecordsResponseExample,
} from "@ensnode/ensnode-sdk/internal";

import { params } from "@/lib/handlers/params.schema";
Expand All @@ -28,7 +35,27 @@ export const resolveRecordsRoute = createRoute({
description: "Successfully resolved records",
content: {
"application/json": {
schema: makeResolveRecordsResponseSchema(),
schema: makeResolveRecordsResponseSchema().openapi({
example: resolveRecordsResponseExample,
}),
},
},
},
400: {
description: "Invalid name or query parameters",
content: {
"application/json": {
schema: makeErrorResponseSchema().openapi({ example: errorResponseInvalidNameExample }),
},
},
},
500: {
description: "Internal server error",
content: {
"application/json": {
schema: makeErrorResponseSchema().openapi({
example: errorResponseInternalServerErrorExample,
}),
},
},
},
Expand Down Expand Up @@ -57,7 +84,29 @@ export const resolvePrimaryNameRoute = createRoute({
description: "Successfully resolved name",
content: {
"application/json": {
schema: makeResolvePrimaryNameResponseSchema(),
schema: makeResolvePrimaryNameResponseSchema().openapi({
example: resolvePrimaryNameResponseExample,
}),
},
},
},
400: {
description: "Invalid address or chain ID",
content: {
"application/json": {
schema: makeErrorResponseSchema().openapi({
example: errorResponseInvalidAddressExample,
}),
},
},
},
500: {
description: "Internal server error",
content: {
"application/json": {
schema: makeErrorResponseSchema().openapi({
example: errorResponseInternalServerErrorExample,
}),
},
},
},
Expand Down Expand Up @@ -86,11 +135,31 @@ export const resolvePrimaryNamesRoute = createRoute({
description: "Successfully resolved records",
content: {
"application/json": {
schema: makeResolvePrimaryNamesResponseSchema(),
schema: makeResolvePrimaryNamesResponseSchema().openapi({
example: resolvePrimaryNamesResponseExample,
}),
},
},
},
400: {
description: "Invalid address or chain IDs",
content: {
"application/json": {
schema: makeErrorResponseSchema().openapi({
example: errorResponseInvalidAddressExample,
}),
},
},
},
500: {
description: "Internal server error",
content: {
"application/json": {
schema: makeErrorResponseSchema().openapi({
example: errorResponseInternalServerErrorExample,
}),
},
},
},
},
});

export const routes = [resolveRecordsRoute, resolvePrimaryNameRoute, resolvePrimaryNamesRoute];
Loading
Loading