n8n
Version:
n8n Workflow Automation Tool
133 lines • 7.07 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);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DataTableImporter = void 0;
const backend_common_1 = require("@n8n/backend-common");
const di_1 = require("@n8n/di");
const n8n_workflow_1 = require("n8n-workflow");
const forbidden_error_1 = require("../../../../errors/response-errors/forbidden.error");
const data_table_service_1 = require("../../../../modules/data-table/data-table.service");
const check_access_1 = require("../../../../permissions.ee/check-access");
const data_table_matching_mode_1 = require("./data-table-matching-mode");
const data_table_missing_mode_1 = require("./data-table-missing-mode");
const data_table_schema_conflict_policy_1 = require("./data-table-schema-conflict-policy");
const data_table_types_1 = require("./data-table.types");
let DataTableImporter = class DataTableImporter {
constructor(dataTableService, moduleRegistry) {
this.dataTableService = dataTableService;
this.moduleRegistry = moduleRegistry;
}
async plan(context, request) {
const requirements = request.requirements ?? [];
if (requirements.length === 0)
return { creations: [], failures: [], matchedCount: 0 };
if (!this.moduleRegistry.isActive('data-table')) {
return {
creations: [],
failures: [{ kind: 'module-disabled', usedByWorkflows: workflowsUsing(requirements) }],
matchedCount: 0,
};
}
const packageTablesById = new Map(request.packageDataTables.map((table) => [table.id, table]));
const targets = await this.dataTableService.findDataTablesByIds(requirements.map(({ id }) => id));
const targetsById = new Map(targets.map((table) => [table.id, table]));
const candidates = { projectId: context.projectId, targetsById };
const creations = [];
const failures = [];
let matchedCount = 0;
for (const requirement of requirements) {
const packageTable = packageTablesById.get(requirement.id);
if (!packageTable) {
throw new n8n_workflow_1.UserError(`Package is missing the data table schema for "${requirement.name}" (${requirement.id}).`);
}
const matchedTargetTable = (0, data_table_matching_mode_1.matchTargetTable)(request.matchingMode, requirement, candidates);
const effect = resolveRequirement(requirement, packageTable, matchedTargetTable, targetsById.get(requirement.id), request.missingMode, request.schemaConflictPolicy);
if (effect.action === 'create')
creations.push({ table: packageTable, requirement });
else if (effect.action === 'fail')
failures.push(effect.failure);
else if (matchedTargetTable)
matchedCount++;
}
failures.push(...(await this.creationFailures(context, creations)));
return { creations: creations.map(({ table }) => table), failures, matchedCount };
}
async apply(context, plan) {
if (plan.creations.length === 0)
return;
if (!(await (0, check_access_1.userHasScopes)(context.user, ['dataTable:create'], false, {
projectId: context.projectId,
}))) {
throw new forbidden_error_1.ForbiddenError('User is missing a scope required to create a data table');
}
for (const table of plan.creations) {
await this.dataTableService.createDataTable(context.projectId, { name: table.name, columns: table.columns }, table.id);
}
}
async creationFailures(context, creations) {
if (creations.length === 0)
return [];
const failures = [];
const canCreate = await (0, check_access_1.userHasScopes)(context.user, ['dataTable:create'], false, {
projectId: context.projectId,
});
if (!canCreate) {
failures.push({
kind: 'permission-denied',
usedByWorkflows: workflowsUsing(creations.map(({ requirement }) => requirement)),
});
}
const existingByName = new Map((await this.dataTableService.findDataTablesByNamesInProject(context.projectId, creations.map(({ table }) => table.name))).map((table) => [table.name, table]));
const packageTablesPerName = new Map();
for (const { table } of creations) {
packageTablesPerName.set(table.name, (packageTablesPerName.get(table.name) ?? 0) + 1);
}
for (const { table, requirement } of creations) {
if (existingByName.has(table.name) || packageTablesPerName.get(table.name) > 1) {
failures.push((0, data_table_types_1.createFailure)(requirement, 'name-conflict'));
}
}
return failures;
}
};
exports.DataTableImporter = DataTableImporter;
exports.DataTableImporter = DataTableImporter = __decorate([
(0, di_1.Service)(),
__metadata("design:paramtypes", [data_table_service_1.DataTableService, backend_common_1.ModuleRegistry])
], DataTableImporter);
function resolveRequirement(requirement, packageTable, matchedTargetTable, existingTableWithSameId, missingMode, schemaConflictPolicy) {
if (matchedTargetTable) {
const incompatibility = (0, data_table_schema_conflict_policy_1.findSchemaConflict)(schemaConflictPolicy, packageTable.columns, matchedTargetTable.columns);
if (incompatibility) {
return {
action: 'fail',
failure: (0, data_table_types_1.createFailure)(requirement, 'schema-incompatible', incompatibility),
};
}
return { action: 'skip' };
}
const effect = (0, data_table_missing_mode_1.decideAbsentTable)(missingMode, requirement);
if (effect.action !== 'create')
return effect;
if (existingTableWithSameId) {
return {
action: 'fail',
failure: (0, data_table_types_1.createFailure)(requirement, 'id-conflict', {
existingProjectId: existingTableWithSameId.projectId,
}),
};
}
return effect;
}
function workflowsUsing(requirements) {
return [...new Set(requirements.flatMap(({ usedByWorkflows }) => usedByWorkflows))].sort();
}
//# sourceMappingURL=data-table-importer.js.map