@graphjson/presets
v0.0.1
Published
> Pre-built plugins for common GraphQL patterns
Readme
@graphjson/presets
Pre-built plugins for common GraphQL patterns
GraphJSON Presets provides ready-to-use plugins for common GraphQL patterns like Relay pagination, eliminating boilerplate and ensuring consistency.
Why Use This?
- 🎯 Relay Pagination - Automatic edges/nodes/pageInfo structure
- 🔌 Plugin-Based - Works with the GraphJSON plugin system
- ⚡ Zero Config - Works out of the box
- 🎨 Customizable - Extend or create your own presets
- 📦 Lightweight - Minimal dependencies
Installation
npm install @graphjson/presets @graphjson/coreQuick Start
import { generateDocument, applyPlugins } from '@graphjson/core';
import { relayPagination } from '@graphjson/presets';
// Generate a basic query
const { ast } = generateDocument({
query: {
posts: {
args: { first: 20 },
select: {
id: true,
title: true
}
}
}
});
// Apply Relay pagination preset
const relayQuery = applyPlugins(ast, [relayPagination()]);
// Result now includes edges { node { ... } } and pageInfo structureAvailable Presets
relayPagination()
Transforms queries to follow the Relay pagination specification.
Before:
query {
posts(first: 20) {
id
title
}
}After:
query {
posts(first: 20) {
edges {
node {
id
title
}
}
pageInfo {
hasNextPage
endCursor
}
}
}Usage
With generateDocument
import { generateDocument, applyPlugins } from '@graphjson/core';
import { relayPagination } from '@graphjson/presets';
const query = {
query: {
users: {
args: { first: 10 },
select: {
id: true,
name: true
}
}
}
};
const { ast } = generateDocument(query);
const transformed = applyPlugins(ast, [relayPagination()]);With SDK
import { query, field } from '@graphjson/sdk';
const q = query({
posts: field()
.paginate('relay') // ← Uses relayPagination preset
.args({ first: 20 })
.select({
id: true,
title: true
})
});Relay Pagination Details
What It Does
The relayPagination() preset automatically wraps your field selection with the Relay connection structure:
Original Field:
{
"posts": {
"select": {
"id": true,
"title": true
}
}
}Transformed:
{
"posts": {
"select": {
"edges": {
"select": {
"node": {
"select": {
"id": true,
"title": true
}
}
}
},
"pageInfo": {
"select": {
"hasNextPage": true,
"endCursor": true
}
}
}
}
}When to Use
Use Relay pagination when:
- ✅ Your API follows Relay cursor connections spec
- ✅ You need cursor-based pagination
- ✅ You want pageInfo metadata
- ✅ You're using Relay or similar clients
Configuration
The preset works automatically with no configuration needed. It detects fields that should be paginated and applies the transformation.
Integration Examples
With Apollo Client
import { ApolloClient } from '@apollo/client';
import { generateDocument, applyPlugins } from '@graphjson/core';
import { relayPagination } from '@graphjson/presets';
const { ast } = generateDocument(query);
const relayAst = applyPlugins(ast, [relayPagination()]);
const result = await client.query({
query: relayAst,
variables: { first: 20 }
});
// Access paginated data
const posts = result.data.posts.edges.map(edge => edge.node);
const hasMore = result.data.posts.pageInfo.hasNextPage;With React
import { useState } from 'react';
function PostsList() {
const [cursor, setCursor] = useState(null);
const loadMore = async () => {
const { ast } = generateDocument(postsQuery);
const relayAst = applyPlugins(ast, [relayPagination()]);
const result = await client.query({
query: relayAst,
variables: { first: 20, after: cursor }
});
const { edges, pageInfo } = result.data.posts;
const newPosts = edges.map(e => e.node);
if (pageInfo.hasNextPage) {
setCursor(pageInfo.endCursor);
}
return newPosts;
};
// ... render logic
}Creating Custom Presets
You can create your own presets following the plugin interface:
import type { GraphJsonPlugin } from '@graphjson/plugins';
export function customPreset(): GraphJsonPlugin {
return {
onDocument(document) {
// Transform entire document
return modifiedDocument;
},
onField(field, context) {
// Transform individual fields
return modifiedField;
}
};
}Example - Add timestamp to all queries:
export function addTimestamp(): GraphJsonPlugin {
return {
onField(field) {
if (!field.selectionSet) return field;
return {
...field,
selectionSet: {
...field.selectionSet,
selections: [
...field.selectionSet.selections,
{
kind: Kind.FIELD,
name: { kind: Kind.NAME, value: 'timestamp' }
}
]
}
};
}
};
}GraphJSON Ecosystem
| Package | Description | NPM |
|---------|-------------|-----|
| @graphjson/core | Core document generation | |
| @graphjson/plugins | Plugin system types |
|
| @graphjson/sdk | High-level SDK |
|
Examples
See the examples directory:
- Pagination Example - Relay pagination
- Advanced Example - Combined features
Contributing
Contributions are welcome! Please see CONTRIBUTING.md.
License
MIT © NexaLeaf
