n8n-workflow-builder-mcp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cursor/rules/cursor_rules.mdc +53 -0
- package/.cursor/rules/dev_workflow.mdc +219 -0
- package/.cursor/rules/mcp.mdc +430 -0
- package/.cursor/rules/self_improve.mdc +72 -0
- package/.cursor/rules/taskmaster.mdc +382 -0
- package/.cursorignore +1 -0
- package/.cursorrules +4 -0
- package/.env.example +23 -0
- package/.eslintrc.json +38 -0
- package/.github/workflows/npm-publish-github-packages.yml +55 -0
- package/.prettierrc +9 -0
- package/.roo/rules/dev_workflow.md +219 -0
- package/.roo/rules/mcp.md +430 -0
- package/.roo/rules/roo_rules.md +53 -0
- package/.roo/rules/self_improve.md +72 -0
- package/.roo/rules/taskmaster.md +382 -0
- package/.roo/rules-architect/architect-rules +93 -0
- package/.roo/rules-ask/ask-rules +89 -0
- package/.roo/rules-boomerang/boomerang-rules +181 -0
- package/.roo/rules-code/code-rules +61 -0
- package/.roo/rules-debug/debug-rules +68 -0
- package/.roo/rules-test/test-rules +61 -0
- package/.roomodes +63 -0
- package/.taskmasterconfig +31 -0
- package/.windsurfrules +2382 -0
- package/LICENSE +21 -0
- package/README.md +210 -0
- package/config/credentials/credentials.json +1 -0
- package/config/default.js +41 -0
- package/package.json +56 -0
- package/scripts/demo-n8n-integration.js +161 -0
- package/scripts/demo-workflow-generator.js +102 -0
- package/scripts/init.sh +36 -0
- package/scripts/prd.txt +197 -0
- package/src/index.ts +1440 -0
- package/src/middleware/auth.js +273 -0
- package/src/middleware/authorize.js +183 -0
- package/src/middleware/logging.js +64 -0
- package/src/middleware/mcp.js +187 -0
- package/src/middleware/rateLimiter.js +82 -0
- package/src/middleware/validation.js +241 -0
- package/src/models/credential.js +359 -0
- package/src/models/llmService.js +236 -0
- package/src/models/n8nIntegration.js +542 -0
- package/src/models/storage.js +196 -0
- package/src/models/tool.js +148 -0
- package/src/models/user.js +164 -0
- package/src/models/workflow.js +229 -0
- package/src/routes/toolDefinitions.js +62 -0
- package/src/routes/toolExecution.js +79 -0
- package/src/tools/__index.js +242 -0
- package/src/tools/connectionManagement.js +500 -0
- package/src/tools/n8nIntegration.js +370 -0
- package/src/tools/nodeDiscovery.js +488 -0
- package/src/tools/nodeManagement.js +674 -0
- package/src/tools/toolDefinitions.js +660 -0
- package/src/tools/workflowCreation.js +100 -0
- package/src/tools/workflowGenerator.js +152 -0
- package/src/tools/workflowStorage.js +113 -0
- package/src/tools/workflowTesting.js +285 -0
- package/src/utils/encryption.js +164 -0
- package/src/utils/logger.js +84 -0
- package/src/utils/mcp.js +85 -0
- package/src/utils/securityLogger.js +109 -0
- package/tests/auth.test.js +402 -0
- package/tests/authorize.test.js +208 -0
- package/tests/run-memory-tests.js +55 -0
- package/tests/run-tests.js +55 -0
- package/tests/server.test.js +203 -0
- package/tests/unit/add-ai-connections.test.js +385 -0
- package/tests/unit/connectionManagement.test.js +309 -0
- package/tests/unit/langchain-llm-format.test.js +259 -0
- package/tests/unit/memory-connection.test.js +140 -0
- package/tests/unit/memory-integration.test.js +253 -0
- package/tests/unit/n8nIntegration.test.js +291 -0
- package/tests/unit/nodeDiscovery.test.js +270 -0
- package/tests/unit/nodeManagement.test.js +522 -0
- package/tests/unit/utils/mcp-test-utils.js +94 -0
- package/tests/unit/workflowCreation.test.js +110 -0
- package/tests/unit/workflowTesting.test.js +269 -0
- package/tests/user.test.js +181 -0
- package/tsconfig.json +20 -0
- package/workflow_nodes/Brandfetch.json +85 -0
- package/workflow_nodes/WorkflowTrigger.json +28 -0
- package/workflow_nodes/actionNetwork.json +218 -0
- package/workflow_nodes/activeCampaign.json +722 -0
- package/workflow_nodes/activeCampaignTrigger.json +52 -0
- package/workflow_nodes/acuitySchedulingTrigger.json +8 -0
- package/workflow_nodes/adalo.json +123 -0
- package/workflow_nodes/affinity.json +203 -0
- package/workflow_nodes/affinityTrigger.json +124 -0
- package/workflow_nodes/aggregate.json +119 -0
- package/workflow_nodes/agileCrm.json +503 -0
- package/workflow_nodes/aiTransform.json +17 -0
- package/workflow_nodes/airtable.json +226 -0
- package/workflow_nodes/airtableTrigger.json +120 -0
- package/workflow_nodes/airtop.json +10 -0
- package/workflow_nodes/amqp.json +62 -0
- package/workflow_nodes/amqpTrigger.json +8 -0
- package/workflow_nodes/apiTemplateIo.json +147 -0
- package/workflow_nodes/asana.json +446 -0
- package/workflow_nodes/asanaTrigger.json +52 -0
- package/workflow_nodes/automizy.json +195 -0
- package/workflow_nodes/autopilot.json +287 -0
- package/workflow_nodes/autopilotTrigger.json +8 -0
- package/workflow_nodes/awsCertificateManager.json +223 -0
- package/workflow_nodes/awsComprehend.json +125 -0
- package/workflow_nodes/awsDynamoDb.json +251 -0
- package/workflow_nodes/awsElb.json +174 -0
- package/workflow_nodes/awsLambda.json +69 -0
- package/workflow_nodes/awsRekognition.json +191 -0
- package/workflow_nodes/awsS3.json +32 -0
- package/workflow_nodes/awsSes.json +302 -0
- package/workflow_nodes/awsSns.json +110 -0
- package/workflow_nodes/awsSnsTrigger.json +47 -0
- package/workflow_nodes/awsSqs.json +140 -0
- package/workflow_nodes/awsTextract.json +43 -0
- package/workflow_nodes/awsTranscribe.json +217 -0
- package/workflow_nodes/azureCosmosDb.json +8 -0
- package/workflow_nodes/azureStorage.json +17 -0
- package/workflow_nodes/bambooHr.json +8 -0
- package/workflow_nodes/bannerbear.json +126 -0
- package/workflow_nodes/baserow.json +277 -0
- package/workflow_nodes/beeminder.json +146 -0
- package/workflow_nodes/bitbucketTrigger.json +62 -0
- package/workflow_nodes/bitly.json +130 -0
- package/workflow_nodes/bitwarden.json +224 -0
- package/workflow_nodes/box.json +457 -0
- package/workflow_nodes/boxTrigger.json +8 -0
- package/workflow_nodes/brevo.json +41 -0
- package/workflow_nodes/brevoTrigger.json +145 -0
- package/workflow_nodes/bubble.json +212 -0
- package/workflow_nodes/calTrigger.json +91 -0
- package/workflow_nodes/calendlyTrigger.json +71 -0
- package/workflow_nodes/chargebee.json +217 -0
- package/workflow_nodes/chargebeeTrigger.json +187 -0
- package/workflow_nodes/circleCi.json +89 -0
- package/workflow_nodes/ciscoWebex.json +593 -0
- package/workflow_nodes/ciscoWebexTrigger.json +159 -0
- package/workflow_nodes/clearbit.json +138 -0
- package/workflow_nodes/clickUp.json +793 -0
- package/workflow_nodes/clickUpTrigger.json +188 -0
- package/workflow_nodes/clockify.json +372 -0
- package/workflow_nodes/clockifyTrigger.json +26 -0
- package/workflow_nodes/cloudflare.json +103 -0
- package/workflow_nodes/cockpit.json +161 -0
- package/workflow_nodes/coda.json +242 -0
- package/workflow_nodes/code.json +40 -0
- package/workflow_nodes/coinGecko.json +363 -0
- package/workflow_nodes/compareDatasets.json +14 -0
- package/workflow_nodes/compression.json +66 -0
- package/workflow_nodes/contentful.json +29 -0
- package/workflow_nodes/convertKit.json +159 -0
- package/workflow_nodes/convertKitTrigger.json +109 -0
- package/workflow_nodes/convertToFile.json +64 -0
- package/workflow_nodes/copper.json +239 -0
- package/workflow_nodes/copperTrigger.json +8 -0
- package/workflow_nodes/cortex.json +348 -0
- package/workflow_nodes/crateDb.json +90 -0
- package/workflow_nodes/cron.json +23 -0
- package/workflow_nodes/crowdDev.json +8 -0
- package/workflow_nodes/crowdDevTrigger.json +8 -0
- package/workflow_nodes/crypto.json +147 -0
- package/workflow_nodes/customerIo.json +206 -0
- package/workflow_nodes/customerIoTrigger.json +185 -0
- package/workflow_nodes/dateTime.json +39 -0
- package/workflow_nodes/debughelper.json +162 -0
- package/workflow_nodes/deepL.json +103 -0
- package/workflow_nodes/demio.json +187 -0
- package/workflow_nodes/dhl.json +53 -0
- package/workflow_nodes/discord.json +81 -0
- package/workflow_nodes/discourse.json +319 -0
- package/workflow_nodes/disqus.json +254 -0
- package/workflow_nodes/drift.json +112 -0
- package/workflow_nodes/dropbox.json +258 -0
- package/workflow_nodes/dropcontact.json +154 -0
- package/workflow_nodes/e2eTest.json +70 -0
- package/workflow_nodes/editImage.json +132 -0
- package/workflow_nodes/egoi.json +220 -0
- package/workflow_nodes/elasticSecurity.json +401 -0
- package/workflow_nodes/elasticsearch.json +422 -0
- package/workflow_nodes/emailReadImap.json +88 -0
- package/workflow_nodes/emailSend.json +38 -0
- package/workflow_nodes/emelia.json +201 -0
- package/workflow_nodes/emeliaTrigger.json +57 -0
- package/workflow_nodes/erpNext.json +139 -0
- package/workflow_nodes/errorTrigger.json +15 -0
- package/workflow_nodes/evaluationMetrics.json +21 -0
- package/workflow_nodes/eventbriteTrigger.json +125 -0
- package/workflow_nodes/executeCommand.json +25 -0
- package/workflow_nodes/executeWorkflow.json +102 -0
- package/workflow_nodes/executeWorkflowTrigger.json +65 -0
- package/workflow_nodes/executionData.json +35 -0
- package/workflow_nodes/extractFromFile.json +71 -0
- package/workflow_nodes/facebookGraphApi.json +234 -0
- package/workflow_nodes/facebookLeadAdsTrigger.json +8 -0
- package/workflow_nodes/facebookTrigger.json +112 -0
- package/workflow_nodes/figmaTrigger.json +8 -0
- package/workflow_nodes/filemaker.json +268 -0
- package/workflow_nodes/filter.json +24 -0
- package/workflow_nodes/flow.json +323 -0
- package/workflow_nodes/flowTrigger.json +52 -0
- package/workflow_nodes/form.json +25 -0
- package/workflow_nodes/formIoTrigger.json +59 -0
- package/workflow_nodes/formTrigger.json +8 -0
- package/workflow_nodes/formstackTrigger.json +8 -0
- package/workflow_nodes/freshdesk.json +584 -0
- package/workflow_nodes/freshservice.json +899 -0
- package/workflow_nodes/freshworksCrm.json +772 -0
- package/workflow_nodes/ftp.json +127 -0
- package/workflow_nodes/function.json +22 -0
- package/workflow_nodes/functionItem.json +22 -0
- package/workflow_nodes/gSuiteAdmin.json +562 -0
- package/workflow_nodes/getResponse.json +310 -0
- package/workflow_nodes/getResponseTrigger.json +82 -0
- package/workflow_nodes/ghost.json +290 -0
- package/workflow_nodes/git.json +184 -0
- package/workflow_nodes/github.json +732 -0
- package/workflow_nodes/githubTrigger.json +317 -0
- package/workflow_nodes/gitlab.json +544 -0
- package/workflow_nodes/gitlabTrigger.json +61 -0
- package/workflow_nodes/gmail.json +62 -0
- package/workflow_nodes/gmailTrigger.json +127 -0
- package/workflow_nodes/goToWebinar.json +430 -0
- package/workflow_nodes/gong.json +22 -0
- package/workflow_nodes/googleAds.json +116 -0
- package/workflow_nodes/googleAnalytics.json +28 -0
- package/workflow_nodes/googleBigQuery.json +38 -0
- package/workflow_nodes/googleBooks.json +154 -0
- package/workflow_nodes/googleBusinessProfile.json +277 -0
- package/workflow_nodes/googleBusinessProfileTrigger.json +55 -0
- package/workflow_nodes/googleCalendar.json +474 -0
- package/workflow_nodes/googleCalendarTrigger.json +72 -0
- package/workflow_nodes/googleChat.json +187 -0
- package/workflow_nodes/googleCloudNaturalLanguage.json +171 -0
- package/workflow_nodes/googleCloudStorage.json +466 -0
- package/workflow_nodes/googleContacts.json +481 -0
- package/workflow_nodes/googleDocs.json +312 -0
- package/workflow_nodes/googleDrive.json +920 -0
- package/workflow_nodes/googleDriveTrigger.json +181 -0
- package/workflow_nodes/googleFirebaseCloudFirestore.json +156 -0
- package/workflow_nodes/googleFirebaseRealtimeDatabase.json +75 -0
- package/workflow_nodes/googlePerspective.json +94 -0
- package/workflow_nodes/googleSheets.json +98 -0
- package/workflow_nodes/googleSheetsTrigger.json +192 -0
- package/workflow_nodes/googleSlides.json +186 -0
- package/workflow_nodes/googleTasks.json +198 -0
- package/workflow_nodes/googleTranslate.json +80 -0
- package/workflow_nodes/gotify.json +110 -0
- package/workflow_nodes/grafana.json +155 -0
- package/workflow_nodes/graphql.json +165 -0
- package/workflow_nodes/grist.json +13 -0
- package/workflow_nodes/gumroadTrigger.json +8 -0
- package/workflow_nodes/hackerNews.json +100 -0
- package/workflow_nodes/haloPSA.json +286 -0
- package/workflow_nodes/harvest.json +699 -0
- package/workflow_nodes/helpScout.json +629 -0
- package/workflow_nodes/helpScoutTrigger.json +8 -0
- package/workflow_nodes/highLevel.json +8 -0
- package/workflow_nodes/homeAssistant.json +201 -0
- package/workflow_nodes/html.json +118 -0
- package/workflow_nodes/htmlExtract.json +87 -0
- package/workflow_nodes/httpRequest.json +472 -0
- package/workflow_nodes/hubspot.json +62 -0
- package/workflow_nodes/hubspotTrigger.json +138 -0
- package/workflow_nodes/humanticAi.json +82 -0
- package/workflow_nodes/hunter.json +168 -0
- package/workflow_nodes/iCal.json +20 -0
- package/workflow_nodes/if.json +24 -0
- package/workflow_nodes/intercom.json +335 -0
- package/workflow_nodes/interval.json +8 -0
- package/workflow_nodes/invoiceNinja.json +882 -0
- package/workflow_nodes/invoiceNinjaTrigger.json +11 -0
- package/workflow_nodes/itemLists.json +313 -0
- package/workflow_nodes/iterable.json +168 -0
- package/workflow_nodes/jenkins.json +172 -0
- package/workflow_nodes/jira.json +529 -0
- package/workflow_nodes/jiraTrigger.json +308 -0
- package/workflow_nodes/jotFormTrigger.json +44 -0
- package/workflow_nodes/jwt.json +195 -0
- package/workflow_nodes/kafka.json +132 -0
- package/workflow_nodes/kafkaTrigger.json +11 -0
- package/workflow_nodes/keap.json +915 -0
- package/workflow_nodes/keapTrigger.json +37 -0
- package/workflow_nodes/kitemaker.json +153 -0
- package/workflow_nodes/koBoToolbox.json +337 -0
- package/workflow_nodes/koBoToolboxTrigger.json +8 -0
- package/workflow_nodes/langchain_Summarization Chain.json +60 -0
- package/workflow_nodes/langchain_agent.json +145 -0
- package/workflow_nodes/langchain_allowFileUploads.json +180 -0
- package/workflow_nodes/langchain_chainLlm.json +16 -0
- package/workflow_nodes/langchain_chainSummarization.json +119 -0
- package/workflow_nodes/langchain_code.json +62 -0
- package/workflow_nodes/langchain_documentBinaryInputLoader.json +8 -0
- package/workflow_nodes/langchain_documentDefaultDataLoader.json +8 -0
- package/workflow_nodes/langchain_documentGithubLoader.json +8 -0
- package/workflow_nodes/langchain_documentJsonInputLoader.json +8 -0
- package/workflow_nodes/langchain_embeddingDimensions.json +17 -0
- package/workflow_nodes/langchain_embeddingsAwsBedrock.json +8 -0
- package/workflow_nodes/langchain_embeddingsAzureOpenAi.json +151 -0
- package/workflow_nodes/langchain_embeddingsCohere.json +8 -0
- package/workflow_nodes/langchain_embeddingsGoogleGemini.json +8 -0
- package/workflow_nodes/langchain_embeddingsGoogleVertex.json +8 -0
- package/workflow_nodes/langchain_embeddingsHuggingFaceInference.json +8 -0
- package/workflow_nodes/langchain_embeddingsMistralCloud.json +8 -0
- package/workflow_nodes/langchain_embeddingsOllama.json +8 -0
- package/workflow_nodes/langchain_informationExtractor.json +81 -0
- package/workflow_nodes/langchain_lmChatAwsBedrock.json +8 -0
- package/workflow_nodes/langchain_lmChatAzureOpenAi.json +151 -0
- package/workflow_nodes/langchain_lmChatDeepSeek.json +10 -0
- package/workflow_nodes/langchain_lmChatGoogleGemini.json +31 -0
- package/workflow_nodes/langchain_lmChatGoogleVertex.json +32 -0
- package/workflow_nodes/langchain_lmChatGroq.json +8 -0
- package/workflow_nodes/langchain_lmChatMistralCloud.json +8 -0
- package/workflow_nodes/langchain_lmChatOllama.json +8 -0
- package/workflow_nodes/langchain_lmChatOpenAi.json +155 -0
- package/workflow_nodes/langchain_lmChatOpenRouter.json +10 -0
- package/workflow_nodes/langchain_lmChatXAiGrok.json +10 -0
- package/workflow_nodes/langchain_lmCohere.json +8 -0
- package/workflow_nodes/langchain_lmOllama.json +8 -0
- package/workflow_nodes/langchain_lmOpenAi.json +251 -0
- package/workflow_nodes/langchain_lmOpenHuggingFaceInference.json +8 -0
- package/workflow_nodes/langchain_manualChatTrigger.json +11 -0
- package/workflow_nodes/langchain_mcpClientTool.json +86 -0
- package/workflow_nodes/langchain_mcpTrigger.json +8 -0
- package/workflow_nodes/langchain_memoryBufferWindow.json +13 -0
- package/workflow_nodes/langchain_memoryChatRetriever.json +22 -0
- package/workflow_nodes/langchain_memoryManager.json +106 -0
- package/workflow_nodes/langchain_memoryMongoDbChat.json +10 -0
- package/workflow_nodes/langchain_memoryMotorhead.json +13 -0
- package/workflow_nodes/langchain_memoryPostgresChat.json +13 -0
- package/workflow_nodes/langchain_memoryRedisChat.json +15 -0
- package/workflow_nodes/langchain_memoryXata.json +14 -0
- package/workflow_nodes/langchain_memoryZep.json +13 -0
- package/workflow_nodes/langchain_model.json +155 -0
- package/workflow_nodes/langchain_mongoCollection.json +16 -0
- package/workflow_nodes/langchain_notice.json +22 -0
- package/workflow_nodes/langchain_openAiAssistant.json +132 -0
- package/workflow_nodes/langchain_options.json +17 -0
- package/workflow_nodes/langchain_outputParserAutofixing.json +8 -0
- package/workflow_nodes/langchain_outputParserItemList.json +8 -0
- package/workflow_nodes/langchain_outputParserStructured.json +12 -0
- package/workflow_nodes/langchain_pineconeNamespace.json +16 -0
- package/workflow_nodes/langchain_queryName.json +16 -0
- package/workflow_nodes/langchain_retrieverContextualCompression.json +8 -0
- package/workflow_nodes/langchain_retrieverMultiQuery.json +8 -0
- package/workflow_nodes/langchain_retrieverVectorStore.json +8 -0
- package/workflow_nodes/langchain_retrieverWorkflow.json +103 -0
- package/workflow_nodes/langchain_sentimentAnalysis.json +52 -0
- package/workflow_nodes/langchain_systemPromptTemplate.json +47 -0
- package/workflow_nodes/langchain_tableName.json +23 -0
- package/workflow_nodes/langchain_textClassifier.json +66 -0
- package/workflow_nodes/langchain_textSplitterCharacterTextSplitter.json +8 -0
- package/workflow_nodes/langchain_textSplitterRecursiveCharacterTextSplitter.json +8 -0
- package/workflow_nodes/langchain_textSplitterTokenSplitter.json +8 -0
- package/workflow_nodes/langchain_toolCalculator.json +8 -0
- package/workflow_nodes/langchain_toolCode.json +12 -0
- package/workflow_nodes/langchain_toolHttpRequest.json +232 -0
- package/workflow_nodes/langchain_toolSearXng.json +8 -0
- package/workflow_nodes/langchain_toolSerpApi.json +8 -0
- package/workflow_nodes/langchain_toolThink.json +8 -0
- package/workflow_nodes/langchain_toolVectorStore.json +11 -0
- package/workflow_nodes/langchain_toolWikipedia.json +8 -0
- package/workflow_nodes/langchain_toolWolframAlpha.json +8 -0
- package/workflow_nodes/langchain_toolWorkflow.json +8 -0
- package/workflow_nodes/langchain_vectorStoreInMemoryInsert.json +29 -0
- package/workflow_nodes/langchain_vectorStoreInMemoryLoad.json +8 -0
- package/workflow_nodes/langchain_vectorStorePineconeInsert.json +37 -0
- package/workflow_nodes/langchain_vectorStorePineconeLoad.json +8 -0
- package/workflow_nodes/langchain_vectorStoreSupabaseInsert.json +32 -0
- package/workflow_nodes/langchain_vectorStoreSupabaseLoad.json +8 -0
- package/workflow_nodes/langchain_vectorStoreZepInsert.json +46 -0
- package/workflow_nodes/langchain_vectorStoreZepLoad.json +8 -0
- package/workflow_nodes/ldap.json +182 -0
- package/workflow_nodes/lemlist.json +44 -0
- package/workflow_nodes/lemlistTrigger.json +45 -0
- package/workflow_nodes/limit.json +26 -0
- package/workflow_nodes/line.json +95 -0
- package/workflow_nodes/linear.json +151 -0
- package/workflow_nodes/linearTrigger.json +71 -0
- package/workflow_nodes/lingvaNex.json +66 -0
- package/workflow_nodes/linkedIn.json +142 -0
- package/workflow_nodes/localFileTrigger.json +120 -0
- package/workflow_nodes/lonescale.json +171 -0
- package/workflow_nodes/lonescaleTrigger.json +8 -0
- package/workflow_nodes/magento2.json +164 -0
- package/workflow_nodes/mailcheck.json +46 -0
- package/workflow_nodes/mailchimp.json +507 -0
- package/workflow_nodes/mailchimpTrigger.json +100 -0
- package/workflow_nodes/mailerLite.json +24 -0
- package/workflow_nodes/mailerLiteTrigger.json +74 -0
- package/workflow_nodes/mailgun.json +81 -0
- package/workflow_nodes/mailjet.json +201 -0
- package/workflow_nodes/mailjetTrigger.json +8 -0
- package/workflow_nodes/mandrill.json +372 -0
- package/workflow_nodes/manualTrigger.json +8 -0
- package/workflow_nodes/markdown.json +376 -0
- package/workflow_nodes/marketstack.json +126 -0
- package/workflow_nodes/matrix.json +264 -0
- package/workflow_nodes/mattermost.json +8 -0
- package/workflow_nodes/mautic.json +564 -0
- package/workflow_nodes/mauticTrigger.json +54 -0
- package/workflow_nodes/medium.json +209 -0
- package/workflow_nodes/merge.json +125 -0
- package/workflow_nodes/messageBird.json +182 -0
- package/workflow_nodes/metabase.json +175 -0
- package/workflow_nodes/microsoftDynamicsCrm.json +100 -0
- package/workflow_nodes/microsoftEntra.json +51 -0
- package/workflow_nodes/microsoftExcel.json +35 -0
- package/workflow_nodes/microsoftGraphSecurity.json +113 -0
- package/workflow_nodes/microsoftOneDrive.json +232 -0
- package/workflow_nodes/microsoftOneDriveTrigger.json +80 -0
- package/workflow_nodes/microsoftOutlook.json +40 -0
- package/workflow_nodes/microsoftOutlookTrigger.json +24 -0
- package/workflow_nodes/microsoftSql.json +81 -0
- package/workflow_nodes/microsoftTeams.json +36 -0
- package/workflow_nodes/microsoftToDo.json +181 -0
- package/workflow_nodes/mindee.json +86 -0
- package/workflow_nodes/misp.json +399 -0
- package/workflow_nodes/mocean.json +103 -0
- package/workflow_nodes/mondayCom.json +290 -0
- package/workflow_nodes/mongoDb.json +16 -0
- package/workflow_nodes/monicaCrm.json +543 -0
- package/workflow_nodes/moveBinaryData.json +121 -0
- package/workflow_nodes/mqtt.json +67 -0
- package/workflow_nodes/mqttTrigger.json +47 -0
- package/workflow_nodes/msg91.json +65 -0
- package/workflow_nodes/mySql.json +111 -0
- package/workflow_nodes/n8n.json +75 -0
- package/workflow_nodes/n8nTrigger.json +27 -0
- package/workflow_nodes/nasa.json +310 -0
- package/workflow_nodes/netlify.json +87 -0
- package/workflow_nodes/netlifyTrigger.json +68 -0
- package/workflow_nodes/netscalerAdc.json +243 -0
- package/workflow_nodes/nextCloud.json +312 -0
- package/workflow_nodes/noOp.json +8 -0
- package/workflow_nodes/nocoDb.json +276 -0
- package/workflow_nodes/notion.json +8 -0
- package/workflow_nodes/notionTrigger.json +75 -0
- package/workflow_nodes/npm.json +64 -0
- package/workflow_nodes/odoo.json +344 -0
- package/workflow_nodes/okta.json +97 -0
- package/workflow_nodes/oneSimpleApi.json +281 -0
- package/workflow_nodes/onfleet.json +316 -0
- package/workflow_nodes/onfleetTrigger.json +8 -0
- package/workflow_nodes/openAi.json +154 -0
- package/workflow_nodes/openThesaurus.json +81 -0
- package/workflow_nodes/openWeatherMap.json +129 -0
- package/workflow_nodes/orbit.json +375 -0
- package/workflow_nodes/oura.json +74 -0
- package/workflow_nodes/paddle.json +403 -0
- package/workflow_nodes/pagerDuty.json +351 -0
- package/workflow_nodes/payPal.json +196 -0
- package/workflow_nodes/payPalTrigger.json +40 -0
- package/workflow_nodes/peekalink.json +41 -0
- package/workflow_nodes/phantombuster.json +172 -0
- package/workflow_nodes/philipsHue.json +177 -0
- package/workflow_nodes/pipedrive.json +860 -0
- package/workflow_nodes/pipedriveTrigger.json +11 -0
- package/workflow_nodes/plivo.json +91 -0
- package/workflow_nodes/postHog.json +122 -0
- package/workflow_nodes/postbin.json +60 -0
- package/workflow_nodes/postgres.json +109 -0
- package/workflow_nodes/postgresTrigger.json +8 -0
- package/workflow_nodes/postmarkTrigger.json +72 -0
- package/workflow_nodes/profitWell.json +305 -0
- package/workflow_nodes/pushbullet.json +186 -0
- package/workflow_nodes/pushcut.json +75 -0
- package/workflow_nodes/pushcutTrigger.json +8 -0
- package/workflow_nodes/pushover.json +159 -0
- package/workflow_nodes/questDb.json +94 -0
- package/workflow_nodes/quickChart.json +188 -0
- package/workflow_nodes/quickbase.json +205 -0
- package/workflow_nodes/quickbooks.json +550 -0
- package/workflow_nodes/rabbitmq.json +165 -0
- package/workflow_nodes/rabbitmqTrigger.json +8 -0
- package/workflow_nodes/raindrop.json +216 -0
- package/workflow_nodes/readBinaryFile.json +26 -0
- package/workflow_nodes/readBinaryFiles.json +26 -0
- package/workflow_nodes/readPDF.json +31 -0
- package/workflow_nodes/readWriteFile.json +27 -0
- package/workflow_nodes/reddit.json +309 -0
- package/workflow_nodes/redis.json +183 -0
- package/workflow_nodes/redisTrigger.json +8 -0
- package/workflow_nodes/removeDuplicates.json +8 -0
- package/workflow_nodes/renameKeys.json +67 -0
- package/workflow_nodes/respondToWebhook.json +126 -0
- package/workflow_nodes/rocketchat.json +216 -0
- package/workflow_nodes/rssFeedRead.json +28 -0
- package/workflow_nodes/rssFeedReadTrigger.json +17 -0
- package/workflow_nodes/rundeck.json +79 -0
- package/workflow_nodes/s3.json +425 -0
- package/workflow_nodes/salesforce.json +1137 -0
- package/workflow_nodes/salesforceTrigger.json +122 -0
- package/workflow_nodes/salesmate.json +467 -0
- package/workflow_nodes/scheduleTrigger.json +270 -0
- package/workflow_nodes/seaTable.json +8 -0
- package/workflow_nodes/seaTableTrigger.json +87 -0
- package/workflow_nodes/securityScorecard.json +459 -0
- package/workflow_nodes/segment.json +219 -0
- package/workflow_nodes/sendGrid.json +359 -0
- package/workflow_nodes/sendy.json +225 -0
- package/workflow_nodes/sentryIo.json +426 -0
- package/workflow_nodes/serviceNow.json +544 -0
- package/workflow_nodes/set.json +124 -0
- package/workflow_nodes/shopify.json +707 -0
- package/workflow_nodes/shopifyTrigger.json +8 -0
- package/workflow_nodes/signl4.json +133 -0
- package/workflow_nodes/simulate.json +30 -0
- package/workflow_nodes/simulateTrigger.json +8 -0
- package/workflow_nodes/slack.json +62 -0
- package/workflow_nodes/slackTrigger.json +135 -0
- package/workflow_nodes/sms77.json +121 -0
- package/workflow_nodes/snowflake.json +65 -0
- package/workflow_nodes/sort.json +57 -0
- package/workflow_nodes/splitInBatches.json +30 -0
- package/workflow_nodes/splitOut.json +62 -0
- package/workflow_nodes/splunk.json +40 -0
- package/workflow_nodes/spontit.json +123 -0
- package/workflow_nodes/spotify.json +285 -0
- package/workflow_nodes/spreadsheetFile.json +8 -0
- package/workflow_nodes/sseTrigger.json +8 -0
- package/workflow_nodes/ssh.json +105 -0
- package/workflow_nodes/stackby.json +85 -0
- package/workflow_nodes/start.json +15 -0
- package/workflow_nodes/stickyNote.json +36 -0
- package/workflow_nodes/stopAndError.json +8 -0
- package/workflow_nodes/storyblok.json +138 -0
- package/workflow_nodes/strapi.json +138 -0
- package/workflow_nodes/strava.json +427 -0
- package/workflow_nodes/stravaTrigger.json +79 -0
- package/workflow_nodes/stripe.json +357 -0
- package/workflow_nodes/stripeTrigger.json +775 -0
- package/workflow_nodes/summarize.json +124 -0
- package/workflow_nodes/supabase.json +136 -0
- package/workflow_nodes/surveyMonkeyTrigger.json +160 -0
- package/workflow_nodes/switch.json +91 -0
- package/workflow_nodes/syncroMsp.json +8 -0
- package/workflow_nodes/taiga.json +340 -0
- package/workflow_nodes/taigaTrigger.json +81 -0
- package/workflow_nodes/tapfiliate.json +241 -0
- package/workflow_nodes/telegram.json +612 -0
- package/workflow_nodes/telegramTrigger.json +142 -0
- package/workflow_nodes/theHive.json +497 -0
- package/workflow_nodes/theHiveProject.json +8 -0
- package/workflow_nodes/theHiveProjectTrigger.json +162 -0
- package/workflow_nodes/theHiveTrigger.json +101 -0
- package/workflow_nodes/timescaleDb.json +95 -0
- package/workflow_nodes/todoist.json +285 -0
- package/workflow_nodes/togglTrigger.json +24 -0
- package/workflow_nodes/totp.json +86 -0
- package/workflow_nodes/travisCi.json +142 -0
- package/workflow_nodes/trello.json +609 -0
- package/workflow_nodes/trelloTrigger.json +8 -0
- package/workflow_nodes/twake.json +76 -0
- package/workflow_nodes/twilio.json +95 -0
- package/workflow_nodes/twilioTrigger.json +46 -0
- package/workflow_nodes/twist.json +376 -0
- package/workflow_nodes/twitter.json +40 -0
- package/workflow_nodes/typeformTrigger.json +62 -0
- package/workflow_nodes/unleashedSoftware.json +154 -0
- package/workflow_nodes/uplead.json +72 -0
- package/workflow_nodes/uproc.json +26 -0
- package/workflow_nodes/uptimeRobot.json +453 -0
- package/workflow_nodes/urlScanIo.json +113 -0
- package/workflow_nodes/venafiTlsProtectCloud.json +310 -0
- package/workflow_nodes/venafiTlsProtectCloudTrigger.json +38 -0
- package/workflow_nodes/venafiTlsProtectDatacenter.json +491 -0
- package/workflow_nodes/vero.json +158 -0
- package/workflow_nodes/vonage.json +125 -0
- package/workflow_nodes/wait.json +71 -0
- package/workflow_nodes/webflow.json +38 -0
- package/workflow_nodes/webflowTrigger.json +8 -0
- package/workflow_nodes/webhook.json +55 -0
- package/workflow_nodes/wekan.json +460 -0
- package/workflow_nodes/whatsApp.json +476 -0
- package/workflow_nodes/whatsAppTrigger.json +103 -0
- package/workflow_nodes/wise.json +330 -0
- package/workflow_nodes/wiseTrigger.json +8 -0
- package/workflow_nodes/wooCommerce.json +812 -0
- package/workflow_nodes/wooCommerceTrigger.json +8 -0
- package/workflow_nodes/wordpress.json +500 -0
- package/workflow_nodes/workableTrigger.json +51 -0
- package/workflow_nodes/writeBinaryFile.json +34 -0
- package/workflow_nodes/wufooTrigger.json +37 -0
- package/workflow_nodes/xero.json +530 -0
- package/workflow_nodes/xml.json +129 -0
- package/workflow_nodes/youTube.json +578 -0
- package/workflow_nodes/yourls.json +71 -0
- package/workflow_nodes/zammad.json +406 -0
- package/workflow_nodes/zendesk.json +526 -0
- package/workflow_nodes/zendeskTrigger.json +187 -0
- package/workflow_nodes/zohoCrm.json +721 -0
- package/workflow_nodes/zoom.json +507 -0
- package/workflow_nodes/zulip.json +371 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow Creation Tool Tests
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const { createWorkflowExecute } = require('../../src/tools/workflowCreation');
|
|
6
|
+
const { workflowStorage } = require('../../src/models/storage');
|
|
7
|
+
|
|
8
|
+
// Mock dependencies
|
|
9
|
+
jest.mock('../../src/models/storage', () => ({
|
|
10
|
+
workflowStorage: {
|
|
11
|
+
saveWorkflow: jest.fn()
|
|
12
|
+
}
|
|
13
|
+
}));
|
|
14
|
+
|
|
15
|
+
jest.mock('../../src/utils/securityLogger', () => ({
|
|
16
|
+
logDataAccess: jest.fn(),
|
|
17
|
+
logSecurityEvent: jest.fn()
|
|
18
|
+
}));
|
|
19
|
+
|
|
20
|
+
jest.mock('../../src/utils/logger', () => ({
|
|
21
|
+
logger: {
|
|
22
|
+
info: jest.fn(),
|
|
23
|
+
error: jest.fn()
|
|
24
|
+
}
|
|
25
|
+
}));
|
|
26
|
+
|
|
27
|
+
jest.mock('uuid', () => ({
|
|
28
|
+
v4: jest.fn().mockReturnValue('test-uuid')
|
|
29
|
+
}));
|
|
30
|
+
|
|
31
|
+
// Cleanup mocks after each test
|
|
32
|
+
afterEach(() => {
|
|
33
|
+
jest.clearAllMocks();
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
describe('Workflow Creation Tool', () => {
|
|
37
|
+
it('should create a workflow with minimum required parameters', async () => {
|
|
38
|
+
// Setup the mock implementation
|
|
39
|
+
workflowStorage.saveWorkflow.mockResolvedValue(true);
|
|
40
|
+
|
|
41
|
+
// Execute the tool
|
|
42
|
+
const result = await createWorkflowExecute({
|
|
43
|
+
name: 'Test Workflow'
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Verify the result
|
|
47
|
+
expect(result.workflowId).toBe('test-uuid');
|
|
48
|
+
expect(result.workflowData.name).toBe('Test Workflow');
|
|
49
|
+
expect(result.workflowData.description).toBe('');
|
|
50
|
+
expect(result.workflowData.active).toBe(false);
|
|
51
|
+
expect(result.workflowData.nodes).toEqual([]);
|
|
52
|
+
expect(result.workflowData.connections).toEqual({});
|
|
53
|
+
|
|
54
|
+
// Verify the workflowStorage.saveWorkflow was called
|
|
55
|
+
expect(workflowStorage.saveWorkflow).toHaveBeenCalledWith(
|
|
56
|
+
'test-uuid',
|
|
57
|
+
expect.objectContaining({
|
|
58
|
+
id: 'test-uuid',
|
|
59
|
+
name: 'Test Workflow'
|
|
60
|
+
}),
|
|
61
|
+
expect.stringContaining('test-uuid.json')
|
|
62
|
+
);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('should create a workflow with all parameters', async () => {
|
|
66
|
+
// Setup the mock implementation
|
|
67
|
+
workflowStorage.saveWorkflow.mockResolvedValue(true);
|
|
68
|
+
|
|
69
|
+
// Execute the tool
|
|
70
|
+
const result = await createWorkflowExecute({
|
|
71
|
+
name: 'Test Workflow',
|
|
72
|
+
description: 'Test Description',
|
|
73
|
+
active: true,
|
|
74
|
+
settings: {
|
|
75
|
+
executionTimeout: 7200
|
|
76
|
+
},
|
|
77
|
+
userId: 'test-user'
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// Verify the result
|
|
81
|
+
expect(result.workflowId).toBe('test-uuid');
|
|
82
|
+
expect(result.workflowData.name).toBe('Test Workflow');
|
|
83
|
+
expect(result.workflowData.description).toBe('Test Description');
|
|
84
|
+
expect(result.workflowData.active).toBe(true);
|
|
85
|
+
expect(result.workflowData.settings.executionTimeout).toBe(7200);
|
|
86
|
+
|
|
87
|
+
// Verify the workflowStorage.saveWorkflow was called
|
|
88
|
+
expect(workflowStorage.saveWorkflow).toHaveBeenCalledWith(
|
|
89
|
+
'test-uuid',
|
|
90
|
+
expect.objectContaining({
|
|
91
|
+
id: 'test-uuid',
|
|
92
|
+
name: 'Test Workflow',
|
|
93
|
+
description: 'Test Description',
|
|
94
|
+
active: true
|
|
95
|
+
}),
|
|
96
|
+
expect.stringContaining('test-uuid.json')
|
|
97
|
+
);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('should handle errors properly', async () => {
|
|
101
|
+
// Setup the mock implementation to throw an error
|
|
102
|
+
const errorMessage = 'Test error message';
|
|
103
|
+
workflowStorage.saveWorkflow.mockRejectedValue(new Error(errorMessage));
|
|
104
|
+
|
|
105
|
+
// Execute the tool and expect it to throw
|
|
106
|
+
await expect(createWorkflowExecute({
|
|
107
|
+
name: 'Test Workflow'
|
|
108
|
+
})).rejects.toThrow(errorMessage);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for workflow testing tools
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const { testWorkflowTool, getExecutionStatusTool } = require('../../src/tools/workflowTesting');
|
|
6
|
+
const { workflowStorage } = require('../../src/models/storage');
|
|
7
|
+
const fetch = require('node-fetch');
|
|
8
|
+
const config = require('../../config/default');
|
|
9
|
+
|
|
10
|
+
// Mock dependencies
|
|
11
|
+
jest.mock('../../src/models/storage');
|
|
12
|
+
jest.mock('node-fetch');
|
|
13
|
+
jest.mock('../../src/utils/logger', () => ({
|
|
14
|
+
logger: {
|
|
15
|
+
info: jest.fn(),
|
|
16
|
+
error: jest.fn(),
|
|
17
|
+
warn: jest.fn()
|
|
18
|
+
}
|
|
19
|
+
}));
|
|
20
|
+
jest.mock('../../src/utils/securityLogger', () => ({
|
|
21
|
+
logDataAccess: jest.fn(),
|
|
22
|
+
logSecurityEvent: jest.fn()
|
|
23
|
+
}));
|
|
24
|
+
jest.mock('../../src/models/n8nIntegration', () => ({
|
|
25
|
+
getIntegrationType: jest.fn().mockReturnValue('api')
|
|
26
|
+
}));
|
|
27
|
+
jest.mock('../../config/default', () => ({
|
|
28
|
+
n8n: {
|
|
29
|
+
apiUrl: 'http://localhost:5678/api/',
|
|
30
|
+
apiKey: 'test-api-key'
|
|
31
|
+
},
|
|
32
|
+
storage: {
|
|
33
|
+
workflowsPath: './test-workflow_nodes',
|
|
34
|
+
versioning: {
|
|
35
|
+
enabled: true,
|
|
36
|
+
maxVersions: 10
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
server: {
|
|
40
|
+
port: 3000,
|
|
41
|
+
env: 'test'
|
|
42
|
+
},
|
|
43
|
+
auth: {
|
|
44
|
+
jwtSecret: 'test-secret',
|
|
45
|
+
jwtExpiresIn: '1d',
|
|
46
|
+
apiKeys: ['test-key']
|
|
47
|
+
},
|
|
48
|
+
logging: {
|
|
49
|
+
level: 'info'
|
|
50
|
+
}
|
|
51
|
+
}));
|
|
52
|
+
|
|
53
|
+
describe('Workflow Testing Tools', () => {
|
|
54
|
+
afterEach(() => {
|
|
55
|
+
jest.clearAllMocks();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
describe('testWorkflowTool', () => {
|
|
59
|
+
it('should execute a workflow and return results', async () => {
|
|
60
|
+
// Mock workflowStorage.loadWorkflow to return a valid workflow
|
|
61
|
+
workflowStorage.loadWorkflow.mockResolvedValueOnce({
|
|
62
|
+
id: 'test-workflow-id',
|
|
63
|
+
name: 'Test Workflow'
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Mock successful fetch response
|
|
67
|
+
const mockResponse = {
|
|
68
|
+
ok: true,
|
|
69
|
+
json: jest.fn().mockResolvedValueOnce({
|
|
70
|
+
executionId: 'test-execution-id',
|
|
71
|
+
data: { result: 'success' },
|
|
72
|
+
logs: ['Workflow started', 'Workflow completed'],
|
|
73
|
+
executionTime: 1234,
|
|
74
|
+
status: 'completed'
|
|
75
|
+
})
|
|
76
|
+
};
|
|
77
|
+
fetch.mockResolvedValueOnce(mockResponse);
|
|
78
|
+
|
|
79
|
+
// Call the tool
|
|
80
|
+
const result = await testWorkflowTool.execute({
|
|
81
|
+
workflowId: 'test-workflow-id',
|
|
82
|
+
testData: { input: 'test-data' }
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// Verify fetch was called with the correct arguments
|
|
86
|
+
expect(fetch).toHaveBeenCalledWith(
|
|
87
|
+
'http://localhost:5678/api/workflows/test-workflow-id/execute',
|
|
88
|
+
expect.objectContaining({
|
|
89
|
+
method: 'POST',
|
|
90
|
+
headers: {
|
|
91
|
+
'Content-Type': 'application/json',
|
|
92
|
+
'X-N8N-API-KEY': 'test-api-key'
|
|
93
|
+
},
|
|
94
|
+
body: JSON.stringify({ data: { input: 'test-data' } })
|
|
95
|
+
})
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
// Verify result structure
|
|
99
|
+
expect(result).toEqual({
|
|
100
|
+
success: true,
|
|
101
|
+
executionId: 'test-execution-id',
|
|
102
|
+
data: { result: 'success' },
|
|
103
|
+
logs: ['Workflow started', 'Workflow completed'],
|
|
104
|
+
executionTime: 1234,
|
|
105
|
+
status: 'completed'
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('should handle workflow not found', async () => {
|
|
110
|
+
// Mock workflowStorage.loadWorkflow to return null (workflow not found)
|
|
111
|
+
workflowStorage.loadWorkflow.mockResolvedValueOnce(null);
|
|
112
|
+
|
|
113
|
+
// Call the tool and expect it to throw an error
|
|
114
|
+
await expect(testWorkflowTool.execute({
|
|
115
|
+
workflowId: 'non-existent-workflow',
|
|
116
|
+
testData: { input: 'test-data' }
|
|
117
|
+
})).rejects.toThrow('Failed to execute workflow: Workflow with ID non-existent-workflow not found');
|
|
118
|
+
|
|
119
|
+
// Verify fetch was not called
|
|
120
|
+
expect(fetch).not.toHaveBeenCalled();
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it('should handle API errors', async () => {
|
|
124
|
+
// Mock workflowStorage.loadWorkflow to return a valid workflow
|
|
125
|
+
workflowStorage.loadWorkflow.mockResolvedValueOnce({
|
|
126
|
+
id: 'test-workflow-id',
|
|
127
|
+
name: 'Test Workflow'
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
// Mock failed fetch response
|
|
131
|
+
const mockResponse = {
|
|
132
|
+
ok: false,
|
|
133
|
+
status: 404,
|
|
134
|
+
statusText: 'Not Found',
|
|
135
|
+
json: jest.fn().mockResolvedValueOnce({
|
|
136
|
+
message: 'Workflow not found in n8n'
|
|
137
|
+
})
|
|
138
|
+
};
|
|
139
|
+
fetch.mockResolvedValueOnce(mockResponse);
|
|
140
|
+
|
|
141
|
+
// Call the tool and expect it to throw an error
|
|
142
|
+
await expect(testWorkflowTool.execute({
|
|
143
|
+
workflowId: 'test-workflow-id',
|
|
144
|
+
testData: { input: 'test-data' }
|
|
145
|
+
})).rejects.toThrow('Failed to execute workflow: 404 Not Found');
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('should handle timeouts', async () => {
|
|
149
|
+
// Mock workflowStorage.loadWorkflow to return a valid workflow
|
|
150
|
+
workflowStorage.loadWorkflow.mockResolvedValueOnce({
|
|
151
|
+
id: 'test-workflow-id',
|
|
152
|
+
name: 'Test Workflow'
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// Mock fetch to simulate a timeout by rejecting with AbortError after delay
|
|
156
|
+
const abortError = new Error('The operation was aborted');
|
|
157
|
+
abortError.name = 'AbortError';
|
|
158
|
+
fetch.mockRejectedValueOnce(abortError);
|
|
159
|
+
|
|
160
|
+
// Call the tool and expect it to throw a timeout error
|
|
161
|
+
await expect(testWorkflowTool.execute({
|
|
162
|
+
workflowId: 'test-workflow-id',
|
|
163
|
+
testData: { input: 'test-data' },
|
|
164
|
+
timeout: 1000 // 1 second timeout
|
|
165
|
+
})).rejects.toThrow('Failed to execute workflow: Workflow execution timed out after 1000ms');
|
|
166
|
+
}, 10000); // Set test timeout to 10 seconds
|
|
167
|
+
|
|
168
|
+
it('should reject filesystem integration for execution', async () => {
|
|
169
|
+
// Mock getIntegrationType to return 'filesystem'
|
|
170
|
+
const { getIntegrationType } = require('../../src/models/n8nIntegration');
|
|
171
|
+
getIntegrationType.mockReturnValueOnce('filesystem');
|
|
172
|
+
|
|
173
|
+
// Mock workflowStorage.loadWorkflow to return a valid workflow
|
|
174
|
+
workflowStorage.loadWorkflow.mockResolvedValueOnce({
|
|
175
|
+
id: 'test-workflow-id',
|
|
176
|
+
name: 'Test Workflow'
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// Call the tool and expect it to throw an error about filesystem integration
|
|
180
|
+
await expect(testWorkflowTool.execute({
|
|
181
|
+
workflowId: 'test-workflow-id',
|
|
182
|
+
testData: { input: 'test-data' }
|
|
183
|
+
})).rejects.toThrow('Failed to execute workflow: Direct workflow execution not supported for filesystem integration');
|
|
184
|
+
|
|
185
|
+
// Verify fetch was not called
|
|
186
|
+
expect(fetch).not.toHaveBeenCalled();
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
describe('getExecutionStatusTool', () => {
|
|
191
|
+
it('should get execution status successfully', async () => {
|
|
192
|
+
// Mock successful fetch response
|
|
193
|
+
const mockResponse = {
|
|
194
|
+
ok: true,
|
|
195
|
+
json: jest.fn().mockResolvedValueOnce({
|
|
196
|
+
id: 'test-execution-id',
|
|
197
|
+
status: 'completed',
|
|
198
|
+
data: { result: 'success' },
|
|
199
|
+
startedAt: '2023-01-01T00:00:00.000Z',
|
|
200
|
+
finishedAt: '2023-01-01T00:01:00.000Z',
|
|
201
|
+
workflowId: 'test-workflow-id',
|
|
202
|
+
mode: 'manual'
|
|
203
|
+
})
|
|
204
|
+
};
|
|
205
|
+
fetch.mockResolvedValueOnce(mockResponse);
|
|
206
|
+
|
|
207
|
+
// Call the tool
|
|
208
|
+
const result = await getExecutionStatusTool.execute({
|
|
209
|
+
executionId: 'test-execution-id'
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
// Verify fetch was called with the correct arguments
|
|
213
|
+
expect(fetch).toHaveBeenCalledWith(
|
|
214
|
+
'http://localhost:5678/api/executions/test-execution-id',
|
|
215
|
+
expect.objectContaining({
|
|
216
|
+
method: 'GET',
|
|
217
|
+
headers: {
|
|
218
|
+
'Content-Type': 'application/json',
|
|
219
|
+
'X-N8N-API-KEY': 'test-api-key'
|
|
220
|
+
}
|
|
221
|
+
})
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
// Verify result structure
|
|
225
|
+
expect(result).toEqual({
|
|
226
|
+
success: true,
|
|
227
|
+
executionId: 'test-execution-id',
|
|
228
|
+
status: 'completed',
|
|
229
|
+
data: { result: 'success' },
|
|
230
|
+
startedAt: '2023-01-01T00:00:00.000Z',
|
|
231
|
+
finishedAt: '2023-01-01T00:01:00.000Z',
|
|
232
|
+
workflowId: 'test-workflow-id',
|
|
233
|
+
mode: 'manual'
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
it('should handle API errors', async () => {
|
|
238
|
+
// Mock failed fetch response
|
|
239
|
+
const mockResponse = {
|
|
240
|
+
ok: false,
|
|
241
|
+
status: 404,
|
|
242
|
+
statusText: 'Not Found',
|
|
243
|
+
json: jest.fn().mockResolvedValueOnce({
|
|
244
|
+
message: 'Execution not found'
|
|
245
|
+
})
|
|
246
|
+
};
|
|
247
|
+
fetch.mockResolvedValueOnce(mockResponse);
|
|
248
|
+
|
|
249
|
+
// Call the tool and expect it to throw an error
|
|
250
|
+
await expect(getExecutionStatusTool.execute({
|
|
251
|
+
executionId: 'non-existent-execution'
|
|
252
|
+
})).rejects.toThrow('Failed to get execution status: 404 Not Found');
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
it('should reject filesystem integration for status check', async () => {
|
|
256
|
+
// Mock getIntegrationType to return 'filesystem'
|
|
257
|
+
const { getIntegrationType } = require('../../src/models/n8nIntegration');
|
|
258
|
+
getIntegrationType.mockReturnValueOnce('filesystem');
|
|
259
|
+
|
|
260
|
+
// Call the tool and expect it to throw an error about filesystem integration
|
|
261
|
+
await expect(getExecutionStatusTool.execute({
|
|
262
|
+
executionId: 'test-execution-id'
|
|
263
|
+
})).rejects.toThrow('Failed to get execution status: Execution status check not supported for filesystem integration');
|
|
264
|
+
|
|
265
|
+
// Verify fetch was not called
|
|
266
|
+
expect(fetch).not.toHaveBeenCalled();
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
});
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User Model Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests for the user roles and permissions model
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const {
|
|
8
|
+
PERMISSIONS,
|
|
9
|
+
ROLES,
|
|
10
|
+
ROLE_PERMISSIONS,
|
|
11
|
+
hasPermission,
|
|
12
|
+
getUserPermissions,
|
|
13
|
+
validateRole
|
|
14
|
+
} = require('../src/models/user');
|
|
15
|
+
|
|
16
|
+
describe('User Model', () => {
|
|
17
|
+
describe('PERMISSIONS', () => {
|
|
18
|
+
it('should define all necessary permission constants', () => {
|
|
19
|
+
// Workflow permissions
|
|
20
|
+
expect(PERMISSIONS.WORKFLOW_VIEW).toBeDefined();
|
|
21
|
+
expect(PERMISSIONS.WORKFLOW_CREATE).toBeDefined();
|
|
22
|
+
expect(PERMISSIONS.WORKFLOW_EDIT).toBeDefined();
|
|
23
|
+
expect(PERMISSIONS.WORKFLOW_DELETE).toBeDefined();
|
|
24
|
+
expect(PERMISSIONS.WORKFLOW_EXECUTE).toBeDefined();
|
|
25
|
+
|
|
26
|
+
// Node permissions
|
|
27
|
+
expect(PERMISSIONS.NODE_VIEW).toBeDefined();
|
|
28
|
+
expect(PERMISSIONS.NODE_ADD).toBeDefined();
|
|
29
|
+
expect(PERMISSIONS.NODE_EDIT).toBeDefined();
|
|
30
|
+
expect(PERMISSIONS.NODE_DELETE).toBeDefined();
|
|
31
|
+
|
|
32
|
+
// Connection permissions
|
|
33
|
+
expect(PERMISSIONS.CONNECTION_VIEW).toBeDefined();
|
|
34
|
+
expect(PERMISSIONS.CONNECTION_CREATE).toBeDefined();
|
|
35
|
+
expect(PERMISSIONS.CONNECTION_DELETE).toBeDefined();
|
|
36
|
+
|
|
37
|
+
// Credential permissions
|
|
38
|
+
expect(PERMISSIONS.CREDENTIAL_VIEW).toBeDefined();
|
|
39
|
+
expect(PERMISSIONS.CREDENTIAL_CREATE).toBeDefined();
|
|
40
|
+
expect(PERMISSIONS.CREDENTIAL_EDIT).toBeDefined();
|
|
41
|
+
expect(PERMISSIONS.CREDENTIAL_DELETE).toBeDefined();
|
|
42
|
+
|
|
43
|
+
// System permissions
|
|
44
|
+
expect(PERMISSIONS.SYSTEM_ADMIN).toBeDefined();
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
describe('ROLES', () => {
|
|
49
|
+
it('should define all necessary roles', () => {
|
|
50
|
+
expect(ROLES.ADMIN).toBeDefined();
|
|
51
|
+
expect(ROLES.EDITOR).toBeDefined();
|
|
52
|
+
expect(ROLES.VIEWER).toBeDefined();
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
describe('ROLE_PERMISSIONS', () => {
|
|
57
|
+
it('should define permissions for admin role', () => {
|
|
58
|
+
const adminPerms = ROLE_PERMISSIONS[ROLES.ADMIN];
|
|
59
|
+
expect(adminPerms).toBeDefined();
|
|
60
|
+
expect(adminPerms).toContain(PERMISSIONS.SYSTEM_ADMIN);
|
|
61
|
+
expect(adminPerms).toContain(PERMISSIONS.WORKFLOW_DELETE);
|
|
62
|
+
expect(adminPerms).toContain(PERMISSIONS.CREDENTIAL_EDIT);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('should define permissions for editor role', () => {
|
|
66
|
+
const editorPerms = ROLE_PERMISSIONS[ROLES.EDITOR];
|
|
67
|
+
expect(editorPerms).toBeDefined();
|
|
68
|
+
expect(editorPerms).toContain(PERMISSIONS.WORKFLOW_EDIT);
|
|
69
|
+
expect(editorPerms).toContain(PERMISSIONS.NODE_EDIT);
|
|
70
|
+
expect(editorPerms).not.toContain(PERMISSIONS.WORKFLOW_DELETE);
|
|
71
|
+
expect(editorPerms).not.toContain(PERMISSIONS.SYSTEM_ADMIN);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('should define permissions for viewer role', () => {
|
|
75
|
+
const viewerPerms = ROLE_PERMISSIONS[ROLES.VIEWER];
|
|
76
|
+
expect(viewerPerms).toBeDefined();
|
|
77
|
+
expect(viewerPerms).toContain(PERMISSIONS.WORKFLOW_VIEW);
|
|
78
|
+
expect(viewerPerms).toContain(PERMISSIONS.NODE_VIEW);
|
|
79
|
+
expect(viewerPerms).not.toContain(PERMISSIONS.WORKFLOW_EDIT);
|
|
80
|
+
expect(viewerPerms).not.toContain(PERMISSIONS.NODE_EDIT);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
describe('hasPermission()', () => {
|
|
85
|
+
it('should return false for undefined user', () => {
|
|
86
|
+
expect(hasPermission(undefined, PERMISSIONS.WORKFLOW_VIEW)).toBe(false);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('should return false for user without roles', () => {
|
|
90
|
+
const user = { id: 'user123' };
|
|
91
|
+
expect(hasPermission(user, PERMISSIONS.WORKFLOW_VIEW)).toBe(false);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('should return false if user has no matching role', () => {
|
|
95
|
+
const user = { id: 'user123', roles: ['unknown-role'] };
|
|
96
|
+
expect(hasPermission(user, PERMISSIONS.WORKFLOW_VIEW)).toBe(false);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('should return true for admin with any permission', () => {
|
|
100
|
+
const user = { id: 'admin123', roles: [ROLES.ADMIN] };
|
|
101
|
+
expect(hasPermission(user, PERMISSIONS.WORKFLOW_DELETE)).toBe(true);
|
|
102
|
+
expect(hasPermission(user, PERMISSIONS.CREDENTIAL_EDIT)).toBe(true);
|
|
103
|
+
expect(hasPermission(user, PERMISSIONS.SYSTEM_ADMIN)).toBe(true);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('should return correct permissions for editor role', () => {
|
|
107
|
+
const user = { id: 'editor123', roles: [ROLES.EDITOR] };
|
|
108
|
+
expect(hasPermission(user, PERMISSIONS.WORKFLOW_EDIT)).toBe(true);
|
|
109
|
+
expect(hasPermission(user, PERMISSIONS.WORKFLOW_DELETE)).toBe(false);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it('should return correct permissions for viewer role', () => {
|
|
113
|
+
const user = { id: 'viewer123', roles: [ROLES.VIEWER] };
|
|
114
|
+
expect(hasPermission(user, PERMISSIONS.WORKFLOW_VIEW)).toBe(true);
|
|
115
|
+
expect(hasPermission(user, PERMISSIONS.WORKFLOW_EDIT)).toBe(false);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('should check permissions across multiple roles', () => {
|
|
119
|
+
const user = { id: 'multi123', roles: [ROLES.VIEWER, ROLES.EDITOR] };
|
|
120
|
+
expect(hasPermission(user, PERMISSIONS.WORKFLOW_VIEW)).toBe(true);
|
|
121
|
+
expect(hasPermission(user, PERMISSIONS.WORKFLOW_EDIT)).toBe(true);
|
|
122
|
+
expect(hasPermission(user, PERMISSIONS.WORKFLOW_DELETE)).toBe(false);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
describe('getUserPermissions()', () => {
|
|
127
|
+
it('should return empty array for undefined user', () => {
|
|
128
|
+
expect(getUserPermissions(undefined)).toEqual([]);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('should return empty array for user without roles', () => {
|
|
132
|
+
const user = { id: 'user123' };
|
|
133
|
+
expect(getUserPermissions(user)).toEqual([]);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('should return all permissions for admin', () => {
|
|
137
|
+
const user = { id: 'admin123', roles: [ROLES.ADMIN] };
|
|
138
|
+
const permissions = getUserPermissions(user);
|
|
139
|
+
|
|
140
|
+
expect(permissions).toContain(PERMISSIONS.SYSTEM_ADMIN);
|
|
141
|
+
expect(permissions).toContain(PERMISSIONS.WORKFLOW_DELETE);
|
|
142
|
+
expect(permissions).toContain(PERMISSIONS.CREDENTIAL_EDIT);
|
|
143
|
+
expect(permissions.length).toBe(ROLE_PERMISSIONS[ROLES.ADMIN].length);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it('should return combined permissions for multiple roles', () => {
|
|
147
|
+
const user = { id: 'multi123', roles: [ROLES.VIEWER, ROLES.EDITOR] };
|
|
148
|
+
const permissions = getUserPermissions(user);
|
|
149
|
+
|
|
150
|
+
// Should include viewer permissions
|
|
151
|
+
expect(permissions).toContain(PERMISSIONS.WORKFLOW_VIEW);
|
|
152
|
+
|
|
153
|
+
// Should include editor permissions
|
|
154
|
+
expect(permissions).toContain(PERMISSIONS.WORKFLOW_EDIT);
|
|
155
|
+
|
|
156
|
+
// Should not include admin permissions
|
|
157
|
+
expect(permissions).not.toContain(PERMISSIONS.SYSTEM_ADMIN);
|
|
158
|
+
|
|
159
|
+
// Should deduplicate permissions
|
|
160
|
+
const uniquePermissions = new Set([
|
|
161
|
+
...ROLE_PERMISSIONS[ROLES.VIEWER],
|
|
162
|
+
...ROLE_PERMISSIONS[ROLES.EDITOR]
|
|
163
|
+
]);
|
|
164
|
+
expect(permissions.length).toBe(uniquePermissions.size);
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
describe('validateRole()', () => {
|
|
169
|
+
it('should return true for valid roles', () => {
|
|
170
|
+
expect(validateRole(ROLES.ADMIN)).toBe(true);
|
|
171
|
+
expect(validateRole(ROLES.EDITOR)).toBe(true);
|
|
172
|
+
expect(validateRole(ROLES.VIEWER)).toBe(true);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it('should return false for invalid roles', () => {
|
|
176
|
+
expect(validateRole('invalid-role')).toBe(false);
|
|
177
|
+
expect(validateRole('')).toBe(false);
|
|
178
|
+
expect(validateRole(undefined)).toBe(false);
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
});
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "es2020", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
|
|
4
|
+
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
|
|
5
|
+
"outDir": "./dist", /* Redirect output structure to the directory. */
|
|
6
|
+
"rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
|
|
7
|
+
"strict": true, /* Enable all strict type-checking options. */
|
|
8
|
+
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
|
|
9
|
+
"skipLibCheck": true, /* Skip type checking of declaration files. */
|
|
10
|
+
"forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */
|
|
11
|
+
"resolveJsonModule": true /* Include modules imported with .json extension */
|
|
12
|
+
},
|
|
13
|
+
"include": [
|
|
14
|
+
"src/**/*.ts" /* Only include files in the src directory */
|
|
15
|
+
],
|
|
16
|
+
"exclude": [
|
|
17
|
+
"node_modules",
|
|
18
|
+
"**/*.test.ts"
|
|
19
|
+
]
|
|
20
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
{
|
|
2
|
+
"nodeType": "n8n-nodes-base.Brandfetch",
|
|
3
|
+
"displayName": "Brandfetch",
|
|
4
|
+
"description": "Consume Brandfetch API",
|
|
5
|
+
"version": 1,
|
|
6
|
+
"properties": [
|
|
7
|
+
{
|
|
8
|
+
"name": "operation",
|
|
9
|
+
"displayName": "Operation",
|
|
10
|
+
"type": "options",
|
|
11
|
+
"default": null,
|
|
12
|
+
"description": "Return a company's colors"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"name": "Company",
|
|
16
|
+
"default": null,
|
|
17
|
+
"description": "Return a company's data"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"name": "Font",
|
|
21
|
+
"default": null,
|
|
22
|
+
"description": "Return a company's fonts"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "Industry",
|
|
26
|
+
"default": null,
|
|
27
|
+
"description": "Return a company's industry"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"name": "Logo",
|
|
31
|
+
"default": null,
|
|
32
|
+
"description": "Return a company's logo & icon"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"name": "domain",
|
|
36
|
+
"displayName": "Domain",
|
|
37
|
+
"type": "string",
|
|
38
|
+
"default": "",
|
|
39
|
+
"description": "The domain name of the company",
|
|
40
|
+
"required": true
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"name": "download",
|
|
44
|
+
"displayName": "Download",
|
|
45
|
+
"type": "boolean",
|
|
46
|
+
"default": false,
|
|
47
|
+
"description": "Name of the binary property to which to write the data of the read file",
|
|
48
|
+
"required": true
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"name": "imageTypes",
|
|
52
|
+
"displayName": "Image Type",
|
|
53
|
+
"type": "multiOptions",
|
|
54
|
+
"default": null
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"name": "imageFormats",
|
|
58
|
+
"displayName": "Image Format",
|
|
59
|
+
"type": "multiOptions",
|
|
60
|
+
"default": null
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"name": "SVG",
|
|
64
|
+
"default": null
|
|
65
|
+
}
|
|
66
|
+
],
|
|
67
|
+
"credentialsConfig": [
|
|
68
|
+
{
|
|
69
|
+
"name": "brandfetchApi",
|
|
70
|
+
"required": true
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"name": "operation",
|
|
74
|
+
"required": false
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"name": "domain",
|
|
78
|
+
"required": true
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"name": "imageFormats",
|
|
82
|
+
"required": false
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
}
|