or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

ast-extraction.mddirectives.mddocument-transformation.mdfragments.mdindex.mdstore-utilities.mdutility-functions.md
tile.json

document-transformation.mddocs/

Document Transformation

Functions for modifying GraphQL documents including removing directives, adding __typename fields, and transforming document structure.

Capabilities

Remove Directives From Document

Removes specified directives from a GraphQL document, with optional field removal when directives match.

/**
 * Remove directives from a GraphQL document
 * @param directives - Array of directive removal configurations
 * @param doc - GraphQL document to transform
 * @returns Modified document with directives removed, or null if document becomes empty
 */
function removeDirectivesFromDocument(
  directives: RemoveDirectiveConfig[],
  doc: DocumentNode
): DocumentNode | null;

Usage Example:

import { removeDirectivesFromDocument } from "apollo-utilities";
import { parse } from "graphql";

const query = parse(`
  query GetUser {
    user @client {
      name
      email @deprecated(reason: "Use contact.email")
      profile @connection(key: "profile") {
        bio
      }
    }
  }
`);

// Remove all @client directives and their fields
const config = [
  {
    name: "client",
    remove: true // Also remove the field containing this directive
  }
];

const cleanedQuery = removeDirectivesFromDocument(config, query);
console.log(print(cleanedQuery));
// query GetUser {
//   // user field completely removed because it had @client
// }

// Remove just the directive but keep the field
const config2 = [
  {
    name: "deprecated",
    remove: false // Only remove directive, keep field
  }
];

const result = removeDirectivesFromDocument(config2, query);
// email field remains but @deprecated directive is removed

Add Typename To Document

Adds __typename fields to all selection sets in a GraphQL document for caching purposes.

/**
 * Add __typename fields to all selection sets in a document
 * @param doc - GraphQL document to transform
 * @returns Document with __typename fields added
 */
function addTypenameToDocument(doc: DocumentNode): DocumentNode;

Usage Example:

import { addTypenameToDocument } from "apollo-utilities";
import { parse } from "graphql";

const query = parse(`
  query GetUser {
    user {
      name
      posts {
        title
        comments {
          text
        }
      }
    }
  }
`);

const queryWithTypename = addTypenameToDocument(query);
console.log(print(queryWithTypename));
// query GetUser {
//   user {
//     name
//     posts {
//       title
//       comments {
//         text
//         __typename
//       }
//       __typename
//     }
//     __typename
//   }
// }

Special Handling:

  • Skips adding __typename to operation-level selection sets
  • Skips if __typename already exists
  • Skips for introspection queries (fields starting with __)
  • Skips for fields with @export directive

Remove Connection Directive From Document

Removes @connection directives from a GraphQL document, with warnings for missing key parameters.

/**
 * Remove @connection directives from document
 * @param doc - GraphQL document to transform
 * @returns Document with @connection directives removed
 */
function removeConnectionDirectiveFromDocument(doc: DocumentNode): DocumentNode | null;

Usage Example:

import { removeConnectionDirectiveFromDocument } from "apollo-utilities";
import { parse } from "graphql";

const query = parse(`
  query GetUser {
    user {
      posts @connection(key: "userPosts") {
        edges {
          node {
            title
          }
        }
      }
    }
  }
`);

const cleanedQuery = removeConnectionDirectiveFromDocument(query);
// @connection directive is removed but posts field remains

Get Directives From Document

Extracts only the parts of a document that contain specified directives.

/**
 * Extract parts of document that contain specified directives
 * @param directives - Array of directive configurations to match
 * @param doc - GraphQL document to analyze
 * @returns Document containing only selections with matching directives
 */
function getDirectivesFromDocument(
  directives: GetDirectiveConfig[],
  doc: DocumentNode
): DocumentNode;

Usage Example:

import { getDirectivesFromDocument } from "apollo-utilities";
import { parse } from "graphql";

const query = parse(`
  query GetUser {
    user {
      name
      email @client
      posts {
        title @client
        content
      }
    }
  }
`);

const clientConfig = [{ name: "client" }];
const clientOnlyDoc = getDirectivesFromDocument(clientConfig, query);

console.log(print(clientOnlyDoc));
// query GetUser {
//   user {
//     email @client
//     posts {
//       title @client
//     }
//   }
// }
// Only fields with @client directive are preserved

Remove Arguments From Document

Removes specified arguments from fields and operation variable definitions.

/**
 * Remove arguments from document fields and operation variables
 * @param config - Array of argument removal configurations
 * @param doc - GraphQL document to transform
 * @returns Document with specified arguments removed
 */
function removeArgumentsFromDocument(
  config: RemoveArgumentsConfig[],
  doc: DocumentNode
): DocumentNode;

