n8n-nodes-sevdesk-v2
Version:
n8n community node for SevDesk API v2 integration with 24 production-ready workflow templates. Direct API access without external dependencies - simplified, secure, and optimized for German accounting automation (n8n 1.101.1 compatible).
191 lines (190 loc) • 7.82 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.BatchOperationUtils = exports.BatchOperationHandler = void 0;
const ResourceDependencyResolver_1 = require("../dependencies/ResourceDependencyResolver");
class BatchOperationHandler {
constructor(executeFunctions) {
this.resourceHandlers = new Map();
this.executeFunctions = executeFunctions;
}
registerResourceHandler(resource, handler) {
this.resourceHandlers.set(resource, handler);
}
async executeBatch(batchRequest) {
const startTime = Date.now();
const results = [];
const options = {
continueOnError: true,
maxConcurrency: 5,
timeout: 30000,
...batchRequest.options
};
this.validateBatchRequest(batchRequest);
const operationContexts = batchRequest.operations.map((operation, index) => ({
resource: operation.resource,
operation: operation.operation,
data: operation.data || {},
index,
id: operation.id,
dependencies: operation.parameters?.dependencies || undefined
}));
const dependencyResult = ResourceDependencyResolver_1.ResourceDependencyResolver.resolveDependencies(operationContexts);
if (!dependencyResult.isValid) {
throw new Error(`Dependency resolution failed: ${dependencyResult.errors.join(', ')}`);
}
const executionResults = new Map();
for (const orderedOp of dependencyResult.executionOrder) {
try {
const originalOperation = batchRequest.operations[orderedOp.index];
const dependenciesSatisfied = this.checkDependenciesSatisfied(orderedOp, executionResults);
if (!dependenciesSatisfied && !options.continueOnError) {
throw new Error(`Dependencies not satisfied for ${orderedOp.resource}:${orderedOp.operation}`);
}
const result = await this.executeOperation(originalOperation, orderedOp.index);
executionResults.set(orderedOp.index, result);
results.push({
operation: originalOperation,
success: true,
data: result
});
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
const originalOperation = batchRequest.operations[orderedOp.index];
results.push({
operation: originalOperation,
success: false,
error: errorMessage
});
if (!options.continueOnError) {
throw error;
}
}
}
const endTime = Date.now();
const successful = results.filter(r => r.success).length;
const failed = results.filter(r => !r.success).length;
return {
success: failed === 0,
results,
summary: {
total: results.length,
successful,
failed,
executionTime: endTime - startTime
}
};
}
async executeOperation(operation, itemIndex) {
const handler = this.resourceHandlers.get(operation.resource);
if (!handler) {
throw new Error(`No handler registered for resource: ${operation.resource}`);
}
this.setupMockParameters(operation, itemIndex);
const result = await handler.execute(operation.operation, itemIndex);
return result?.json || result;
}
setupMockParameters(operation, itemIndex) {
const originalGetNodeParameter = this.executeFunctions.getNodeParameter;
this.executeFunctions.getNodeParameter = (parameterName, index, defaultValue) => {
if (operation.parameters && operation.parameters[parameterName] !== undefined) {
return operation.parameters[parameterName];
}
switch (parameterName) {
case 'additionalFields':
return operation.data || defaultValue || {};
case `${operation.resource.toLowerCase()}Id`:
return operation.id || defaultValue;
default:
return originalGetNodeParameter.call(this.executeFunctions, parameterName, index, defaultValue);
}
};
}
checkDependenciesSatisfied(operation, executionResults) {
if (!operation.dependencies || operation.dependencies.length === 0) {
return true;
}
return operation.dependencies.every(dep => {
const [, , depIndexStr] = dep.split(':');
const depIndex = parseInt(depIndexStr);
return executionResults.has(depIndex) && executionResults.get(depIndex) !== null;
});
}
validateBatchRequest(batchRequest) {
if (!batchRequest.operations || !Array.isArray(batchRequest.operations)) {
throw new Error('Batch request must contain an array of operations');
}
if (batchRequest.operations.length === 0) {
throw new Error('Batch request must contain at least one operation');
}
if (batchRequest.operations.length > 100) {
throw new Error('Batch request cannot contain more than 100 operations');
}
batchRequest.operations.forEach((operation, index) => {
if (!operation.resource || !operation.operation) {
throw new Error(`Operation at index ${index} must have resource and operation properties`);
}
if (!this.resourceHandlers.has(operation.resource)) {
throw new Error(`No handler registered for resource: ${operation.resource} at index ${index}`);
}
});
}
static createBatchOperation(resource, operation, data, id, parameters) {
return {
resource,
operation,
data,
id,
parameters
};
}
static createBatchRequest(operations, options) {
return {
operations,
options: {
continueOnError: true,
maxConcurrency: 5,
timeout: 30000,
...options
}
};
}
}
exports.BatchOperationHandler = BatchOperationHandler;
class BatchOperationUtils {
static groupOperationsByResource(operations) {
const grouped = new Map();
operations.forEach(operation => {
const existing = grouped.get(operation.resource) || [];
existing.push(operation);
grouped.set(operation.resource, existing);
});
return grouped;
}
static chunkOperations(operations, chunkSize = 50) {
const chunks = [];
for (let i = 0; i < operations.length; i += chunkSize) {
chunks.push(operations.slice(i, i + chunkSize));
}
return chunks;
}
static validateOperationCompatibility(operations) {
const resourceOperations = new Map();
operations.forEach(operation => {
const key = `${operation.resource}:${operation.id || 'new'}`;
const ops = resourceOperations.get(key) || new Set();
ops.add(operation.operation);
resourceOperations.set(key, ops);
});
for (const [, ops] of resourceOperations) {
if (ops.has('create') && ops.has('delete')) {
return false;
}
if (ops.has('update') && ops.has('delete')) {
return false;
}
}
return true;
}
}
exports.BatchOperationUtils = BatchOperationUtils;