@graphjson/plugins
v0.0.1
Published
> Plugin system type definitions for GraphJSON
Downloads
123
Readme
@graphjson/plugins
Plugin system type definitions for GraphJSON
Type definitions and interfaces for creating GraphJSON plugins that can transform GraphQL documents.
Why Use This?
- 🔌 Plugin Interface - Standard interface for creating plugins
- 🎯 Type-Safe - Full TypeScript support
- 🏗️ Extensible - Build custom transformations
- 📚 Well-Defined - Clear plugin lifecycle
- 🔧 Flexible - Transform documents or fields
Installation
npm install @graphjson/pluginsQuick Start
import type { GraphJsonPlugin } from '@graphjson/plugins';
import { Kind } from 'graphql';
export function myPlugin(): GraphJsonPlugin {
return {
onDocument(document) {
// Transform entire document
return document;
},
onField(field, context) {
// Transform individual fields
return field;
}
};
}Plugin Interface
interface GraphJsonPlugin {
onDocument?: (document: DocumentNode) => DocumentNode | void;
onField?: (field: FieldNode, context: PluginContext) => FieldNode | void;
}
interface PluginContext {
path: string[];
}Creating Plugins
Document-Level Plugin
Transforms the entire GraphQL document:
export function addOperationName(name: string): GraphJsonPlugin {
return {
onDocument(document) {
return {
...document,
definitions: document.definitions.map(def => {
if (def.kind === Kind.OPERATION_DEFINITION) {
return {
...def,
name: { kind: Kind.NAME, value: name }
};
}
return def;
})
};
}
};
}Field-Level Plugin
Transforms individual fields:
export function addTimestampField(): 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' }
}
]
}
};
}
};
}Context-Aware Plugin
Use context to make decisions:
export function depthLimiter(maxDepth: number): GraphJsonPlugin {
return {
onField(field, context) {
if (context.path.length > maxDepth) {
// Remove selections if too deep
return {
...field,
selectionSet: undefined
};
}
return field;
}
};
}Plugin Examples
Relay Pagination Plugin
export function relayPagination(): GraphJsonPlugin {
return {
onField(field) {
if (!field.selectionSet) return;
const hasEdges = field.selectionSet.selections.some(
s => s.kind === Kind.FIELD && s.name.value === 'edges'
);
if (hasEdges) return;
return {
...field,
selectionSet: {
kind: Kind.SELECTION_SET,
selections: [
{
kind: Kind.FIELD,
name: { kind: Kind.NAME, value: 'edges' },
selectionSet: {
kind: Kind.SELECTION_SET,
selections: [
{
kind: Kind.FIELD,
name: { kind: Kind.NAME, value: 'node' },
selectionSet: field.selectionSet
}
]
}
},
{
kind: Kind.FIELD,
name: { kind: Kind.NAME, value: 'pageInfo' },
selectionSet: {
kind: Kind.SELECTION_SET,
selections: [
{ kind: Kind.FIELD, name: { kind: Kind.NAME, value: 'hasNextPage' } },
{ kind: Kind.FIELD, name: { kind: Kind.NAME, value: 'endCursor' } }
]
}
}
]
}
};
}
};
}Auto-Include ID Plugin
export function autoIncludeId(): GraphJsonPlugin {
return {
onField(field) {
if (!field.selectionSet) return field;
const hasId = field.selectionSet.selections.some(
s => s.kind === Kind.FIELD && s.name.value === 'id'
);
if (hasId) return field;
return {
...field,
selectionSet: {
...field.selectionSet,
selections: [
{
kind: Kind.FIELD,
name: { kind: Kind.NAME, value: 'id' }
},
...field.selectionSet.selections
]
}
};
}
};
}Using Plugins
Single Plugin
import { applyPlugins } from '@graphjson/core';
import { relayPagination } from '@graphjson/presets';
const transformed = applyPlugins(document, [relayPagination()]);Multiple Plugins
import { applyPlugins } from '@graphjson/core';
const transformed = applyPlugins(document, [
plugin1(),
plugin2(),
plugin3()
]);Plugins are applied in order.
TypeScript Support
import type { GraphJsonPlugin, PluginContext } from '@graphjson/plugins';
import type { DocumentNode, FieldNode } from 'graphql';
export function typedPlugin(): GraphJsonPlugin {
return {
onDocument(document: DocumentNode): DocumentNode {
return document;
},
onField(field: FieldNode, context: PluginContext): FieldNode {
return field;
}
};
}GraphJSON Ecosystem
| Package | Description | NPM |
|---------|-------------|-----|
| @graphjson/core | Core library (uses plugins) | |
| @graphjson/presets | Pre-built plugins |
|
Contributing
Contributions are welcome! Please see CONTRIBUTING.md.
License
MIT © NexaLeaf
