UNPKG

ponder-enrich-gql-docs-middleware

Version:

A middleware for Ponder that allows devs to enrich their GraphQL docs with docstrings

97 lines (96 loc) 4.3 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createDocumentationMiddleware = createDocumentationMiddleware; const graphql_1 = require("graphql"); const introspection_1 = require("./introspection"); /** * Creates a middleware function that enhances GraphQL introspection queries with documentation. * * This middleware intercepts GraphQL introspection queries and adds documentation strings * to the schema before returning it to the client. It's particularly useful for adding * detailed documentation to your GraphQL API that will show up in tools like GraphiQL. * * @param docs - Documentation strings to add to the schema * @param options - Configuration options for the middleware * @returns A middleware function to use in your GraphQL server * * @example * ```typescript * import { createDocumentationMiddleware } from '@your-lib/graphql-docs'; * import { ponder } from 'ponder:registry'; * * const docs = { * User: "Represents a user in the system", * "User.balance": "The user's balance" * }; * * const middleware = createDocumentationMiddleware(docs, { debug: true }); * ponder.use('/graphql', middleware); * ``` */ function createDocumentationMiddleware(docs, options = {}) { const { debug = false } = options; const log = debug ? (...args) => console.log("[GraphQL Docs]:", ...args) : () => { }; /** * The actual middleware function that processes GraphQL requests. * * @param context - The middleware context containing request and response * @param next - Function to call the next middleware */ return function documentationMiddleware(context, next) { return __awaiter(this, void 0, void 0, function* () { var _a; const body = yield context.req.raw.clone().text(); let parsed; try { parsed = JSON.parse(body); } catch (err) { log("Failed to parse request body:", err); return next(); } if (!(parsed === null || parsed === void 0 ? void 0 : parsed.query)) { log("No query found in request"); return next(); } try { const document = (0, graphql_1.parse)(parsed.query); const isIntrospection = document.definitions.some((def) => { if (def.kind === "OperationDefinition") { return def.selectionSet.selections.some((sel) => sel.kind === "Field" && sel.name.value.startsWith("__")); } return false; }); if (!isIntrospection) { log("Not an introspection query"); return next(); } yield next(); const response = yield context.res.clone().text(); const json = JSON.parse(response); if ((_a = json === null || json === void 0 ? void 0 : json.data) === null || _a === void 0 ? void 0 : _a.__schema) { log("Enhancing schema with documentation"); json.data = (0, introspection_1.addDocStringsToIntrospection)(json.data, docs); context.res = new Response(JSON.stringify(json), { headers: { "Content-Type": "application/json" }, }); } } catch (err) { log("Error processing GraphQL request:", err); throw err; } }); }; }