Relocate the ~6k-file docs tree from the repo root into plugins/document-navigator/docs/ so the plugin is self-contained and portable. docs/superpowers/ (specs and plans) stays at the repo root. Moved via cp+rm rather than git mv because directory rename() fails with EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the identical-content files at commit time. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
7.2 KiB
@suaveplan/api-plugin-graphql - GraphQL adapter plugin for @suaveplan/api — fluent SchemaBuilder / TypeBuilder for object/input/enum/interface/union types and queries/mutations/subscriptions, ResolverComposer with composable global + per-type middleware, requireRoles / validateArgs / createQueryExecutedMiddleware built-ins, typed graphqlEvents EventBus, defineGraphQLPlugin factory producing a GraphQLPluginDefinition compatible with the definePlugin pattern. 6 GRAPHQL.* error codes, Zod-validated boundary, OTel resolvers_executed_total + resolver_duration_ms instruments.
GraphQL description + resolver-composition layer for @suaveplan/api. Server-tier — runs in Bun and Node.
The package provides a typed, builder-driven way to declare GraphQL APIs without raw SDL. It does not ship a graphql-js executor — its output is a GraphQLPluginDefinition consumed by downstream tooling (a future @suaveplan/api-plugin-graphql-executor, or any third-party executor).
Documentation tree
- error-codes — Defines the stable
GRAPHQL.*error-code registry for@suaveplan/api-plugin-graphqland theGraphQLErrorclass con…- error-codes — Defines the stable
GRAPHQL.*error-code registry for@suaveplan/api-plugin-graphqland theGraphQLErrorclass con…
- error-codes — Defines the stable
- otel — Defines the OpenTelemetry instruments emitted from
createQueryExecutedMiddleware. The middleware is the only producti…- instruments — Defines the OpenTelemetry instruments emitted from
createQueryExecutedMiddleware. The middleware is the only producti…
- instruments — Defines the OpenTelemetry instruments emitted from
- plugin — Declares
defineGraphQLPlugin(options), the factory that produces aGraphQLPluginDefinitionconsumable by the Suavep…- plugin — Declares
defineGraphQLPlugin(options), the factory that produces aGraphQLPluginDefinitionconsumable by the Suavep…
- plugin — Declares
- resolver — Implements
ResolverComposer(the fluent builder for resolver maps), the two built-in middleware factories `requireRol…- resolver — Implements
ResolverComposer(the fluent builder for resolver maps), the two built-in middleware factories `requireRol…
- resolver — Implements
- schema-builder — Declares
SchemaBuilder, the fluent builder for GraphQL schema definitions. Consumers describe types, queries, mutatio…- schema-builder — Declares
SchemaBuilder, the fluent builder for GraphQL schema definitions. Consumers describe types, queries, mutatio…
- schema-builder — Declares
- schemas — Defines
DefineGraphQLPluginOptionsSchema, the Zod schema wired at the package boundary insidedefineGraphQLPlugin.…- options — Defines
DefineGraphQLPluginOptionsSchema, the Zod schema wired at the package boundary insidedefineGraphQLPlugin.…
- options — Defines
- type-builder — Declares the
TypeBuilderclass — the inner builderSchemaBuilderhands to user-supplied callbacks when declaring ob…- type-builder — Declares the
TypeBuilderclass — the inner builderSchemaBuilderhands to user-supplied callbacks when declaring ob…
- type-builder — Declares the
What you get
defineGraphQLPlugin(options)— typed factory producing aGraphQLPluginDefinition(name + merged config + lifecycle hooks +getSchema()/getResolvers()).SchemaBuilder— fluent builder for object / input / enum / interface / union types and queries / mutations / subscriptions.TypeBuilder— chainable field declarations consumed bySchemaBuilder.ResolverComposer—use/useForType/addResolver/addResolvers/build, with right-to-left middleware composition.requireRoles(...roles)— auth-check middleware. ThrowsGraphQLError(UNAUTHENTICATED | INSUFFICIENT_ROLE).validateArgs(validator)— arg-validation middleware. ThrowsGraphQLError(VALIDATION_FAILED).graphqlEvents— typedEventBus<GraphQLEventMap>forgraphql:query:executed.createQueryExecutedMiddleware(bus?)— production observability middleware recording OTel instruments + emitting events.GRAPHQL_CODES+GraphQLError— 6 stable codes (UNAUTHENTICATED,INSUFFICIENT_ROLE,VALIDATION_FAILED,INVALID_INPUT,TYPE_NOT_FOUND,DUPLICATE_RESOLVER).- OTel —
graphql.resolvers_executed_total{outcome}counter andgraphql.resolver_duration_mshistogram.
Quick-start
import {
defineGraphQLPlugin,
ResolverComposer,
SchemaBuilder,
requireRoles,
validateArgs,
createQueryExecutedMiddleware,
graphqlEvents,
} from "@suaveplan/api-plugin-graphql";
const schema = new SchemaBuilder()
.addType("User", (t) =>
t.field("id", "ID", { required: true })
.field("email", "String", { required: true })
)
.addQuery("user", "User", {
args: [{ name: "id", type: "ID", required: true, isList: false }],
})
.addMutation("deleteUser", "Boolean", {
required: true,
args: [{ name: "id", type: "ID", required: true, isList: false }],
})
.build();
const resolvers = new ResolverComposer()
.useForType("Query", createQueryExecutedMiddleware())
.useForType("Mutation", createQueryExecutedMiddleware())
.useForType("Mutation", requireRoles("admin"))
.useForType(
"Mutation",
validateArgs((a) => (typeof a.id === "string" ? null : "id required"))
)
.addResolver("Query", "user", (_p, args) => ({ id: args.id, email: "x@y" }))
.addResolver("Mutation", "deleteUser", () => true)
.build();
graphqlEvents.on("graphql:query:executed", (e) => {
console.log(`${e.operationType}.${e.operationName} ${e.durationMs}ms`);
});
const definition = defineGraphQLPlugin({
name: "users-gql",
version: "0.1.0",
schema,
resolvers,
});
Modules
error-codes/error-codes.md—GRAPHQL_CODES,GraphQLError.otel/instruments.md— OTel instruments.plugin/plugin.md—defineGraphQLPlugin.resolver/resolver.md—ResolverComposer,requireRoles,validateArgs,createQueryExecutedMiddleware,graphqlEvents.schema-builder/schema-builder.md—SchemaBuilder.schemas/options.md—DefineGraphQLPluginOptionsSchema.type-builder/type-builder.md—TypeBuilder.types/graphql.types.md— full type surface.
Scope
This package is functional-parity with upstream @suaveplan/api-plugin-graphql (suaveplan main, v1.0.4) plus hardening (typed errors, Zod boundary, OTel). Live execution (graphql-js), federation, persisted queries, subscriptions transport, SDL emission, and schema-registry publishing are out of scope for this release and are enumerated in enterprise/api-plugin-graphql.md §3 as future enterprise upgrades.
License
MIT.