@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.
286 lines • 13.4 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createBaseCrudResolver = createBaseCrudResolver;
const graphql_1 = require("@nestjs/graphql");
const graphql_subscriptions_1 = require("graphql-subscriptions");
const common_1 = require("@nestjs/common");
const decorators_1 = require("./decorators");
const authorizer_1 = require("@eleven-am/authorizer");
/**
* Creates a GraphQL resolver class with standard CRUD operations for a specific entity
*
* @template Item - The entity type this resolver 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
*
* @param {symbol} serviceToken - Symbol for the CRUD service token
* @param {symbol} resolverToken - Symbol for the subscription resolver token
* @param {Type} SubscriptionFilter - The filter type for subscriptions
* @param {CreateBaseCrudResolverOptions<Item, CreateInput, UpdateInput, UpdateManyInput, WhereInput>} options - Configuration options
* @returns {Type} A dynamically generated resolver class with CRUD operations
*/
function createBaseCrudResolver(serviceToken, resolverToken, SubscriptionFilter, options) {
var _a;
const ModelName = (0, decorators_1.firstLetterUppercase)(options.modelName);
let BaseCrudResolver = class BaseCrudResolver {
constructor(service, resolver, pubSub) {
this.service = service;
this.resolver = resolver;
this.pubSub = pubSub;
}
/**
* Query to find a single entity by criteria
*
* @param {any} ability - The user's ability for authorization
* @param {GraphQLResolveInfo} info - GraphQL resolve info for field selection
* @param {WhereInput} where - Filter criteria
* @returns {Promise<Item | null>} The found entity or null
*/
async findOne(ability, info, where) {
const select = this.service.fieldSelectionProvider.parseSelection(info);
return this.service.findOne(ability, where, select);
}
/**
* Query to find multiple entities matching criteria
*
* @param {any} ability - The user's ability for authorization
* @param {GraphQLResolveInfo} info - GraphQL resolve info for field selection
* @param {FindManyContract<WhereInput>} where - Filter and pagination criteria
* @returns {Promise<Item[]>} Array of matched entities
*/
async findMany(info, ability, where) {
const select = this.service.fieldSelectionProvider.parseSelection(info);
return this.service.findMany(ability, where || {}, select);
}
/**
* Mutation to create a new entity
*
* @param {GraphQLResolveInfo} info - GraphQL resolve info for field selection
* @param {CreateInput} args - The data to create the entity with
* @returns {Promise<Item>} The newly created entity
*/
async create(info, args) {
const select = this.service.fieldSelectionProvider.parseSelection(info);
return this.service.create(args, select);
}
/**
* Mutation to update a single entity by ID
*
* @param {any} ability - The user's ability for authorization
* @param {GraphQLResolveInfo} info - GraphQL resolve info for field selection
* @param {UpdateInput} data - The data to update
* @param {string} id - The ID of the entity to update
* @returns {Promise<Item>} The updated entity
*/
async updateOne(info, ability, data, id) {
const select = this.service.fieldSelectionProvider.parseSelection(info);
return this.service.update(ability, data, id, select);
}
/**
* Mutation to update multiple entities matching criteria
*
* @param {any} ability - The user's ability for authorization
* @param {GraphQLResolveInfo} info - GraphQL resolve info for field selection
* @param {UpdateManyInput} data - The data to update
* @param {WhereInput} where - Filter criteria for entities to update
* @returns {Promise<Item[]>} Array of updated entities
*/
async updateMany(info, ability, data, where) {
const select = this.service.fieldSelectionProvider.parseSelection(info);
return this.service.updateMany(ability, data, where, select);
}
/**
* Mutation to delete a single entity by ID
*
* @param {any} ability - The user's ability for authorization
* @param {GraphQLResolveInfo} info - GraphQL resolve info for field selection
* @param {string} id - The ID of the entity to delete
* @returns {Promise<Item>} The deleted entity
*/
async deleteOne(info, ability, id) {
const select = this.service.fieldSelectionProvider.parseSelection(info);
return this.service.delete(ability, id, select);
}
/**
* Mutation to delete multiple entities matching criteria
*
* @param {any} ability - The user's ability for authorization
* @param {GraphQLResolveInfo} info - GraphQL resolve info for field selection
* @param {WhereInput} where - Filter criteria for entities to delete
* @returns {Promise<Item[]>} Array of deleted entities
*/
async deleteMany(info, ability, where) {
const select = this.service.fieldSelectionProvider.parseSelection(info);
return this.service.deleteMany(ability, where, select);
}
/**
* Subscription to receive real-time updates for this entity type
*
* @param {any} where - Filter criteria for the subscription
*/
async [_a = `${options.modelName}s`](where) {
return this.pubSub.asyncIterableIterator(options.modelName);
}
};
__decorate([
(0, graphql_1.Query)(() => options.entity, {
name: `${options.modelName}FindOne`,
nullable: true,
}),
(0, authorizer_1.CanPerform)({
action: authorizer_1.Action.Read,
// @ts-ignore
resource: ModelName
}),
__param(0, authorizer_1.CurrentAbility.HTTP()),
__param(1, (0, graphql_1.Info)()),
__param(2, (0, graphql_1.Args)('where', { type: () => options.whereInput })),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, Object]),
__metadata("design:returntype", Promise)
], BaseCrudResolver.prototype, "findOne", null);
__decorate([
(0, graphql_1.Query)(() => [options.entity], {
name: `${options.modelName}FindMany`,
}),
(0, authorizer_1.CanPerform)({
action: authorizer_1.Action.Read,
// @ts-ignore
resource: ModelName
}),
__param(0, (0, graphql_1.Info)()),
__param(1, authorizer_1.CurrentAbility.HTTP()),
__param(2, (0, graphql_1.Args)('filter', { type: () => options.findManyArgs, nullable: true })),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, Object]),
__metadata("design:returntype", Promise)
], BaseCrudResolver.prototype, "findMany", null);
__decorate([
(0, graphql_1.Mutation)(() => options.entity, {
name: `${options.modelName}Create`,
}),
(0, authorizer_1.CanPerform)({
action: authorizer_1.Action.Create,
// @ts-ignore
resource: ModelName
}),
__param(0, (0, graphql_1.Info)()),
__param(1, (0, graphql_1.Args)('data', { type: () => options.createInput })),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object]),
__metadata("design:returntype", Promise)
], BaseCrudResolver.prototype, "create", null);
__decorate([
(0, graphql_1.Mutation)(() => options.entity, {
name: `${options.modelName}Update`,
}),
(0, authorizer_1.CanPerform)({
action: authorizer_1.Action.Update,
// @ts-ignore
resource: ModelName
}),
__param(0, (0, graphql_1.Info)()),
__param(1, authorizer_1.CurrentAbility.HTTP()),
__param(2, (0, graphql_1.Args)('data', { type: () => options.updateInput })),
__param(3, (0, graphql_1.Args)('id', { type: () => String })),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, Object, String]),
__metadata("design:returntype", Promise)
], BaseCrudResolver.prototype, "updateOne", null);
__decorate([
(0, graphql_1.Mutation)(() => [options.entity], {
name: `${options.modelName}UpdateMany`,
}),
(0, authorizer_1.CanPerform)({
action: authorizer_1.Action.Update,
// @ts-ignore
resource: ModelName
}),
__param(0, (0, graphql_1.Info)()),
__param(1, authorizer_1.CurrentAbility.HTTP()),
__param(2, (0, graphql_1.Args)('data', { type: () => options.updateManyInput })),
__param(3, (0, graphql_1.Args)('where', { type: () => options.whereInput })),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, Object, Object]),
__metadata("design:returntype", Promise)
], BaseCrudResolver.prototype, "updateMany", null);
__decorate([
(0, graphql_1.Mutation)(() => options.entity, {
name: `${options.modelName}Delete`,
}),
(0, authorizer_1.CanPerform)({
action: authorizer_1.Action.Delete,
// @ts-ignore
resource: ModelName
}),
__param(0, (0, graphql_1.Info)()),
__param(1, authorizer_1.CurrentAbility.HTTP()),
__param(2, (0, graphql_1.Args)('id', { type: () => String })),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String]),
__metadata("design:returntype", Promise)
], BaseCrudResolver.prototype, "deleteOne", null);
__decorate([
(0, graphql_1.Mutation)(() => [options.entity], {
name: `${options.modelName}DeleteMany`,
}),
(0, authorizer_1.CanPerform)({
action: authorizer_1.Action.Delete,
// @ts-ignore
resource: ModelName
}),
__param(0, (0, graphql_1.Info)()),
__param(1, authorizer_1.CurrentAbility.HTTP()),
__param(2, (0, graphql_1.Args)('where', { type: () => options.whereInput })),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, Object]),
__metadata("design:returntype", Promise)
], BaseCrudResolver.prototype, "deleteMany", null);
__decorate([
(0, graphql_1.Subscription)(() => [options.entity], {
// @ts-ignore
filter(payload, variables) {
return this.resolver.filter(variables.filter, payload.data);
},
// @ts-ignore
resolve(payload, variables, _ctx, info) {
return this.resolver.resolve(variables.filter, payload.data, info);
}
}),
__param(0, (0, graphql_1.Args)('filter', {
type: () => SubscriptionFilter,
nullable: true,
})),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", Promise)
], BaseCrudResolver.prototype, _a, null);
BaseCrudResolver = __decorate([
(0, graphql_1.Resolver)(() => options.entity),
__param(0, (0, common_1.Inject)(serviceToken)),
__param(1, (0, common_1.Inject)(resolverToken)),
__param(2, (0, decorators_1.CurrentPubSub)()),
__metadata("design:paramtypes", [Object, Object, graphql_subscriptions_1.PubSub])
], BaseCrudResolver);
// Give the dynamic class a descriptive name for easier debugging
Object.defineProperty(BaseCrudResolver, 'name', {
value: `${ModelName}Resolver`,
writable: false,
});
return BaseCrudResolver;
}
//# sourceMappingURL=createBaseCrudResolver.js.map