@eleven-am/nestjs-graphql-crud
Version:
nestjs-graphql-crud is a library that aims to reduce the boilerplate code needed to create a GraphQL CRUD API.
287 lines • 10.7 kB
JavaScript
"use strict";
/**
* @module crudModuleConfig
* @description Provides a fluent configuration API for CRUD modules
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.CustomResolverConfig = exports.CrudModuleConfig = exports.BaseCrudModuleConfig = void 0;
/**
* Base Configuration builder for CRUD modules with a fluent API
*
* @template Item - The entity type this CRUD module will manage
* @template CreateInput - The input type for create operations
* @template UpdateInput - The input type for update operations
* @template UpdateManyInput - The input type for update many operations
* @template WhereInput - The input type for query filters
*/
class BaseCrudModuleConfig {
/**
* Create a new CRUD module configuration
*
* @param {CrudModuleOptions<Item, CreateInput, UpdateInput, UpdateManyInput, WhereInput>} options - Initial configuration options
*/
constructor(options) {
this.options = options;
// Initialize resolver structure if not exists
if (!this.options.resolvers) {
this.options.resolvers = {
relationResolvers: []
};
}
}
/**
* Adds a one-to-many relation resolver to the module
*
* @template Target - The related entity type
* @template TargetWhereInput - The input type for filtering related entities
*
* @param {OneToManyRelationResolverConfig<Target, TargetWhereInput>} config - Configuration for the relation resolver
* @returns {this} The configuration builder (for method chaining)
*/
addRelation(config) {
if (!this.options.resolvers) {
this.options.resolvers = {
relationResolvers: []
};
}
this.options.resolvers.relationResolvers.push(config);
return this;
}
/**
* Adds a one-to-one relation resolver to the module
*
* @template Target - The related entity type
*
* @param {Omit<OneToOneRelationResolverConfig<Item, Target>, 'oneToOneRelation'>} config - Configuration for the one-to-one relation resolver
* @returns {this} The configuration builder (for method chaining)
*/
addOneToOneRelation(config) {
if (!this.options.resolvers) {
this.options.resolvers = {
relationResolvers: []
};
}
this.options.resolvers.relationResolvers.push({
...config,
nullable: config.nullable ?? false,
oneToOneRelation: true
});
return this;
}
/**
* Adds a custom subscription resolver to the module
*
* @template FilterType - The filter type for subscriptions
*
* @param {{ filter: Type<FilterType>; resolver: Type<SubscriptionResolver<Item, FilterType>> }} config - Configuration for the subscription resolver
* @returns {this} The configuration builder (for method chaining)
*/
withSubscription(config) {
this.options.subscriptionResolver = config;
return this;
}
/**
* Adds custom providers to the module
*
* @param {...Type[]} providers - The provider classes to add
* @returns {this} The configuration builder (for method chaining)
*/
withProviders(...providers) {
if (!this.options.providers) {
this.options.providers = [];
}
this.options.providers.push(...providers);
return this;
}
/**
* Sets a custom FindMany args type (e.g., from prisma-nest-graphql)
* This replaces the default take/skip pagination with full Prisma-style args
*
* @template FindManyArgs - The type of the custom find many args
* @param {Type<FindManyArgs>} findManyArgsType - The custom FindMany args class
* @returns {this} The configuration builder (for method chaining)
*/
withFindManyArgs(findManyArgsType) {
this.options.findManyArgs = findManyArgsType;
return this;
}
/**
* Adds custom controllers to the module
*
* @param {...Type[]} controllers - The controller classes to add
* @returns {this} The configuration builder (for method chaining)
*/
withControllers(...controllers) {
if (!this.options.controllers) {
this.options.controllers = [];
}
this.options.controllers.push(...controllers);
return this;
}
/**
* Adds custom authorizers to the module
*
* @param {...Type<WillAuthorize>[]} authorizer - The authorizer classes to add
* @returns {this} The configuration builder (for method chaining)
*/
withAuthorization(...authorizer) {
return this.withProviders(...authorizer);
}
/**
* Adds imports to the module
*
* @param {...(Type | DynamicModule | Promise<DynamicModule> | ForwardReference)[]} imports - The modules to import
* @returns {this} The configuration builder (for method chaining)
*/
import(...imports) {
if (!this.options.imports) {
this.options.imports = [];
}
this.options.imports.push(...imports);
return this;
}
/**
* Adds exports to the module
*
* @param {...(DynamicModule | string | symbol | Provider | ForwardReference | Abstract<any> | Function)[]} exports - The providers or modules to export
* @returns {this} The configuration builder (for method chaining)
*/
export(...exports) {
if (!this.options.exports) {
this.options.exports = [];
}
this.options.exports.push(...exports);
return this;
}
}
exports.BaseCrudModuleConfig = BaseCrudModuleConfig;
/**
* Configuration builder for CRUD modules with a fluent API
*
* @template Item - The entity type this CRUD module will manage
* @template CreateInput - The input type for create operations
* @template UpdateInput - The input type for update operations
* @template UpdateManyInput - The input type for update many operations
* @template WhereInput - The input type for query filters
*/
class CrudModuleConfig extends BaseCrudModuleConfig {
/**
* Registers a custom resolver class for this entity
*
* @template TResolver The type of the resolver class
* @param {Type<TResolver>} resolverClass The resolver class that implements custom resolvers
* @returns {CustomResolverConfig<Item, CreateInput, UpdateInput, UpdateManyInput, WhereInput, TResolver>} A CustomResolverConfig instance for chaining specialized resolver methods
*/
withCustomResolver(resolverClass) {
if (!this.options.resolvers) {
this.options.resolvers = {
relationResolvers: []
};
}
// Initialize custom resolvers if not exists
if (!this.options.resolvers.customResolvers) {
this.options.resolvers.customResolvers = {
factoryClass: resolverClass,
customResolvers: []
};
}
else {
this.options.resolvers.customResolvers.factoryClass = resolverClass;
}
// Add resolver class to providers
if (!this.options.providers) {
this.options.providers = [];
}
this.options.providers.push(resolverClass);
return new CustomResolverConfig(this.options);
}
}
exports.CrudModuleConfig = CrudModuleConfig;
/**
* Configuration class for custom resolvers that appears after withCustomResolver is called
*
* @template Item - The entity type this CRUD module will manage
* @template CreateInput - The input type for create operations
* @template UpdateInput - The input type for update operations
* @template UpdateManyInput - The input type for update many operations
* @template WhereInput - The input type for query filters
* @template TResolver - The type of the resolver class
*/
class CustomResolverConfig extends BaseCrudModuleConfig {
/**
* Add a custom query to the GraphQL schema
*
* @template M Method name in the resolver class
* @param {Object} config - Configuration for the query
* @returns {this} The configuration builder (for method chaining)
*/
addQuery(config) {
const customConfig = {
...config,
isMutation: false,
};
if (!this.options.resolvers) {
throw new Error('Custom resolver class not registered');
}
if (!this.options.resolvers.customResolvers) {
throw new Error('Custom resolver class not registered');
}
this.options.resolvers.customResolvers.customResolvers.push(customConfig);
return this;
}
/**
* Add a custom mutation to the GraphQL schema
*
* @template M Method name in the resolver class
* @param {Object} config - Configuration for the mutation
* @returns {this} The configuration builder (for method chaining)
*/
addMutation(config) {
const customConfig = {
...config,
isMutation: true,
};
if (!this.options.resolvers) {
throw new Error('Custom resolver class not registered');
}
if (!this.options.resolvers.customResolvers) {
throw new Error('Custom resolver class not registered');
}
this.options.resolvers.customResolvers.customResolvers.push(customConfig);
return this;
}
/**
* Add a field resolver to a type in the GraphQL schema
*
* @template M Method name in the resolver class
* @param {Object} config - Configuration for the field resolver
* @returns {this} The configuration builder (for method chaining)
*/
addResolveField(config) {
const customConfig = {
...config,
inputType: config.inputType || null,
outputType: config.outputType,
isMutation: false,
resolveField: config.resolveField,
};
if (!this.options.resolvers) {
throw new Error('Custom resolver class not registered');
}
if (!this.options.resolvers.customResolvers) {
throw new Error('Custom resolver class not registered');
}
this.options.resolvers.customResolvers.customResolvers.push(customConfig);
return this;
}
/**
* Go back to the main config builder
*
* @returns {CrudModuleConfig<Item, CreateInput, UpdateInput, UpdateManyInput, WhereInput>} The main configuration builder
*/
and() {
return new CrudModuleConfig(this.options);
}
}
exports.CustomResolverConfig = CustomResolverConfig;
//# sourceMappingURL=crudModuleConfig.js.map