UNPKG

n8n

Version:

n8n Workflow Automation Tool

237 lines 11.2 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); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.RoleMappingRuleService = void 0; const db_1 = require("@n8n/db"); const di_1 = require("@n8n/di"); const typeorm_1 = require("@n8n/typeorm"); const bad_request_error_1 = require("../../errors/response-errors/bad-request.error"); const conflict_error_1 = require("../../errors/response-errors/conflict.error"); const not_found_error_1 = require("../../errors/response-errors/not-found.error"); const role_mapping_rule_validation_1 = require("./role-mapping-rule.validation"); let RoleMappingRuleService = class RoleMappingRuleService { constructor(roleMappingRuleRepository, roleRepository, projectRepository) { this.roleMappingRuleRepository = roleMappingRuleRepository; this.roleRepository = roleRepository; this.projectRepository = projectRepository; } async list(query) { const sortBy = query.sortBy ?? 'order:asc'; const [sortField, sortDir] = sortBy.split(':'); const direction = sortDir === 'desc' ? 'DESC' : 'ASC'; const order = sortField === 'createdAt' ? { createdAt: direction, id: 'ASC' } : sortField === 'updatedAt' ? { updatedAt: direction, id: 'ASC' } : { order: direction, id: 'ASC' }; const where = query.type ? { type: query.type } : {}; const [entities, count] = await this.roleMappingRuleRepository.findAndCount({ where, relations: ['projects', 'role'], order, skip: query.skip, take: query.take, }); return { count, items: entities.map((entity) => this.toResponse(entity)), }; } async create(dto) { const uniqueProjectIds = (0, role_mapping_rule_validation_1.assertAndNormalizeProjectIdsForRuleType)(dto.type, dto.projectIds, []); const role = await this.roleRepository.findOne({ where: { slug: dto.role } }); if (!role) { throw new not_found_error_1.NotFoundError(`Could not find role with slug "${dto.role}"`); } (0, role_mapping_rule_validation_1.assertRoleCompatibleWithMappingType)(role, dto.type); const projects = uniqueProjectIds.length > 0 ? await this.projectRepository.findBy({ id: (0, typeorm_1.In)(uniqueProjectIds) }) : []; if (projects.length !== uniqueProjectIds.length) { throw new bad_request_error_1.BadRequestError('One or more projects were not found'); } const existingRules = await this.roleMappingRuleRepository.find({ where: { type: dto.type }, select: ['id', 'order'], order: { order: 'ASC' }, }); const requestedOrder = dto.order ?? existingRules.length; const targetIndex = Math.min(Math.max(requestedOrder, 0), existingRules.length); const maxOrder = existingRules.length > 0 ? existingRules[existingRules.length - 1].order : -1; const tempOrder = Math.max(maxOrder, existingRules.length - 1) + 1; const rule = new db_1.RoleMappingRule(); rule.expression = dto.expression; rule.role = role; rule.type = dto.type; rule.order = tempOrder; rule.projects = projects; const saved = await this.roleMappingRuleRepository.save(rule); const reorderedIds = existingRules.map((r) => r.id); reorderedIds.splice(targetIndex, 0, saved.id); await this.applyOrder(reorderedIds); const loaded = await this.roleMappingRuleRepository.findOneOrFail({ where: { id: saved.id }, relations: ['projects', 'role'], }); return this.toResponse(loaded); } async patch(id, dto) { if (typeof id !== 'string' || id.length === 0) { throw new bad_request_error_1.BadRequestError('Rule id is required'); } if (dto === undefined || dto === null || Object.keys(dto).length === 0) { throw new bad_request_error_1.BadRequestError('At least one field is required'); } const rule = await this.roleMappingRuleRepository.findOne({ where: { id }, relations: ['projects', 'role'], }); if (!rule) { throw new not_found_error_1.NotFoundError('Could not find role mapping rule'); } const originalType = rule.type; const mergedType = dto.type ?? originalType; const mergedOrder = dto.order ?? rule.order; const mergedExpression = dto.expression ?? rule.expression; const mergedRoleSlug = dto.role ?? rule.role.slug; const fallbackProjectIds = rule.projects.map((p) => p.id); const uniqueProjectIds = (0, role_mapping_rule_validation_1.assertAndNormalizeProjectIdsForRuleType)(mergedType, dto.projectIds, fallbackProjectIds); const role = mergedRoleSlug === rule.role.slug ? rule.role : await this.roleRepository.findOne({ where: { slug: mergedRoleSlug } }); if (!role) { throw new not_found_error_1.NotFoundError(`Could not find role with slug "${mergedRoleSlug}"`); } (0, role_mapping_rule_validation_1.assertRoleCompatibleWithMappingType)(role, mergedType); await this.assertOrderAvailable(mergedType, mergedOrder, id); const projects = uniqueProjectIds.length > 0 ? await this.projectRepository.findBy({ id: (0, typeorm_1.In)(uniqueProjectIds) }) : []; if (projects.length !== uniqueProjectIds.length) { throw new bad_request_error_1.BadRequestError('One or more projects were not found'); } rule.expression = mergedExpression; rule.role = role; rule.type = mergedType; rule.order = mergedOrder; rule.projects = projects; await this.roleMappingRuleRepository.save(rule); await this.normalizeOrderForType(mergedType); if (originalType !== mergedType) { await this.normalizeOrderForType(originalType); } const loaded = await this.roleMappingRuleRepository.findOneOrFail({ where: { id: rule.id }, relations: ['projects', 'role'], }); return this.toResponse(loaded); } async delete(id) { if (typeof id !== 'string' || id.length === 0) { throw new bad_request_error_1.BadRequestError('Rule id is required'); } const rule = await this.roleMappingRuleRepository.findOne({ where: { id } }); if (!rule) { throw new not_found_error_1.NotFoundError('Could not find role mapping rule'); } const ruleType = rule.type; await this.roleMappingRuleRepository.remove(rule); await this.normalizeOrderForType(ruleType); return { ruleType }; } async deleteAllOfType(type, tx) { const repo = tx ? tx.getRepository(db_1.RoleMappingRule) : this.roleMappingRuleRepository; const result = await repo.delete({ type }); return result.affected ?? 0; } async move(id, targetIndex) { if (typeof id !== 'string' || id.length === 0) { throw new bad_request_error_1.BadRequestError('Rule id is required'); } const rule = await this.roleMappingRuleRepository.findOne({ where: { id }, relations: ['projects', 'role'], }); if (!rule) { throw new not_found_error_1.NotFoundError('Could not find role mapping rule'); } const type = rule.type; const all = await this.roleMappingRuleRepository.find({ where: { type }, select: ['id', 'order'], order: { order: 'ASC' }, }); const clampedIndex = Math.min(targetIndex, all.length - 1); const currentIndex = all.findIndex((r) => r.id === id); const reordered = [...all]; reordered.splice(currentIndex, 1); reordered.splice(clampedIndex, 0, all[currentIndex]); await this.applyOrder(reordered.map((r) => r.id)); const loaded = await this.roleMappingRuleRepository.findOneOrFail({ where: { id }, relations: ['projects', 'role'], }); return this.toResponse(loaded); } async applyOrder(orderedIds) { if (orderedIds.length === 0) return; await this.roleMappingRuleRepository.manager.transaction(async (tx) => { const offset = orderedIds.length + 1000; for (let i = 0; i < orderedIds.length; i++) { await tx.update(db_1.RoleMappingRule, { id: orderedIds[i] }, { order: offset + i }); } for (let i = 0; i < orderedIds.length; i++) { await tx.update(db_1.RoleMappingRule, { id: orderedIds[i] }, { order: i }); } }); } async normalizeOrderForType(type) { const rules = await this.roleMappingRuleRepository.find({ where: { type }, select: ['id', 'order'], order: { order: 'ASC' }, }); if (rules.length === 0) return; if (rules.every((r, i) => r.order === i)) return; await this.applyOrder(rules.map((r) => r.id)); } async assertOrderAvailable(type, order, excludeRuleId) { const existingAtOrder = await this.roleMappingRuleRepository.findOne({ where: { type, order }, }); if (existingAtOrder && existingAtOrder.id !== excludeRuleId) { throw new conflict_error_1.ConflictError(`A role mapping rule already exists with type "${type}" and order ${order}. Use a different order value.`); } } toResponse(loaded) { return { id: loaded.id, expression: loaded.expression, role: loaded.role.slug, type: loaded.type, order: loaded.order, projectIds: loaded.projects.map((p) => p.id), createdAt: loaded.createdAt.toISOString(), updatedAt: loaded.updatedAt.toISOString(), }; } }; exports.RoleMappingRuleService = RoleMappingRuleService; exports.RoleMappingRuleService = RoleMappingRuleService = __decorate([ (0, di_1.Service)(), __metadata("design:paramtypes", [db_1.RoleMappingRuleRepository, db_1.RoleRepository, db_1.ProjectRepository]) ], RoleMappingRuleService); //# sourceMappingURL=role-mapping-rule.service.ee.js.map