Usage Example:

import { removeArgumentsFromDocument } from "apollo-utilities";
import { parse } from "graphql";

const query = parse(`
  query GetUsers($status: String, $limit: Int) {
    users(status: $status, limit: $limit) {
      name
    }
  }
`);

const config = [
  { name: "status" } // Remove all arguments that use $status variable
];

const result = removeArgumentsFromDocument(config, query);
// $status variable definition and status argument are removed
// $limit remains unchanged

Remove Fragment Spread From Document

Removes specified fragment spreads and their definitions from a document.

/**
 * Remove fragment spreads and definitions from document
 * @param config - Array of fragment spread removal configurations
 * @param doc - GraphQL document to transform
 * @returns Document with specified fragments removed
 */
function removeFragmentSpreadFromDocument(
  config: RemoveFragmentSpreadConfig[],
  doc: DocumentNode
): DocumentNode;

Build Query From Selection Set

Converts any operation into a query operation while preserving the selection set.

/**
 * Convert operation to query operation
 * @param document - GraphQL document to transform
 * @returns Document with operation converted to query type
 */
function buildQueryFromSelectionSet(document: DocumentNode): DocumentNode;

Usage Example:

import { buildQueryFromSelectionSet } from "apollo-utilities";
import { parse } from "graphql";

const mutation = parse(`
  mutation CreateUser($input: UserInput!) {
    createUser(input: $input) {
      id
      name
      email
    }
  }
`);

const queryVersion = buildQueryFromSelectionSet(mutation);
console.log(print(queryVersion));
// query CreateUser($input: UserInput!) {
//   createUser(input: $input) {
//     id
//     name
//     email
//   }
// }
// Operation type changed from mutation to query

Remove Client Sets From Document

Removes fields and selection sets that contain @client directives, used for separating server and client-only operations.

/**
 * Remove @client directive fields from document
 * @param document - GraphQL document to transform
 * @returns Document with @client fields removed, or null if document becomes empty
 */
function removeClientSetsFromDocument(document: DocumentNode): DocumentNode | null;

Usage Example:

import { removeClientSetsFromDocument } from "apollo-utilities";
import { parse } from "graphql";

const query = parse(`
  query GetUser {
    user {
      id
      name
      email
      isLoggedIn @client
      localPreferences @client {
        theme
        notifications
      }
    }
  }
`);

const serverOnlyQuery = removeClientSetsFromDocument(query);
console.log(print(serverOnlyQuery));
// query GetUser {
//   user {
//     id
//     name
//     email
//   }
// }
// @client fields are completely removed

Configuration Types

interface RemoveNodeConfig<N> {
  /** Name of the node to match */
  name?: string;
  /** Custom test function for matching nodes */
  test?: (node: N) => boolean;
  /** Whether to remove the entire field/node when directive matches */
  remove?: boolean;
}

interface GetNodeConfig<N> {
  /** Name of the node to match */
  name?: string;
  /** Custom test function for matching nodes */
  test?: (node: N) => boolean;
}

type RemoveDirectiveConfig = RemoveNodeConfig<DirectiveNode>;
type GetDirectiveConfig = GetNodeConfig<DirectiveNode>;
type RemoveArgumentsConfig = RemoveNodeConfig<ArgumentNode>;
type GetFragmentSpreadConfig = GetNodeConfig<FragmentSpreadNode>;
type RemoveFragmentSpreadConfig = RemoveNodeConfig<FragmentSpreadNode>;
type RemoveFragmentDefinitionConfig = RemoveNodeConfig<FragmentDefinitionNode>;
type RemoveVariableDefinitionConfig = RemoveNodeConfig<VariableDefinitionNode>;

Advanced Usage Patterns

Conditional Directive Removal

// Remove directives based on custom logic
const config = [
  {
    test: (directive: DirectiveNode) => {
      return directive.name.value === "deprecated" && 
             directive.arguments?.some(arg => 
               arg.name.value === "reason" && 
               arg.value.kind === "StringValue" &&
               arg.value.value.includes("legacy")
             );
    },
    remove: true
  }
];

const result = removeDirectivesFromDocument(config, document);

Chaining Transformations

import { 
  removeClientSetsFromDocument,
  addTypenameToDocument,
  removeConnectionDirectiveFromDocument 
} from "apollo-utilities";

// Chain multiple transformations
let transformedDoc = removeClientSetsFromDocument(originalDoc);
if (transformedDoc) {
  transformedDoc = removeConnectionDirectiveFromDocument(transformedDoc);
  if (transformedDoc) {
    transformedDoc = addTypenameToDocument(transformedDoc);
  }
}