GraphQL integration for the NestJS framework enabling developers to build GraphQL APIs using decorators and TypeScript
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Advanced schema building utilities, type loading, and definition generation for both code-first and schema-first approaches. This module provides the core infrastructure for generating executable GraphQL schemas from TypeScript classes and SDL files.
Main factory service for creating executable GraphQL schemas from NestJS module configuration.
/**
* Injectable factory service for generating executable GraphQL schemas
* Core service that orchestrates schema creation from decorators and metadata
*/
export class GraphQLFactory {
/**
* Create an executable GraphQL schema from module options
* @param options - GraphQL module configuration options
* @returns Promise resolving to executable GraphQL schema
*/
create(options: GqlModuleOptions): Promise<GraphQLSchema>;
/**
* Create schema with custom build options
* @param options - Module options
* @param buildOptions - Custom schema building options
* @returns Promise resolving to executable GraphQL schema
*/
createWithBuildOptions(
options: GqlModuleOptions,
buildOptions: BuildSchemaOptions
): Promise<GraphQLSchema>;
/**
* Merge multiple schemas into a single executable schema
* @param schemas - Array of GraphQL schemas to merge
* @returns Merged executable schema
*/
mergeSchemas(schemas: GraphQLSchema[]): GraphQLSchema;
}Usage Examples:
import { Injectable } from "@nestjs/common";
import { GraphQLFactory, GqlModuleOptions } from "@nestjs/graphql";
@Injectable()
export class CustomSchemaService {
constructor(private readonly graphqlFactory: GraphQLFactory) {}
async createCustomSchema(): Promise<GraphQLSchema> {
const options: GqlModuleOptions = {
autoSchemaFile: true,
buildSchemaOptions: {
dateScalarMode: 'isoDate',
orphanedTypes: [CustomType],
},
};
return this.graphqlFactory.create(options);
}
}Low-level factory for creating GraphQL schemas from metadata and build options.
/**
* Factory class for creating GraphQL schemas from metadata
* Provides fine-grained control over schema construction process
*/
export class GraphQLSchemaFactory {
/**
* Create GraphQL schema from build options and metadata
* @param metadata - Schema building options and metadata
* @returns Executable GraphQL schema
*/
create(metadata: BuildSchemaOptions): GraphQLSchema;
/**
* Create schema with custom type definitions
* @param typeDefs - GraphQL SDL type definitions
* @param resolvers - Resolver map
* @param options - Additional build options
* @returns Executable GraphQL schema
*/
createFromTypeDefs(
typeDefs: string,
resolvers: any,
options?: BuildSchemaOptions
): GraphQLSchema;
/**
* Transform existing schema with build options
* @param schema - Existing GraphQL schema
* @param options - Transformation options
* @returns Transformed schema
*/
transformSchema(schema: GraphQLSchema, options: BuildSchemaOptions): GraphQLSchema;
}Service for loading and merging GraphQL type definitions from files (schema-first approach).
/**
* Injectable service for loading and merging GraphQL type definitions from files
* Used in schema-first approach to combine SDL files into unified schema
*/
export class GraphQLTypesLoader {
/**
* Load and merge GraphQL type definitions from specified file paths
* @param paths - Array of file paths or glob patterns
* @returns Merged GraphQL SDL string
*/
mergeTypesByPaths(paths: string[]): string;
/**
* Load type definitions from a single file
* @param path - File path to load
* @returns GraphQL SDL string from file
*/
loadFromFile(path: string): string;
/**
* Load type definitions from multiple files
* @param paths - Array of file paths
* @returns Array of GraphQL SDL strings
*/
loadFromFiles(paths: string[]): string[];
/**
* Merge multiple GraphQL SDL strings
* @param typeDefs - Array of GraphQL SDL strings
* @returns Single merged GraphQL SDL string
*/
mergeTypeDefs(typeDefs: string[]): string;
}Usage Examples:
import { Injectable } from "@nestjs/common";
import { GraphQLTypesLoader } from "@nestjs/graphql";
@Injectable()
export class SchemaService {
constructor(private readonly typesLoader: GraphQLTypesLoader) {}
loadSchemaFiles(): string {
// Load from multiple paths
const typeDefs = this.typesLoader.mergeTypesByPaths([
'src/**/*.graphql',
'schemas/*.gql',
'types/user.graphql',
]);
return typeDefs;
}
loadSpecificSchema(): string {
// Load from specific files
const userTypes = this.typesLoader.loadFromFile('schemas/user.graphql');
const postTypes = this.typesLoader.loadFromFile('schemas/post.graphql');
return this.typesLoader.mergeTypeDefs([userTypes, postTypes]);
}
}
// Schema-first module configuration
@Module({
imports: [
GraphQLModule.forRoot({
typePaths: ['./**/*.graphql'],
definitions: {
path: join(process.cwd(), 'src/graphql.ts'),
outputAs: 'class',
},
}),
],
})
export class SchemaFirstModule {}Factory for generating TypeScript definitions from GraphQL schemas.
/**
* Factory for generating TypeScript definitions from GraphQL schemas
* Converts GraphQL SDL to TypeScript interfaces and types
*/
export class GraphQLDefinitionsFactory {
/**
* Generate TypeScript definitions from GraphQL schema
* @param options - Configuration options for generation
* @returns Promise that resolves when generation is complete
*/
generate(options: GenerateOptions): Promise<void>;
/**
* Generate definitions from schema object
* @param schema - GraphQL schema object
* @param options - Generation options
* @returns Generated TypeScript code string
*/
generateFromSchema(schema: GraphQLSchema, options: GenerateOptions): string;
/**
* Generate definitions from SDL string
* @param typeDefs - GraphQL SDL string
* @param options - Generation options
* @returns Generated TypeScript code string
*/
generateFromTypeDefs(typeDefs: string, options: GenerateOptions): string;
}
/**
* Options for TypeScript definitions generation
*/
interface GenerateOptions {
/** Output file path for generated definitions */
path: string;
/** Output format: 'class' or 'interface' */
outputAs?: 'class' | 'interface';
/** Whether to watch for schema changes */
watch?: boolean;
/** Custom scalar type mappings */
customScalarTypeMapping?: Record<string, string>;
/** Additional type imports to include */
additionalTypeImports?: string[];
/** Whether to emit decorator metadata */
emitDecoratorMetadata?: boolean;
/** Whether to skip schema validation */
skipSchemaValidation?: boolean;
}
type DefinitionsGeneratorOptions = GenerateOptions;Usage Examples:
import { GraphQLDefinitionsFactory } from "@nestjs/graphql";
// Generate TypeScript definitions
const definitionsFactory = new GraphQLDefinitionsFactory();
await definitionsFactory.generate({
path: join(process.cwd(), 'src/generated/graphql.ts'),
outputAs: 'interface',
customScalarTypeMapping: {
DateTime: 'Date',
JSON: 'any',
},
additionalTypeImports: [
"import { CustomType } from '../types/custom';"
],
});
// Generated file content example:
/*
export interface User {
id: string;
name: string;
email: string;
createdAt: Date; // DateTime scalar mapped to Date
}
export interface CreateUserInput {
name: string;
email: string;
}
export interface Query {
users(): User[];
user(id: string): User;
}
export interface Mutation {
createUser(input: CreateUserInput): User;
}
*/Service providing runtime access to the compiled GraphQL schema.
/**
* Injectable service providing access to the compiled GraphQL schema
* Useful for runtime schema introspection and manipulation
*/
export class GraphQLSchemaHost {
/**
* Get the compiled GraphQL schema
* @returns Executable GraphQL schema instance
*/
get schema(): GraphQLSchema;
/**
* Check if schema is available
* @returns True if schema has been compiled and is available
*/
get isSchemaAvailable(): boolean;
/**
* Get schema SDL representation
* @returns GraphQL SDL string of the compiled schema
*/
getSchemaString(): string;
/**
* Get specific type from schema
* @param typeName - Name of the GraphQL type
* @returns GraphQL type object or undefined
*/
getType(typeName: string): GraphQLType | undefined;
/**
* Get all types from schema
* @returns Map of type names to GraphQL type objects
*/
getTypeMap(): GraphQLTypeMap;
}Usage Examples:
import { Injectable } from "@nestjs/common";
import { GraphQLSchemaHost } from "@nestjs/graphql";
import { printSchema } from "graphql";
@Injectable()
export class SchemaIntrospectionService {
constructor(private readonly schemaHost: GraphQLSchemaHost) {}
getSchemaSDL(): string {
const schema = this.schemaHost.schema;
return printSchema(schema);
}
hasType(typeName: string): boolean {
return !!this.schemaHost.getType(typeName);
}
getAllTypeNames(): string[] {
const typeMap = this.schemaHost.getTypeMap();
return Object.keys(typeMap).filter(name => !name.startsWith('__'));
}
validateSchemaIntegrity(): boolean {
return this.schemaHost.isSchemaAvailable;
}
}Service for exploring GraphQL AST and generating TypeScript definitions.
/**
* Injectable service for exploring GraphQL AST and generating TypeScript definitions
* Provides low-level access to GraphQL schema analysis
*/
export class GraphQLAstExplorer {
/**
* Explore GraphQL document AST and extract type information
* @param documentAST - GraphQL document AST
* @returns Extracted type information
*/
explore(documentAST: DocumentNode): any;
/**
* Generate TypeScript definitions from AST
* @param documentAST - GraphQL document AST
* @param options - Generation options
* @returns Generated TypeScript code
*/
generateDefinitions(documentAST: DocumentNode, options: DefinitionsGeneratorOptions): string;
/**
* Extract field information from type definition
* @param typeNode - GraphQL type definition node
* @returns Field information array
*/
extractFields(typeNode: any): any[];
/**
* Build type reference from AST node
* @param typeNode - GraphQL type node
* @returns TypeScript type reference string
*/
buildTypeReference(typeNode: any): string;
}Utility class for file system operations during schema building.
/**
* Helper class for file system operations during schema building
* Provides utilities for file watching, path resolution, and file I/O
*/
export class FileSystemHelper {
/**
* Write content to file with proper directory creation
* @param path - File path to write to
* @param content - Content to write
* @returns Promise that resolves when write is complete
*/
writeFile(path: string, content: string): Promise<void>;
/**
* Read file content
* @param path - File path to read from
* @returns Promise resolving to file content
*/
readFile(path: string): Promise<string>;
/**
* Check if file exists
* @param path - File path to check
* @returns True if file exists
*/
fileExists(path: string): boolean;
/**
* Watch files for changes
* @param paths - File paths or patterns to watch
* @param callback - Callback function for file changes
* @returns File watcher instance
*/
watchFiles(paths: string[], callback: (path: string) => void): any;
/**
* Resolve glob patterns to file paths
* @param patterns - Glob patterns to resolve
* @returns Array of resolved file paths
*/
resolveGlobPatterns(patterns: string[]): string[];
}Comprehensive configuration options for schema building process.
/**
* Options for GraphQL schema construction and building
*/
interface BuildSchemaOptions {
/** Date scalar handling mode */
dateScalarMode?: 'isoDate' | 'timestamp';
/** Custom scalar type mappings */
scalarsMap?: ScalarsTypeMap[];
/** Types to include in schema even if not referenced */
orphanedTypes?: Function[];
/** Global pipes for all fields */
globalPipes?: PipeTransform[];
/** Field-level middleware */
fieldMiddleware?: FieldMiddleware[];
/** Validation options for resolvers */
resolverValidationOptions?: ResolverValidationOptions;
/** Custom schema directives */
directives?: DirectiveNode[];
/** Schema-level extensions */
extensions?: Record<string, any>;
/** Number type handling */
numberScalarMode?: 'float' | 'integer';
/** Custom type name formatter */
typeNameFormatter?: (name: string) => string;
/** Schema transformation functions */
schemaTransformers?: SchemaTransformer[];
}
/**
* Schema transformer function type
*/
type SchemaTransformer = (schema: GraphQLSchema) => GraphQLSchema;
/**
* Scalar type mapping configuration
*/
interface ScalarsTypeMap {
/** TypeScript/JavaScript type constructor */
type: Function;
/** Corresponding GraphQL scalar type */
scalar: GraphQLScalarType;
}
/**
* Resolver validation configuration
*/
interface ResolverValidationOptions {
/** Whether to require resolvers for resolve type */
requireResolversForResolveType?: boolean;
/** Whether to require resolvers for args */
requireResolversForArgs?: boolean;
/** Whether to require resolvers for non-scalar fields */
requireResolversForNonScalar?: boolean;
/** Whether to require resolvers for all fields */
requireResolversForAllFields?: boolean;
/** Whether to allow resolve type on interfaces */
allowResolveTypeOnInterface?: boolean;
}Advanced Schema Building Example:
import { Module } from "@nestjs/common";
import { GraphQLModule } from "@nestjs/graphql";
import { ApolloDriver, ApolloDriverConfig } from "@nestjs/apollo";
import { GraphQLScalarType } from "graphql";
// Custom scalar
const DateTimeScalar = new GraphQLScalarType({
name: 'DateTime',
serialize: (value: Date) => value.toISOString(),
parseValue: (value: string) => new Date(value),
parseLiteral: (ast) => new Date(ast.value),
});
@Module({
imports: [
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
autoSchemaFile: true,
buildSchemaOptions: {
dateScalarMode: 'isoDate',
scalarsMap: [
{ type: Date, scalar: DateTimeScalar },
],
orphanedTypes: [UnreferencedType],
fieldMiddleware: [LoggingMiddleware],
resolverValidationOptions: {
requireResolversForNonScalar: false,
allowResolveTypeOnInterface: true,
},
schemaTransformers: [
(schema) => {
// Custom schema transformation
return addCustomDirectives(schema);
},
],
},
}),
],
})
export class AdvancedSchemaModule {}