UNPKG

@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
"use strict"; 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