UNPKG

n8n-nodes-nextcloud-tables

Version:

Production-Ready n8n Node für Nextcloud Tables - Vollständige API-Abdeckung mit erweiterten Filtern, Multi-Column-Sorting, CSV-Import und professioneller Datenvalidierung

512 lines 23.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ColumnHandler = void 0; const api_helper_1 = require("../helpers/api.helper"); class ColumnHandler { static async execute(context, operation, itemIndex) { switch (operation) { case 'getAll': return this.getAll(context, itemIndex); case 'get': return this.get(context, itemIndex); case 'create': return this.create(context, itemIndex); case 'createAIFriendly': return this.createAIFriendly(context, itemIndex); case 'update': return this.update(context, itemIndex); case 'updateAIFriendly': return this.updateAIFriendly(context, itemIndex); case 'delete': return this.delete(context, itemIndex); default: throw new Error(`Unbekannte Operation: ${operation}`); } } /** * Alle Spalten einer Tabelle abrufen */ static async getAll(context, itemIndex) { const tableId = api_helper_1.ApiHelper.getResourceId(context.getNodeParameter('tableId', itemIndex)); return api_helper_1.ApiHelper.makeApiRequest(context, 'GET', `/tables/${tableId}/columns`); } /** * Eine spezifische Spalte abrufen */ static async get(context, itemIndex) { const columnId = api_helper_1.ApiHelper.getResourceId(context.getNodeParameter('columnId', itemIndex)); return api_helper_1.ApiHelper.makeApiRequest(context, 'GET', `/columns/${columnId}`); } /** * Eine neue Spalte erstellen */ static async create(context, itemIndex) { const tableId = api_helper_1.ApiHelper.getResourceId(context.getNodeParameter('tableId', itemIndex)); const type = context.getNodeParameter('type', itemIndex); const title = context.getNodeParameter('title', itemIndex); const description = context.getNodeParameter('description', itemIndex, ''); const mandatory = context.getNodeParameter('mandatory', itemIndex, false); const body = { type, title, mandatory, }; if (description) { body.description = description; } // Typ-spezifische Parameter hinzufügen switch (type) { case 'text': this.addTextParameters(context, itemIndex, body); break; case 'number': this.addNumberParameters(context, itemIndex, body); break; case 'datetime': this.addDateTimeParameters(context, itemIndex, body); break; case 'selection': this.addSelectionParameters(context, itemIndex, body); break; case 'usergroup': this.addUserGroupParameters(context, itemIndex, body); break; } // API v1 mit Query-Parametern verwenden (wie in Community-Lösung) return api_helper_1.ApiHelper.makeApiRequest(context, 'POST', `/tables/${tableId}/columns`, body, true); } /** * Eine neue Spalte erstellen (KI-Friendly Version) * Alle Parameter sind direkt verfügbar ohne verschachtelte Strukturen */ static async createAIFriendly(context, itemIndex) { const tableIdAI = context.getNodeParameter('tableIdAI', itemIndex, ''); // Validierung: tableIdAI ist für createAIFriendly erforderlich if (!tableIdAI) { throw new Error('tableIdAI ist für createAIFriendly Operation erforderlich'); } const tableId = api_helper_1.ApiHelper.getResourceId(tableIdAI); // Basis-Parameter direkt abrufen (alle immer verfügbar) const type = context.getNodeParameter('columnType', itemIndex); const title = context.getNodeParameter('columnTitle', itemIndex); const description = context.getNodeParameter('columnDescription', itemIndex, ''); const mandatory = context.getNodeParameter('columnMandatory', itemIndex, false); if (!type || !title) { throw new Error('Spaltentyp und Titel sind erforderlich'); } const body = { type, title, mandatory, }; if (description) { body.description = description; } // Typ-spezifische Parameter direkt aus den flachen Parametern hinzufügen // KI Agent kann alle Parameter sehen, aber nur die relevanten werden verwendet switch (type) { case 'text': this.addTextParametersAIFriendly(context, itemIndex, body); break; case 'number': this.addNumberParametersAIFriendly(context, itemIndex, body); break; case 'datetime': this.addDateTimeParametersAIFriendly(context, itemIndex, body); break; case 'selection': this.addSelectionParametersAIFriendly(context, itemIndex, body); break; case 'usergroup': this.addUserGroupParametersAIFriendly(context, itemIndex, body); break; } // API v1 mit Query-Parametern verwenden (wie in Community-Lösung) return api_helper_1.ApiHelper.makeApiRequest(context, 'POST', `/tables/${tableId}/columns`, body, true); } /** * Eine Spalte aktualisieren */ static async update(context, itemIndex) { const columnId = api_helper_1.ApiHelper.getResourceId(context.getNodeParameter('columnId', itemIndex)); const title = context.getNodeParameter('title', itemIndex, ''); const description = context.getNodeParameter('description', itemIndex, ''); const mandatory = context.getNodeParameter('mandatory', itemIndex); const body = {}; if (title) { body.title = title; } if (description !== undefined) { body.description = description; } if (mandatory !== undefined) { body.mandatory = mandatory; } // Nur aktualisieren, wenn es Änderungen gibt if (Object.keys(body).length === 0) { throw new Error('Mindestens ein Feld muss für die Aktualisierung angegeben werden'); } return api_helper_1.ApiHelper.makeApiRequest(context, 'PUT', `/columns/${columnId}`, body); } /** * Eine Spalte löschen */ static async delete(context, itemIndex) { const columnId = api_helper_1.ApiHelper.getResourceId(context.getNodeParameter('columnId', itemIndex)); await api_helper_1.ApiHelper.makeApiRequest(context, 'DELETE', `/columns/${columnId}`); return { success: true, message: `Spalte ${columnId} wurde erfolgreich gelöscht` }; } /** * Eine Spalte komplett aktualisieren (KI-Friendly Version) * Alle Parameter sind direkt verfügbar, KI kann Spalten-Typ und alle Eigenschaften ändern */ static async updateAIFriendly(context, itemIndex) { const columnIdAI = context.getNodeParameter('columnIdAI', itemIndex, ''); // Validierung: columnIdAI ist für updateAIFriendly erforderlich if (!columnIdAI) { throw new Error('columnIdAI ist für updateAIFriendly Operation erforderlich'); } const columnId = api_helper_1.ApiHelper.getResourceId(columnIdAI); // Basis-Parameter direkt abrufen (alle immer verfügbar) const type = context.getNodeParameter('columnType', itemIndex, ''); const title = context.getNodeParameter('columnTitle', itemIndex, ''); const description = context.getNodeParameter('columnDescription', itemIndex, ''); const mandatory = context.getNodeParameter('columnMandatory', itemIndex, false); const body = {}; // Nur setzen was wirklich angegeben wurde if (type) { body.type = type; } if (title) { body.title = title; } if (description !== undefined) { body.description = description; } if (mandatory !== undefined) { body.mandatory = mandatory; } // Typ-spezifische Parameter direkt aus den flachen Parametern hinzufügen // Aber nur wenn ein Typ gesetzt wurde if (type) { switch (type) { case 'text': this.addTextParametersAIFriendly(context, itemIndex, body); break; case 'number': this.addNumberParametersAIFriendly(context, itemIndex, body); break; case 'datetime': this.addDateTimeParametersAIFriendly(context, itemIndex, body); break; case 'selection': this.addSelectionParametersAIFriendly(context, itemIndex, body); break; case 'usergroup': this.addUserGroupParametersAIFriendly(context, itemIndex, body); break; } } // Verbesserte Validierung: Mindestens ein sinnvolles Feld muss für Update angegeben werden if (Object.keys(body).length === 0) { throw new Error('Mindestens ein Feld muss für die Aktualisierung angegeben werden (type, title, description, mandatory oder typ-spezifische Parameter)'); } // Zusätzliche Validierung: Bei Typ-Änderung sollte auch mindestens ein typ-spezifischer Parameter gesetzt werden if (type && !title && Object.keys(body).length === 1) { throw new Error('Bei einer Typ-Änderung sollte auch mindestens der Titel oder typ-spezifische Parameter angegeben werden'); } return api_helper_1.ApiHelper.makeApiRequest(context, 'PUT', `/columns/${columnId}`, body); } /** * Text-spezifische Parameter hinzufügen */ static addTextParameters(context, itemIndex, body) { // KRITISCH: subtype ist für Text-Spalten erforderlich! const subtype = context.getNodeParameter('subtype', itemIndex, 'line'); const textDefault = context.getNodeParameter('textDefault', itemIndex, ''); const textMaxLength = context.getNodeParameter('textMaxLength', itemIndex, null); const textAllowedPattern = context.getNodeParameter('textAllowedPattern', itemIndex, ''); // Subtype ist erforderlich für die API body.subtype = subtype; if (textDefault) { body.textDefault = textDefault; } if (textMaxLength && textMaxLength > 0) { body.textMaxLength = textMaxLength; } if (textAllowedPattern) { body.textAllowedPattern = textAllowedPattern; } } /** * Number-spezifische Parameter hinzufügen */ static addNumberParameters(context, itemIndex, body) { const numberDefault = context.getNodeParameter('numberDefault', itemIndex, null); const numberMin = context.getNodeParameter('numberMin', itemIndex, null); const numberMax = context.getNodeParameter('numberMax', itemIndex, null); const numberDecimals = context.getNodeParameter('numberDecimals', itemIndex, 0); const numberPrefix = context.getNodeParameter('numberPrefix', itemIndex, ''); const numberSuffix = context.getNodeParameter('numberSuffix', itemIndex, ''); if (numberDefault !== null) { body.numberDefault = numberDefault; } if (numberMin !== null) { body.numberMin = numberMin; } if (numberMax !== null) { body.numberMax = numberMax; } if (numberDecimals >= 0) { body.numberDecimals = numberDecimals; } if (numberPrefix) { body.numberPrefix = numberPrefix; } if (numberSuffix) { body.numberSuffix = numberSuffix; } } /** * DateTime-spezifische Parameter hinzufügen */ static addDateTimeParameters(context, itemIndex, body) { const datetimeDefault = context.getNodeParameter('datetimeDefault', itemIndex, ''); if (datetimeDefault) { body.datetimeDefault = datetimeDefault; } } /** * Selection-spezifische Parameter hinzufügen */ static addSelectionParameters(context, itemIndex, body) { const selectionOptions = context.getNodeParameter('selectionOptions', itemIndex, ''); const selectionDefault = context.getNodeParameter('selectionDefault', itemIndex, ''); if (selectionOptions) { // Optionen in Format konvertieren: Zeilen in JSON-Array const options = selectionOptions.split('\n').filter(line => line.trim() !== ''); body.selectionOptions = JSON.stringify(options); } if (selectionDefault) { body.selectionDefault = selectionDefault; } } /** * UserGroup-spezifische Parameter hinzufügen */ static addUserGroupParameters(context, itemIndex, body) { const usergroupDefault = context.getNodeParameter('usergroupDefault', itemIndex, ''); const usergroupMultipleItems = context.getNodeParameter('usergroupMultipleItems', itemIndex, false); const usergroupSelectUsers = context.getNodeParameter('usergroupSelectUsers', itemIndex, true); const usergroupSelectGroups = context.getNodeParameter('usergroupSelectGroups', itemIndex, true); const usergroupSelectTeams = context.getNodeParameter('usergroupSelectTeams', itemIndex, false); const showUserStatus = context.getNodeParameter('showUserStatus', itemIndex, false); if (usergroupDefault) { body.usergroupDefault = usergroupDefault; } body.usergroupMultipleItems = usergroupMultipleItems; body.usergroupSelectUsers = usergroupSelectUsers; body.usergroupSelectGroups = usergroupSelectGroups; body.usergroupSelectTeams = usergroupSelectTeams; body.showUserStatus = showUserStatus; } /** * Text-spezifische Parameter aus fixedCollection extrahieren */ static addTextParametersFromConfig(context, itemIndex, body) { const textConfig = context.getNodeParameter('textConfig.settings', itemIndex, {}); // Subtype ist erforderlich für die API body.subtype = textConfig.subtype || 'line'; if (textConfig.textDefault) { body.textDefault = textConfig.textDefault; } if (textConfig.textMaxLength && textConfig.textMaxLength > 0) { body.textMaxLength = textConfig.textMaxLength; } if (textConfig.textAllowedPattern) { body.textAllowedPattern = textConfig.textAllowedPattern; } } /** * Number-spezifische Parameter aus fixedCollection extrahieren */ static addNumberParametersFromConfig(context, itemIndex, body) { const numberConfig = context.getNodeParameter('numberConfig.settings', itemIndex, {}); if (numberConfig.numberDefault !== undefined && numberConfig.numberDefault !== null) { body.numberDefault = numberConfig.numberDefault; } if (numberConfig.numberMin !== undefined && numberConfig.numberMin !== null) { body.numberMin = numberConfig.numberMin; } if (numberConfig.numberMax !== undefined && numberConfig.numberMax !== null) { body.numberMax = numberConfig.numberMax; } if (numberConfig.numberDecimals !== undefined && numberConfig.numberDecimals >= 0) { body.numberDecimals = numberConfig.numberDecimals; } if (numberConfig.numberPrefix) { body.numberPrefix = numberConfig.numberPrefix; } if (numberConfig.numberSuffix) { body.numberSuffix = numberConfig.numberSuffix; } } /** * DateTime-spezifische Parameter aus fixedCollection extrahieren */ static addDateTimeParametersFromConfig(context, itemIndex, body) { const datetimeConfig = context.getNodeParameter('datetimeConfig.settings', itemIndex, {}); if (datetimeConfig.datetimeDefault) { body.datetimeDefault = datetimeConfig.datetimeDefault; } } /** * Selection-spezifische Parameter aus fixedCollection extrahieren */ static addSelectionParametersFromConfig(context, itemIndex, body) { const selectionConfig = context.getNodeParameter('selectionConfig.settings', itemIndex, {}); if (selectionConfig.selectionOptions) { // Optionen in Format konvertieren: Zeilen in JSON-Array const options = selectionConfig.selectionOptions.split('\n').filter((line) => line.trim() !== ''); body.selectionOptions = JSON.stringify(options); } if (selectionConfig.selectionDefault) { body.selectionDefault = selectionConfig.selectionDefault; } } /** * UserGroup-spezifische Parameter aus fixedCollection extrahieren */ static addUserGroupParametersFromConfig(context, itemIndex, body) { const usergroupConfig = context.getNodeParameter('usergroupConfig.settings', itemIndex, {}); if (usergroupConfig.usergroupDefault) { body.usergroupDefault = usergroupConfig.usergroupDefault; } body.usergroupMultipleItems = usergroupConfig.usergroupMultipleItems || false; body.usergroupSelectUsers = usergroupConfig.usergroupSelectUsers !== undefined ? usergroupConfig.usergroupSelectUsers : true; body.usergroupSelectGroups = usergroupConfig.usergroupSelectGroups !== undefined ? usergroupConfig.usergroupSelectGroups : true; body.usergroupSelectTeams = usergroupConfig.usergroupSelectTeams || false; body.showUserStatus = usergroupConfig.showUserStatus || false; } // ======================================================= // AI-FRIENDLY Parameter-Methoden (flache Struktur) // ======================================================= /** * Text-spezifische Parameter für AI-Friendly Version (flache Parameter) */ static addTextParametersAIFriendly(context, itemIndex, body) { const subtype = context.getNodeParameter('textSubtypeAI', itemIndex, 'line'); const textDefault = context.getNodeParameter('textDefaultAI', itemIndex, ''); const textMaxLength = context.getNodeParameter('textMaxLengthAI', itemIndex, 255); const textPattern = context.getNodeParameter('textPatternAI', itemIndex, ''); // Subtype ist erforderlich für die API body.subtype = subtype; if (textDefault) { body.textDefault = textDefault; } if (textMaxLength && textMaxLength > 0) { body.textMaxLength = textMaxLength; } if (textPattern) { body.textAllowedPattern = textPattern; } } /** * Number-spezifische Parameter für AI-Friendly Version (flache Parameter) */ static addNumberParametersAIFriendly(context, itemIndex, body) { const numberDefault = context.getNodeParameter('numberDefaultAI', itemIndex, 0); const numberMin = context.getNodeParameter('numberMinAI', itemIndex, null); const numberMax = context.getNodeParameter('numberMaxAI', itemIndex, null); const numberDecimals = context.getNodeParameter('numberDecimalsAI', itemIndex, 0); const numberPrefix = context.getNodeParameter('numberPrefixAI', itemIndex, ''); const numberSuffix = context.getNodeParameter('numberSuffixAI', itemIndex, ''); if (numberDefault !== undefined && numberDefault !== null) { body.numberDefault = numberDefault; } if (numberMin !== undefined && numberMin !== null) { body.numberMin = numberMin; } if (numberMax !== undefined && numberMax !== null) { body.numberMax = numberMax; } if (numberDecimals !== undefined && numberDecimals >= 0) { body.numberDecimals = numberDecimals; } if (numberPrefix) { body.numberPrefix = numberPrefix; } if (numberSuffix) { body.numberSuffix = numberSuffix; } } /** * DateTime-spezifische Parameter für AI-Friendly Version (flache Parameter) */ static addDateTimeParametersAIFriendly(context, itemIndex, body) { const datetimeDefault = context.getNodeParameter('datetimeDefaultAI', itemIndex, ''); if (datetimeDefault) { body.datetimeDefault = datetimeDefault; } } /** * Selection-spezifische Parameter für AI-Friendly Version (flache Parameter) */ static addSelectionParametersAIFriendly(context, itemIndex, body) { const selectionOptions = context.getNodeParameter('selectionOptionsAI', itemIndex, ''); const selectionDefault = context.getNodeParameter('selectionDefaultAI', itemIndex, ''); const selectionMultiple = context.getNodeParameter('selectionMultipleAI', itemIndex, false); if (selectionOptions) { try { // KI Agent gibt JSON-Array als String const options = JSON.parse(selectionOptions); if (Array.isArray(options)) { body.selectionOptions = JSON.stringify(options); } else { throw new Error('selectionOptionsAI muss ein JSON-Array sein'); } } catch (error) { throw new Error(`Ungültiges JSON in selectionOptionsAI: ${error.message}`); } } if (selectionDefault) { body.selectionDefault = selectionDefault; } if (selectionMultiple !== undefined) { body.selectionMultiple = selectionMultiple; } } /** * UserGroup-spezifische Parameter für AI-Friendly Version (flache Parameter) */ static addUserGroupParametersAIFriendly(context, itemIndex, body) { const usergroupType = context.getNodeParameter('usergroupTypeAI', itemIndex, 'user'); const usergroupDefault = context.getNodeParameter('usergroupDefaultAI', itemIndex, ''); const usergroupMultiple = context.getNodeParameter('usergroupMultipleAI', itemIndex, false); if (usergroupDefault) { body.usergroupDefault = usergroupDefault; } // Basierend auf usergroupType die entsprechenden Flags setzen body.usergroupMultipleItems = usergroupMultiple; if (usergroupType === 'user') { body.usergroupSelectUsers = true; body.usergroupSelectGroups = false; } else if (usergroupType === 'group') { body.usergroupSelectUsers = false; body.usergroupSelectGroups = true; } else { // Fallback: beide erlauben body.usergroupSelectUsers = true; body.usergroupSelectGroups = true; } // Standardwerte für andere Optionen body.usergroupSelectTeams = false; body.showUserStatus = false; } } exports.ColumnHandler = ColumnHandler; //# sourceMappingURL=column.handler.js.map