| name | gazania |
| description | Gazania — a TypeScript GraphQL query builder. Applies when: writing graphql queries/mutations/subscriptions with gazania. |
| applyTo | **/*.ts,**/*.tsx,**/*.vue,**/*.svelte,gazania.config.ts,gazania.config.js |
Gazania Skill
Gazania lets you write GraphQL operations as TypeScript code with full type inference, autocompletion, and compile-time error checking.
Quick start
Installation
pnpm install gazania
npx gazania generate --schema https://api.example.com/graphql --output src/gazania-schema.d.ts
Examples
Basic query
import { createGazania } from 'gazania'
const gazania = createGazania('https://api.example.com/graphql')
const GetHelloQuery = gazania.query('GetHello')
.select($ => $.select(['hello']))
query GetHello {
hello
}
With variables and arguments
const FindAdminQuery = gazania.query('FindAdmin')
.vars({ name: 'String!' })
.select(($, vars) => $.select([{
users: $ => $.args({ name: vars.name, first: 1, role: gazania.enum('ADMIN') })
.select(['id', 'name', 'email']),
}]))
query FindAdmin($name: String!) {
users(name: $name, first: 1, role: ADMIN) {
id
name
email
}
}
Directives
const WithDirectiveQuery = gazania.query('WithDirective')
.vars({ includeEmail: 'Boolean!' })
.directives(vars => [
['@cache', { disable: vars.includeEmail }],
])
.select(($, vars) => $.select([{
users: $ => $.args({ first: 1 })
.select([
'id',
'name',
{
email: $ => $.directives(['@include', { if: vars.includeEmail }]),
}
]),
}]))
query WithDirective($includeEmail: Boolean!) @cache(disable: $includeEmail) {
users(first: 1) {
id
name
email @include(if: $includeEmail)
}
}
Splitting / Reuse Query
const UserBasicInfo_UserFragment = gazania.partial('UserBasicInfo_User')
.on('User')
.select(['id', 'name', 'email'])
const UserBasicInfoQuery = gazania.query('UserBasicInfo')
.select(($, vars) => $.select([{
users: $ => $.args({ first: 1 })
.select([
...UserBasicInfo_UserFragment(vars)
]),
}]))
query UserBasicInfo {
users(first: 1) {
...UserBasicInfo_User
}
}
fragment UserBasicInfo_User on User {
id
name
email
}
References
Consult these files for detailed patterns before generating code:
- Setup & configuration — install,
gazania.config.ts, schema generation, multi-schema
- Building queries — selections, variables, arguments, aliases, directives, mutations, subscriptions
- Fragments & partials — named fragments, reusable partials, fragment masking
- Typed documents —
ResultOf, VariablesOf, TypedDocumentNode, client integration
- Persisted queries —
gazania extract, manifest generation, persisted query workflows
Rules
Always follow these rules when writing Gazania code:
- In
.select([...]), use this shape only: zero or more literal field strings, then at most one object as the final element
- Non-final elements in
.select([...]) must be literal selections (for example 'id', 'name', '__typename')
- Put all nested field callbacks in the single final object when object-style selection is needed
- Initialize with
createGazania('https://api.example.com/graphql') (URL from config), or createGazania({} as Schema) as an alternative.
- Variable types use GraphQL type strings (e.g.
'Int!'), not TypeScript types
- Add
! for non-nullable fields (e.g. 'String!'), otherwise the result type includes null | undefined
- Use
ResultOf / VariablesOf to extract types (e.g. type User = ResultOf<typeof userQuery>) — never write them manually
- For fragment masking: type props with
FragmentOf<typeof partial> and access data via readFragment()
- Config file should be named
gazania.config.ts (Node.js >= 22.6) or gazania.config.js
- NEVER use external variables or functions inside selection builders, the query MUST BE standalone and statically analyzable
- NEVER commit the generated schema file to git — add it to
.gitignore and regenerate in CI/build. The generated format is not a stability guarantee and may change in any Gazania release