npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@bota-apps/gql-codegen

v0.6.3

Published

SDL-first code generator: derives domain definitions, form/detail schemas, enum display metadata, Zod input validators, and typed GraphQL documents from an annotated GraphQL SDL. Node-side build tool — pairs with @graphql-codegen/typescript for the base t

Readme

@bota-apps/gql-codegen

SDL-first code generator. Reads an annotated GraphQL SDL — the API-side single source of truth — and derives everything the UI would otherwise hand-maintain:

| File | Contents | | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | domainDefinitions.ts | Rich per-entity field model (EntityDefinition / CreateInputDefinition), plus <mutation>Definition for custom action inputs | | forms.ts | Create/update form schemas + detail schemas + <mutation>FormSchema for custom action mutations, built via @bota-apps/schema-utils | | enums.ts | <enum>Meta (label + Badge tone from @display) and <enum>Options | | inputSchemas.ts | Directive-aware Zod validators for every create/update and action-mutation input (nested inputs included) | | operations.ts | TypedDocumentNode documents for every Query/Mutation root field — entity CRUD plus custom operations (aggregates, singletons, domain mutations), with nested selections |

It pairs with @graphql-codegen/typescript, which emits the base types.ts the artifacts import (--types-import, default ./types).

Install

pnpm add -D @bota-apps/gql-codegen
# pairs with @graphql-codegen/typescript for the base types.ts

Usage

CLI

The package ships a bota-gql-codegen bin. It reads every .graphql file under --schema (recursive, sorted for determinism), writes the five artifact files into --out, prints diagnostics to stderr, and exits non-zero when any diagnostic is an error:

bota-gql-codegen --schema ../../mock-graphql/src --out src/schema/generated

| Flag | Default | What | | ---------------- | ---------- | --------------------------------------------------------------------------------- | | --schema <dir> | required | Directory scanned recursively for .graphql SDL files | | --out <dir> | required | Output directory for the five generated files (created if missing) | | --types-import | ./types | Import specifier for the base types file emitted by @graphql-codegen/typescript | | --money-type | Money | Object type treated as the platform money value | | --quiet | false | Report only error diagnostics (suppress info/warning) |

Programmatic

import { collectSdl, generateFromSdl } from "@bota-apps/gql-codegen";

const sdl = collectSdl("../../mock-graphql/src").join("\n");
const { files, diagnostics } = generateFromSdl(sdl, {
  typesImportPath: "./types", // default
  moneyTypeName: "Money", // default
  maxSelectionDepth: 4, // default nesting depth for selection sets
});

// files: { domainDefinitions, forms, enums, inputSchemas, operations } — each a string

API

| Export | What | | -------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | | generateFromSdl(sdl, options?) | Orchestrator: SDL string in → { files, diagnostics } (GenerateResult) out | | collectSdl(dir) | Reads every .graphql file under dir (recursive, sorted) → string[] | | buildModel(sdl, options?) | Lower-level SDL → SdlModel domain model the emitters consume | | humanize(name) | Field/enum name → human label (the same helper used for default @labels) | | widgetForField / widgetAllowed / isDomainWidget | Widget-policy helpers mapping GraphQL types → form widgets | | GenerateOptions / GenerateResult / GeneratedFiles | Option and result types for generateFromSdl | | SdlModel / EntityModel / FieldModel / RootFieldModel / InputFormModel / ActionFormModel / DetailViewModel / Diagnostic | Domain-model types returned by buildModel |

What the SDL expresses

  • Entities are object types with a matching Create<X>Input and/or Update<X>Input (update-only entities are supported — services without create/delete exist).
  • Custom operations are all remaining Query/Mutation root fields — each gets a document too (scalar/enum/JSON returns emit selection-less documents), so apps never hand-write operations. Underscore-prefixed root fields (_health) are treated as internal and skipped.
  • Action forms are projected from a custom mutation's input-object argument (preferring one named input): promoteProject(input: PromoteProjectInput!) yields promoteProjectFormSchema() alongside its document, using the input's own @widget/@min/@label directives. Scalar-only actions (lockTask(id: ID!)) get no form. So apps stop hand-authoring the forms that just mirror an SDL input.
  • @detailView types are read-only projections with no Create/Update input (e.g. type OrganizationProfile @detailView). They get a <type>DetailSchema() so apps stop hand-authoring DynamicDetail schemas, but claim no root fields — a profile: Profile! query stays non-null (unlike an entity's nullable oneField).
  • Widgets come from GraphQL types, never field names: enum → select, Booleancheckbox, Moneycurrency, Int/Floatnumber, everything else → text. Specialized widgets (email, phone, date, textarea, switch, …) are requested explicitly with @widget(type:).
  • Validation directives (@min, @max, @minLength, @maxLength, @pattern) feed both the form field constraints and the Zod schemas.
  • Display metadata: @display(label:, tone:) on enum values, @label / @placeholder / @description / @section / @order on fields, @detail(hidden: true) to drop a field from detail views.

Graceful degradation, loud contradictions

SDL a form can't render never aborts the run:

  • a required unsupported input field (list, nested input object, JSON) skips that one form — the entity's documents and Zod schemas still generate;
  • an optional unsupported input field is omitted from the form but kept in Zod;
  • entity fields a detail view can't render (lists, nested objects, JSON) are skipped from the detail schema but still fetched by the generated selections;
  • nested selections are cycle-guarded and depth-capped (maxSelectionDepth), and fields taking required arguments are left to hand-written documents.

Each of these is reported as an info/warning diagnostic. Actual contradictions — an @widget that doesn't fit the field's type, an empty enum — are error diagnostics and fail the CLI.

Every generated operation is validated against the schema built from the same SDL before it is returned, so emitted documents are schema-valid by construction.

Part of the @bota-apps packages monorepo.