strictql
v1.0.0
Published
Contract-driven, code-first GraphQL library. Mandatory Zod validation, predictable error shape, auth policies, security limits, and deterministic schema artifact generation.
Maintainers
Readme
StrictQL
Contract-driven, code-first GraphQL library for Node.js + TypeScript. Mandatory input/output validation (Zod), predictable error shape, reusable auth policies, query security limits, and deterministic artifact generation — all enforced through a fixed execution pipeline.
Installation
npm install strictql graphql zodPeer dependencies: graphql ^16, zod ^4.
Quick start
import { z } from "zod";
import { query, mutation, buildSchema } from "strictql";
const getUser = query({
name: "getUser",
description: "Fetch user by ID",
input: z.object({ id: z.string() }),
output: z.object({ id: z.string(), name: z.string(), role: z.string() }),
resolve: async ({ input }) => ({ id: input.id, name: "Alice", role: "admin" })
});
const schema = buildSchema({ queries: [getUser], mutations: [] });Execution pipeline
Every operation: validate input → auth check → resolve → validate output → normalize errors. None of these steps can be skipped.
Error handling
All errors land in errors[].extensions.strictql. Branch by code, not by message.
| code | phase |
|------|-------|
| INPUT_VALIDATION_ERROR | input |
| OUTPUT_VALIDATION_ERROR | output |
| RESOLVER_ERROR | resolver |
| INTERNAL_ERROR | pipeline |
| AUTH_DENIED | auth |
| RATE_LIMITED | resolver |
| SECURITY_LIMIT_EXCEEDED | security |
Auth policies
import { createPolicy, andPolicy, hasRolePolicy } from "strictql";
const isAdmin = hasRolePolicy("isAdmin", { roleKey: "role", requiredRole: "admin" });
const schema = buildSchema({ queries, authPolicy: isAdmin }); // global
// or per-operation:
const q = query({ name: "secret", policy: isAdmin, ... });Strict access mode
When strictAccessMode: true, every operation must declare an explicit policy (or be covered by a global authPolicy). Missing policy is a build-time error, not a runtime surprise.
import { buildSchema, publicPolicy, hasRolePolicy } from "strictql";
const isAdmin = hasRolePolicy("isAdmin", { roleKey: "role", requiredRole: "admin" });
const schema = buildSchema({
strictAccessMode: true,
queries: [
query({ name: "getUsers", policy: publicPolicy, ... }),
query({ name: "adminData", policy: isAdmin, ... }),
],
});Use publicPolicy for operations that are intentionally open — this makes the intent explicit rather than implicit.
Security
buildSchema({ queries, mutations, maxQueryDepth: 6, maxQueryComplexity: 50, maxNestedListDepth: 2 });Contract generation
import { writeOperationArtifacts } from "strictql";
await writeOperationArtifacts({ queries, mutations, outputDir: "./artifacts", title: "My API" });Generates: strictql.contract.json, strictql.contract.llm.json, strictql.schema.graphql, strictql.contract.md.
strictql-tooling CLI
Any project using this library can generate a full schema export with one command:
# Install strictql, then add to package.json scripts:
# "export-api": "strictql-tooling export"
npx strictql-tooling export --config ./strictql.tooling.config.tsConfig file (strictql.tooling.config.ts):
import type { StrictQLToolingConfig } from "strictql";
import { queries, mutations } from "./src/graphql/registry.js";
export default {
queries,
mutations,
outputDir: "./artifacts",
title: "My API Contract"
} satisfies StrictQLToolingConfig;For TypeScript config files, run via tsx:
npx tsx strictql-tooling exportApollo integration
import { ApolloServer } from "@apollo/server";
import { createApolloServerIntegration } from "strictql";
const { schema, context } = createApolloServerIntegration({
schema,
injectContext: ({ adapterContext }) => ({ userId: adapterContext.headers["x-user-id"] })
});
const server = new ApolloServer({ schema });Yoga integration
import { createYoga } from "graphql-yoga";
import { createGraphqlYogaIntegration } from "strictql";
const { schema, context } = createGraphqlYogaIntegration({ schema, injectContext: ... });
const yoga = createYoga({ schema, context: ({ req }) => context({ adapterContext: req }) });Full API reference
See LLMS.md — auto-generated full API reference for all exported functions and types.
